Message ID | 20200312214758.343212-4-Jes.Sorensen@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Split fsverity-utils into a shared library | expand |
On Thu, Mar 12, 2020 at 05:47:52PM -0400, Jes Sorensen wrote: > From: Jes Sorensen <jsorensen@fb.com> > > Signed-off-by: Jes Sorensen <jsorensen@fb.com> > --- > cmd_sign.c | 19 +------------------ > libfsverity.h | 26 +++++++++++++++++++++++++- > 2 files changed, 26 insertions(+), 19 deletions(-) > > diff --git a/cmd_sign.c b/cmd_sign.c > index dcc44f8..1792084 100644 > --- a/cmd_sign.c > +++ b/cmd_sign.c > @@ -20,26 +20,9 @@ > #include <unistd.h> > > #include "commands.h" > -#include "fsverity_uapi.h" > +#include "libfsverity.h" > #include "hash_algs.h" > > -/* > - * Merkle tree properties. The file measurement is the hash of this structure > - * excluding the signature and with the sig_size field set to 0. > - */ > -struct fsverity_descriptor { > - __u8 version; /* must be 1 */ > - __u8 hash_algorithm; /* Merkle tree hash algorithm */ > - __u8 log_blocksize; /* log2 of size of data and tree blocks */ > - __u8 salt_size; /* size of salt in bytes; 0 if none */ > - __le32 sig_size; /* size of signature in bytes; 0 if none */ > - __le64 data_size; /* size of file the Merkle tree is built over */ > - __u8 root_hash[64]; /* Merkle tree root hash */ > - __u8 salt[32]; /* salt prepended to each hashed block */ > - __u8 __reserved[144]; /* must be 0's */ > - __u8 signature[]; /* optional PKCS#7 signature */ > -}; > - > /* > * Format in which verity file measurements are signed. This is the same as > * 'struct fsverity_digest', except here some magic bytes are prepended to > diff --git a/libfsverity.h b/libfsverity.h > index ceebae1..396a6ee 100644 > --- a/libfsverity.h > +++ b/libfsverity.h > @@ -13,13 +13,14 @@ > > #include <stddef.h> > #include <stdint.h> > +#include <linux/types.h> > > #define FS_VERITY_HASH_ALG_SHA256 1 > #define FS_VERITY_HASH_ALG_SHA512 2 > > struct libfsverity_merkle_tree_params { > uint16_t version; > - uint16_t hash_algorithm; > + uint16_t hash_algorithm; /* Matches the digest_algorithm type */ > uint32_t block_size; > uint32_t salt_size; > const uint8_t *salt; > @@ -27,6 +28,7 @@ struct libfsverity_merkle_tree_params { > }; > > struct libfsverity_digest { > + char magic[8]; /* must be "FSVerity" */ > uint16_t digest_algorithm; > uint16_t digest_size; > uint8_t digest[]; > @@ -38,4 +40,26 @@ struct libfsverity_signature_params { > uint64_t reserved[11]; > }; > > +/* > + * Merkle tree properties. The file measurement is the hash of this structure > + * excluding the signature and with the sig_size field set to 0. > + */ > +struct fsverity_descriptor { > + uint8_t version; /* must be 1 */ > + uint8_t hash_algorithm; /* Merkle tree hash algorithm */ > + uint8_t log_blocksize; /* log2 of size of data and tree blocks */ > + uint8_t salt_size; /* size of salt in bytes; 0 if none */ > + __le32 sig_size; /* size of signature in bytes; 0 if none */ > + __le64 data_size; /* size of file the Merkle tree is built over */ > + uint8_t root_hash[64]; /* Merkle tree root hash */ > + uint8_t salt[32]; /* salt prepended to each hashed block */ > + uint8_t __reserved[144];/* must be 0's */ > + uint8_t signature[]; /* optional PKCS#7 signature */ > +}; > + I thought there was no need for this to be part of the library API? - Eric
On 3/22/20 12:57 AM, Eric Biggers wrote: > On Thu, Mar 12, 2020 at 05:47:52PM -0400, Jes Sorensen wrote: >> From: Jes Sorensen <jsorensen@fb.com> >> >> Signed-off-by: Jes Sorensen <jsorensen@fb.com> >> --- >> cmd_sign.c | 19 +------------------ >> libfsverity.h | 26 +++++++++++++++++++++++++- >> 2 files changed, 26 insertions(+), 19 deletions(-) >> >> diff --git a/cmd_sign.c b/cmd_sign.c >> index dcc44f8..1792084 100644 >> --- a/cmd_sign.c >> +++ b/cmd_sign.c >> @@ -20,26 +20,9 @@ >> #include <unistd.h> >> >> #include "commands.h" >> -#include "fsverity_uapi.h" >> +#include "libfsverity.h" >> #include "hash_algs.h" >> >> -/* >> - * Merkle tree properties. The file measurement is the hash of this structure >> - * excluding the signature and with the sig_size field set to 0. >> - */ >> -struct fsverity_descriptor { >> - __u8 version; /* must be 1 */ >> - __u8 hash_algorithm; /* Merkle tree hash algorithm */ >> - __u8 log_blocksize; /* log2 of size of data and tree blocks */ >> - __u8 salt_size; /* size of salt in bytes; 0 if none */ >> - __le32 sig_size; /* size of signature in bytes; 0 if none */ >> - __le64 data_size; /* size of file the Merkle tree is built over */ >> - __u8 root_hash[64]; /* Merkle tree root hash */ >> - __u8 salt[32]; /* salt prepended to each hashed block */ >> - __u8 __reserved[144]; /* must be 0's */ >> - __u8 signature[]; /* optional PKCS#7 signature */ >> -}; >> - >> /* >> * Format in which verity file measurements are signed. This is the same as >> * 'struct fsverity_digest', except here some magic bytes are prepended to >> diff --git a/libfsverity.h b/libfsverity.h >> index ceebae1..396a6ee 100644 >> --- a/libfsverity.h >> +++ b/libfsverity.h >> @@ -13,13 +13,14 @@ >> >> #include <stddef.h> >> #include <stdint.h> >> +#include <linux/types.h> >> >> #define FS_VERITY_HASH_ALG_SHA256 1 >> #define FS_VERITY_HASH_ALG_SHA512 2 >> >> struct libfsverity_merkle_tree_params { >> uint16_t version; >> - uint16_t hash_algorithm; >> + uint16_t hash_algorithm; /* Matches the digest_algorithm type */ >> uint32_t block_size; >> uint32_t salt_size; >> const uint8_t *salt; >> @@ -27,6 +28,7 @@ struct libfsverity_merkle_tree_params { >> }; >> >> struct libfsverity_digest { >> + char magic[8]; /* must be "FSVerity" */ >> uint16_t digest_algorithm; >> uint16_t digest_size; >> uint8_t digest[]; >> @@ -38,4 +40,26 @@ struct libfsverity_signature_params { >> uint64_t reserved[11]; >> }; >> >> +/* >> + * Merkle tree properties. The file measurement is the hash of this structure >> + * excluding the signature and with the sig_size field set to 0. >> + */ >> +struct fsverity_descriptor { >> + uint8_t version; /* must be 1 */ >> + uint8_t hash_algorithm; /* Merkle tree hash algorithm */ >> + uint8_t log_blocksize; /* log2 of size of data and tree blocks */ >> + uint8_t salt_size; /* size of salt in bytes; 0 if none */ >> + __le32 sig_size; /* size of signature in bytes; 0 if none */ >> + __le64 data_size; /* size of file the Merkle tree is built over */ >> + uint8_t root_hash[64]; /* Merkle tree root hash */ >> + uint8_t salt[32]; /* salt prepended to each hashed block */ >> + uint8_t __reserved[144];/* must be 0's */ >> + uint8_t signature[]; /* optional PKCS#7 signature */ >> +}; >> + > > I thought there was no need for this to be part of the library API? Hi Eric, Been busy working on RPM support, but looking at this again now. Given that the fsverity signature is a hash of the descriptor, I don't see how we can avoid this? Cheers, Jes
On Tue, Apr 21, 2020 at 12:07:07PM -0400, Jes Sorensen wrote: > On 3/22/20 12:57 AM, Eric Biggers wrote: > > On Thu, Mar 12, 2020 at 05:47:52PM -0400, Jes Sorensen wrote: > >> From: Jes Sorensen <jsorensen@fb.com> > >> > >> Signed-off-by: Jes Sorensen <jsorensen@fb.com> > >> --- > >> cmd_sign.c | 19 +------------------ > >> libfsverity.h | 26 +++++++++++++++++++++++++- > >> 2 files changed, 26 insertions(+), 19 deletions(-) > >> > >> diff --git a/cmd_sign.c b/cmd_sign.c > >> index dcc44f8..1792084 100644 > >> --- a/cmd_sign.c > >> +++ b/cmd_sign.c > >> @@ -20,26 +20,9 @@ > >> #include <unistd.h> > >> > >> #include "commands.h" > >> -#include "fsverity_uapi.h" > >> +#include "libfsverity.h" > >> #include "hash_algs.h" > >> > >> -/* > >> - * Merkle tree properties. The file measurement is the hash of this structure > >> - * excluding the signature and with the sig_size field set to 0. > >> - */ > >> -struct fsverity_descriptor { > >> - __u8 version; /* must be 1 */ > >> - __u8 hash_algorithm; /* Merkle tree hash algorithm */ > >> - __u8 log_blocksize; /* log2 of size of data and tree blocks */ > >> - __u8 salt_size; /* size of salt in bytes; 0 if none */ > >> - __le32 sig_size; /* size of signature in bytes; 0 if none */ > >> - __le64 data_size; /* size of file the Merkle tree is built over */ > >> - __u8 root_hash[64]; /* Merkle tree root hash */ > >> - __u8 salt[32]; /* salt prepended to each hashed block */ > >> - __u8 __reserved[144]; /* must be 0's */ > >> - __u8 signature[]; /* optional PKCS#7 signature */ > >> -}; > >> - > >> /* > >> * Format in which verity file measurements are signed. This is the same as > >> * 'struct fsverity_digest', except here some magic bytes are prepended to > >> diff --git a/libfsverity.h b/libfsverity.h > >> index ceebae1..396a6ee 100644 > >> --- a/libfsverity.h > >> +++ b/libfsverity.h > >> @@ -13,13 +13,14 @@ > >> > >> #include <stddef.h> > >> #include <stdint.h> > >> +#include <linux/types.h> > >> > >> #define FS_VERITY_HASH_ALG_SHA256 1 > >> #define FS_VERITY_HASH_ALG_SHA512 2 > >> > >> struct libfsverity_merkle_tree_params { > >> uint16_t version; > >> - uint16_t hash_algorithm; > >> + uint16_t hash_algorithm; /* Matches the digest_algorithm type */ > >> uint32_t block_size; > >> uint32_t salt_size; > >> const uint8_t *salt; > >> @@ -27,6 +28,7 @@ struct libfsverity_merkle_tree_params { > >> }; > >> > >> struct libfsverity_digest { > >> + char magic[8]; /* must be "FSVerity" */ > >> uint16_t digest_algorithm; > >> uint16_t digest_size; > >> uint8_t digest[]; > >> @@ -38,4 +40,26 @@ struct libfsverity_signature_params { > >> uint64_t reserved[11]; > >> }; > >> > >> +/* > >> + * Merkle tree properties. The file measurement is the hash of this structure > >> + * excluding the signature and with the sig_size field set to 0. > >> + */ > >> +struct fsverity_descriptor { > >> + uint8_t version; /* must be 1 */ > >> + uint8_t hash_algorithm; /* Merkle tree hash algorithm */ > >> + uint8_t log_blocksize; /* log2 of size of data and tree blocks */ > >> + uint8_t salt_size; /* size of salt in bytes; 0 if none */ > >> + __le32 sig_size; /* size of signature in bytes; 0 if none */ > >> + __le64 data_size; /* size of file the Merkle tree is built over */ > >> + uint8_t root_hash[64]; /* Merkle tree root hash */ > >> + uint8_t salt[32]; /* salt prepended to each hashed block */ > >> + uint8_t __reserved[144];/* must be 0's */ > >> + uint8_t signature[]; /* optional PKCS#7 signature */ > >> +}; > >> + > > > > I thought there was no need for this to be part of the library API? > > Hi Eric, > > Been busy working on RPM support, but looking at this again now. Given > that the fsverity signature is a hash of the descriptor, I don't see how > we can avoid this? > struct fsverity_descriptor isn't signed directly; it's hashed as an intermediate step in libfsverity_compute_digest(). So why would the library user need the definition of 'struct fsverity_descriptor'? - Eric
On 4/21/20 12:16 PM, Eric Biggers wrote: > On Tue, Apr 21, 2020 at 12:07:07PM -0400, Jes Sorensen wrote: >> On 3/22/20 12:57 AM, Eric Biggers wrote: >>> I thought there was no need for this to be part of the library API? >> >> Hi Eric, >> >> Been busy working on RPM support, but looking at this again now. Given >> that the fsverity signature is a hash of the descriptor, I don't see how >> we can avoid this? >> > > struct fsverity_descriptor isn't signed directly; it's hashed as an intermediate > step in libfsverity_compute_digest(). So why would the library user need the > definition of 'struct fsverity_descriptor'? Hi Eric, You're right, I actually moved it to libfsverity_private.h already, but it's in the new patches I am working on. I pushed it all to git.kernel.org, but I still need to address some of the issues you responded about. I'll post an update to this when I have worked through your list of comments. Most noticeable is that I had to rework the read API to make it work with RPM, but you can find my current tree here (libfsverity branch): https://git.kernel.org/pub/scm/linux/kernel/git/jes/fsverity-utils.git/ Current RPM work is here: https://github.com/jessorensen/rpm/tree/rpm-fsverity Cheers, Jes
diff --git a/cmd_sign.c b/cmd_sign.c index dcc44f8..1792084 100644 --- a/cmd_sign.c +++ b/cmd_sign.c @@ -20,26 +20,9 @@ #include <unistd.h> #include "commands.h" -#include "fsverity_uapi.h" +#include "libfsverity.h" #include "hash_algs.h" -/* - * Merkle tree properties. The file measurement is the hash of this structure - * excluding the signature and with the sig_size field set to 0. - */ -struct fsverity_descriptor { - __u8 version; /* must be 1 */ - __u8 hash_algorithm; /* Merkle tree hash algorithm */ - __u8 log_blocksize; /* log2 of size of data and tree blocks */ - __u8 salt_size; /* size of salt in bytes; 0 if none */ - __le32 sig_size; /* size of signature in bytes; 0 if none */ - __le64 data_size; /* size of file the Merkle tree is built over */ - __u8 root_hash[64]; /* Merkle tree root hash */ - __u8 salt[32]; /* salt prepended to each hashed block */ - __u8 __reserved[144]; /* must be 0's */ - __u8 signature[]; /* optional PKCS#7 signature */ -}; - /* * Format in which verity file measurements are signed. This is the same as * 'struct fsverity_digest', except here some magic bytes are prepended to diff --git a/libfsverity.h b/libfsverity.h index ceebae1..396a6ee 100644 --- a/libfsverity.h +++ b/libfsverity.h @@ -13,13 +13,14 @@ #include <stddef.h> #include <stdint.h> +#include <linux/types.h> #define FS_VERITY_HASH_ALG_SHA256 1 #define FS_VERITY_HASH_ALG_SHA512 2 struct libfsverity_merkle_tree_params { uint16_t version; - uint16_t hash_algorithm; + uint16_t hash_algorithm; /* Matches the digest_algorithm type */ uint32_t block_size; uint32_t salt_size; const uint8_t *salt; @@ -27,6 +28,7 @@ struct libfsverity_merkle_tree_params { }; struct libfsverity_digest { + char magic[8]; /* must be "FSVerity" */ uint16_t digest_algorithm; uint16_t digest_size; uint8_t digest[]; @@ -38,4 +40,26 @@ struct libfsverity_signature_params { uint64_t reserved[11]; }; +/* + * Merkle tree properties. The file measurement is the hash of this structure + * excluding the signature and with the sig_size field set to 0. + */ +struct fsverity_descriptor { + uint8_t version; /* must be 1 */ + uint8_t hash_algorithm; /* Merkle tree hash algorithm */ + uint8_t log_blocksize; /* log2 of size of data and tree blocks */ + uint8_t salt_size; /* size of salt in bytes; 0 if none */ + __le32 sig_size; /* size of signature in bytes; 0 if none */ + __le64 data_size; /* size of file the Merkle tree is built over */ + uint8_t root_hash[64]; /* Merkle tree root hash */ + uint8_t salt[32]; /* salt prepended to each hashed block */ + uint8_t __reserved[144];/* must be 0's */ + uint8_t signature[]; /* optional PKCS#7 signature */ +}; + +int +libfsverity_compute_digest(int fd, + const struct libfsverity_merkle_tree_params *params, + struct libfsverity_digest **digest_ret); + #endif