77
88#include "fsverity_private.h"
99
10- #include <crypto/hash.h>
11-
1210/* The hash algorithms supported by fs-verity */
13- struct fsverity_hash_alg fsverity_hash_algs [] = {
11+ const struct fsverity_hash_alg fsverity_hash_algs [] = {
1412 [FS_VERITY_HASH_ALG_SHA256 ] = {
1513 .name = "sha256" ,
1614 .digest_size = SHA256_DIGEST_SIZE ,
@@ -25,106 +23,42 @@ struct fsverity_hash_alg fsverity_hash_algs[] = {
2523 },
2624};
2725
28- static DEFINE_MUTEX (fsverity_hash_alg_init_mutex );
29-
3026/**
31- * fsverity_get_hash_alg() - validate and prepare a hash algorithm
27+ * fsverity_get_hash_alg() - get a hash algorithm by number
3228 * @inode: optional inode for logging purposes
3329 * @num: the hash algorithm number
3430 *
35- * Get the struct fsverity_hash_alg for the given hash algorithm number, and
36- * ensure it has a hash transform ready to go. The hash transforms are
37- * allocated on-demand so that we don't waste resources unnecessarily, and
38- * because the crypto modules may be initialized later than fs/verity/.
31+ * Get the struct fsverity_hash_alg for the given hash algorithm number.
3932 *
40- * Return: pointer to the hash alg on success, else an ERR_PTR()
33+ * Return: pointer to the hash alg if it's known, otherwise NULL.
4134 */
4235const struct fsverity_hash_alg * fsverity_get_hash_alg (const struct inode * inode ,
4336 unsigned int num )
4437{
45- struct fsverity_hash_alg * alg ;
46- struct crypto_shash * tfm ;
47- int err ;
48-
4938 if (num >= ARRAY_SIZE (fsverity_hash_algs ) ||
5039 !fsverity_hash_algs [num ].name ) {
5140 fsverity_warn (inode , "Unknown hash algorithm number: %u" , num );
52- return ERR_PTR (- EINVAL );
53- }
54- alg = & fsverity_hash_algs [num ];
55-
56- /* pairs with smp_store_release() below */
57- if (likely (smp_load_acquire (& alg -> tfm ) != NULL ))
58- return alg ;
59-
60- mutex_lock (& fsverity_hash_alg_init_mutex );
61-
62- if (alg -> tfm != NULL )
63- goto out_unlock ;
64-
65- tfm = crypto_alloc_shash (alg -> name , 0 , 0 );
66- if (IS_ERR (tfm )) {
67- if (PTR_ERR (tfm ) == - ENOENT ) {
68- fsverity_warn (inode ,
69- "Missing crypto API support for hash algorithm \"%s\"" ,
70- alg -> name );
71- alg = ERR_PTR (- ENOPKG );
72- goto out_unlock ;
73- }
74- fsverity_err (inode ,
75- "Error allocating hash algorithm \"%s\": %ld" ,
76- alg -> name , PTR_ERR (tfm ));
77- alg = ERR_CAST (tfm );
78- goto out_unlock ;
41+ return NULL ;
7942 }
80-
81- err = - EINVAL ;
82- if (WARN_ON_ONCE (alg -> digest_size != crypto_shash_digestsize (tfm )))
83- goto err_free_tfm ;
84- if (WARN_ON_ONCE (alg -> block_size != crypto_shash_blocksize (tfm )))
85- goto err_free_tfm ;
86-
87- pr_info ("%s using implementation \"%s\"\n" ,
88- alg -> name , crypto_shash_driver_name (tfm ));
89-
90- /* pairs with smp_load_acquire() above */
91- smp_store_release (& alg -> tfm , tfm );
92- goto out_unlock ;
93-
94- err_free_tfm :
95- crypto_free_shash (tfm );
96- alg = ERR_PTR (err );
97- out_unlock :
98- mutex_unlock (& fsverity_hash_alg_init_mutex );
99- return alg ;
43+ return & fsverity_hash_algs [num ];
10044}
10145
10246/**
10347 * fsverity_prepare_hash_state() - precompute the initial hash state
10448 * @alg: hash algorithm
10549 * @salt: a salt which is to be prepended to all data to be hashed
106- * @salt_size: salt size in bytes, possibly 0
50+ * @salt_size: salt size in bytes
10751 *
108- * Return: NULL if the salt is empty, otherwise the kmalloc()'ed precomputed
109- * initial hash state on success or an ERR_PTR() on failure.
52+ * Return: the kmalloc()'ed initial hash state, or NULL if out of memory.
11053 */
111- const u8 * fsverity_prepare_hash_state (const struct fsverity_hash_alg * alg ,
112- const u8 * salt , size_t salt_size )
54+ union fsverity_hash_ctx *
55+ fsverity_prepare_hash_state (const struct fsverity_hash_alg * alg ,
56+ const u8 * salt , size_t salt_size )
11357{
114- u8 * hashstate = NULL ;
115- SHASH_DESC_ON_STACK (desc , alg -> tfm );
11658 u8 * padded_salt = NULL ;
11759 size_t padded_salt_size ;
118- int err ;
119-
120- desc -> tfm = alg -> tfm ;
121-
122- if (salt_size == 0 )
123- return NULL ;
124-
125- hashstate = kmalloc (crypto_shash_statesize (alg -> tfm ), GFP_KERNEL );
126- if (!hashstate )
127- return ERR_PTR (- ENOMEM );
60+ union fsverity_hash_ctx ctx ;
61+ void * res = NULL ;
12862
12963 /*
13064 * Zero-pad the salt to the next multiple of the input size of the hash
@@ -135,30 +69,26 @@ const u8 *fsverity_prepare_hash_state(const struct fsverity_hash_alg *alg,
13569 */
13670 padded_salt_size = round_up (salt_size , alg -> block_size );
13771 padded_salt = kzalloc (padded_salt_size , GFP_KERNEL );
138- if (!padded_salt ) {
139- err = - ENOMEM ;
140- goto err_free ;
141- }
72+ if (!padded_salt )
73+ return NULL ;
14274 memcpy (padded_salt , salt , salt_size );
143- err = crypto_shash_init (desc );
144- if (err )
145- goto err_free ;
146-
147- err = crypto_shash_update (desc , padded_salt , padded_salt_size );
148- if (err )
149- goto err_free ;
150-
151- err = crypto_shash_export (desc , hashstate );
152- if (err )
153- goto err_free ;
154- out :
155- kfree (padded_salt );
156- return hashstate ;
15775
158- err_free :
159- kfree (hashstate );
160- hashstate = ERR_PTR (err );
161- goto out ;
76+ switch (alg -> algo_id ) {
77+ case HASH_ALGO_SHA256 :
78+ sha256_init (& ctx .sha256 );
79+ sha256_update (& ctx .sha256 , padded_salt , padded_salt_size );
80+ res = kmemdup (& ctx .sha256 , sizeof (ctx .sha256 ), GFP_KERNEL );
81+ break ;
82+ case HASH_ALGO_SHA512 :
83+ sha512_init (& ctx .sha512 );
84+ sha512_update (& ctx .sha512 , padded_salt , padded_salt_size );
85+ res = kmemdup (& ctx .sha512 , sizeof (ctx .sha512 ), GFP_KERNEL );
86+ break ;
87+ default :
88+ WARN_ON_ONCE (1 );
89+ }
90+ kfree (padded_salt );
91+ return res ;
16292}
16393
16494/**
@@ -170,31 +100,32 @@ const u8 *fsverity_prepare_hash_state(const struct fsverity_hash_alg *alg,
170100 *
171101 * Hash a single data or hash block. The hash is salted if a salt is specified
172102 * in the Merkle tree parameters.
173- *
174- * Return: 0 on success, -errno on failure
175103 */
176- int fsverity_hash_block (const struct merkle_tree_params * params ,
177- const struct inode * inode , const void * data , u8 * out )
104+ void fsverity_hash_block (const struct merkle_tree_params * params ,
105+ const struct inode * inode , const void * data , u8 * out )
178106{
179- SHASH_DESC_ON_STACK (desc , params -> hash_alg -> tfm );
180- int err ;
181-
182- desc -> tfm = params -> hash_alg -> tfm ;
183-
184- if (params -> hashstate ) {
185- err = crypto_shash_import (desc , params -> hashstate );
186- if (err ) {
187- fsverity_err (inode ,
188- "Error %d importing hash state" , err );
189- return err ;
190- }
191- err = crypto_shash_finup (desc , data , params -> block_size , out );
192- } else {
193- err = crypto_shash_digest (desc , data , params -> block_size , out );
107+ union fsverity_hash_ctx ctx ;
108+
109+ if (!params -> hashstate ) {
110+ fsverity_hash_buffer (params -> hash_alg , data , params -> block_size ,
111+ out );
112+ return ;
113+ }
114+
115+ switch (params -> hash_alg -> algo_id ) {
116+ case HASH_ALGO_SHA256 :
117+ ctx .sha256 = params -> hashstate -> sha256 ;
118+ sha256_update (& ctx .sha256 , data , params -> block_size );
119+ sha256_final (& ctx .sha256 , out );
120+ return ;
121+ case HASH_ALGO_SHA512 :
122+ ctx .sha512 = params -> hashstate -> sha512 ;
123+ sha512_update (& ctx .sha512 , data , params -> block_size );
124+ sha512_final (& ctx .sha512 , out );
125+ return ;
126+ default :
127+ BUG ();
194128 }
195- if (err )
196- fsverity_err (inode , "Error %d computing block hash" , err );
197- return err ;
198129}
199130
200131/**
@@ -203,13 +134,20 @@ int fsverity_hash_block(const struct merkle_tree_params *params,
203134 * @data: the data to hash
204135 * @size: size of data to hash, in bytes
205136 * @out: output digest, size 'alg->digest_size' bytes
206- *
207- * Return: 0 on success, -errno on failure
208137 */
209- int fsverity_hash_buffer (const struct fsverity_hash_alg * alg ,
210- const void * data , size_t size , u8 * out )
138+ void fsverity_hash_buffer (const struct fsverity_hash_alg * alg ,
139+ const void * data , size_t size , u8 * out )
211140{
212- return crypto_shash_tfm_digest (alg -> tfm , data , size , out );
141+ switch (alg -> algo_id ) {
142+ case HASH_ALGO_SHA256 :
143+ sha256 (data , size , out );
144+ return ;
145+ case HASH_ALGO_SHA512 :
146+ sha512 (data , size , out );
147+ return ;
148+ default :
149+ BUG ();
150+ }
213151}
214152
215153void __init fsverity_check_hash_algs (void )
0 commit comments