8
8
#include "fsverity_private.h"
9
9
10
10
#include <crypto/hash.h>
11
- #include <linux/scatterlist.h>
12
11
13
12
/* The hash algorithms supported by fs-verity */
14
13
struct fsverity_hash_alg fsverity_hash_algs [] = {
@@ -44,7 +43,7 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
44
43
unsigned int num )
45
44
{
46
45
struct fsverity_hash_alg * alg ;
47
- struct crypto_ahash * tfm ;
46
+ struct crypto_shash * tfm ;
48
47
int err ;
49
48
50
49
if (num >= ARRAY_SIZE (fsverity_hash_algs ) ||
@@ -63,11 +62,7 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
63
62
if (alg -> tfm != NULL )
64
63
goto out_unlock ;
65
64
66
- /*
67
- * Using the shash API would make things a bit simpler, but the ahash
68
- * API is preferable as it allows the use of crypto accelerators.
69
- */
70
- tfm = crypto_alloc_ahash (alg -> name , 0 , 0 );
65
+ tfm = crypto_alloc_shash (alg -> name , 0 , 0 );
71
66
if (IS_ERR (tfm )) {
72
67
if (PTR_ERR (tfm ) == - ENOENT ) {
73
68
fsverity_warn (inode ,
@@ -84,68 +79,26 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
84
79
}
85
80
86
81
err = - EINVAL ;
87
- if (WARN_ON_ONCE (alg -> digest_size != crypto_ahash_digestsize (tfm )))
82
+ if (WARN_ON_ONCE (alg -> digest_size != crypto_shash_digestsize (tfm )))
88
83
goto err_free_tfm ;
89
- if (WARN_ON_ONCE (alg -> block_size != crypto_ahash_blocksize (tfm )))
90
- goto err_free_tfm ;
91
-
92
- err = mempool_init_kmalloc_pool (& alg -> req_pool , 1 ,
93
- sizeof (struct ahash_request ) +
94
- crypto_ahash_reqsize (tfm ));
95
- if (err )
84
+ if (WARN_ON_ONCE (alg -> block_size != crypto_shash_blocksize (tfm )))
96
85
goto err_free_tfm ;
97
86
98
87
pr_info ("%s using implementation \"%s\"\n" ,
99
- alg -> name , crypto_ahash_driver_name (tfm ));
88
+ alg -> name , crypto_shash_driver_name (tfm ));
100
89
101
90
/* pairs with smp_load_acquire() above */
102
91
smp_store_release (& alg -> tfm , tfm );
103
92
goto out_unlock ;
104
93
105
94
err_free_tfm :
106
- crypto_free_ahash (tfm );
95
+ crypto_free_shash (tfm );
107
96
alg = ERR_PTR (err );
108
97
out_unlock :
109
98
mutex_unlock (& fsverity_hash_alg_init_mutex );
110
99
return alg ;
111
100
}
112
101
113
- /**
114
- * fsverity_alloc_hash_request() - allocate a hash request object
115
- * @alg: the hash algorithm for which to allocate the request
116
- * @gfp_flags: memory allocation flags
117
- *
118
- * This is mempool-backed, so this never fails if __GFP_DIRECT_RECLAIM is set in
119
- * @gfp_flags. However, in that case this might need to wait for all
120
- * previously-allocated requests to be freed. So to avoid deadlocks, callers
121
- * must never need multiple requests at a time to make forward progress.
122
- *
123
- * Return: the request object on success; NULL on failure (but see above)
124
- */
125
- struct ahash_request * fsverity_alloc_hash_request (struct fsverity_hash_alg * alg ,
126
- gfp_t gfp_flags )
127
- {
128
- struct ahash_request * req = mempool_alloc (& alg -> req_pool , gfp_flags );
129
-
130
- if (req )
131
- ahash_request_set_tfm (req , alg -> tfm );
132
- return req ;
133
- }
134
-
135
- /**
136
- * fsverity_free_hash_request() - free a hash request object
137
- * @alg: the hash algorithm
138
- * @req: the hash request object to free
139
- */
140
- void fsverity_free_hash_request (struct fsverity_hash_alg * alg ,
141
- struct ahash_request * req )
142
- {
143
- if (req ) {
144
- ahash_request_zero (req );
145
- mempool_free (req , & alg -> req_pool );
146
- }
147
- }
148
-
149
102
/**
150
103
* fsverity_prepare_hash_state() - precompute the initial hash state
151
104
* @alg: hash algorithm
@@ -159,23 +112,20 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
159
112
const u8 * salt , size_t salt_size )
160
113
{
161
114
u8 * hashstate = NULL ;
162
- struct ahash_request * req = NULL ;
115
+ SHASH_DESC_ON_STACK ( desc , alg -> tfm ) ;
163
116
u8 * padded_salt = NULL ;
164
117
size_t padded_salt_size ;
165
- struct scatterlist sg ;
166
- DECLARE_CRYPTO_WAIT (wait );
167
118
int err ;
168
119
120
+ desc -> tfm = alg -> tfm ;
121
+
169
122
if (salt_size == 0 )
170
123
return NULL ;
171
124
172
- hashstate = kmalloc (crypto_ahash_statesize (alg -> tfm ), GFP_KERNEL );
125
+ hashstate = kmalloc (crypto_shash_statesize (alg -> tfm ), GFP_KERNEL );
173
126
if (!hashstate )
174
127
return ERR_PTR (- ENOMEM );
175
128
176
- /* This allocation never fails, since it's mempool-backed. */
177
- req = fsverity_alloc_hash_request (alg , GFP_KERNEL );
178
-
179
129
/*
180
130
* Zero-pad the salt to the next multiple of the input size of the hash
181
131
* algorithm's compression function, e.g. 64 bytes for SHA-256 or 128
@@ -190,26 +140,18 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
190
140
goto err_free ;
191
141
}
192
142
memcpy (padded_salt , salt , salt_size );
193
-
194
- sg_init_one (& sg , padded_salt , padded_salt_size );
195
- ahash_request_set_callback (req , CRYPTO_TFM_REQ_MAY_SLEEP |
196
- CRYPTO_TFM_REQ_MAY_BACKLOG ,
197
- crypto_req_done , & wait );
198
- ahash_request_set_crypt (req , & sg , NULL , padded_salt_size );
199
-
200
- err = crypto_wait_req (crypto_ahash_init (req ), & wait );
143
+ err = crypto_shash_init (desc );
201
144
if (err )
202
145
goto err_free ;
203
146
204
- err = crypto_wait_req ( crypto_ahash_update ( req ), & wait );
147
+ err = crypto_shash_update ( desc , padded_salt , padded_salt_size );
205
148
if (err )
206
149
goto err_free ;
207
150
208
- err = crypto_ahash_export ( req , hashstate );
151
+ err = crypto_shash_export ( desc , hashstate );
209
152
if (err )
210
153
goto err_free ;
211
154
out :
212
- fsverity_free_hash_request (alg , req );
213
155
kfree (padded_salt );
214
156
return hashstate ;
215
157
@@ -223,9 +165,7 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
223
165
* fsverity_hash_block() - hash a single data or hash block
224
166
* @params: the Merkle tree's parameters
225
167
* @inode: inode for which the hashing is being done
226
- * @req: preallocated hash request
227
- * @page: the page containing the block to hash
228
- * @offset: the offset of the block within @page
168
+ * @data: virtual address of a buffer containing the block to hash
229
169
* @out: output digest, size 'params->digest_size' bytes
230
170
*
231
171
* Hash a single data or hash block. The hash is salted if a salt is specified
@@ -234,33 +174,24 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
234
174
* Return: 0 on success, -errno on failure
235
175
*/
236
176
int fsverity_hash_block (const struct merkle_tree_params * params ,
237
- const struct inode * inode , struct ahash_request * req ,
238
- struct page * page , unsigned int offset , u8 * out )
177
+ const struct inode * inode , const void * data , u8 * out )
239
178
{
240
- struct scatterlist sg ;
241
- DECLARE_CRYPTO_WAIT (wait );
179
+ SHASH_DESC_ON_STACK (desc , params -> hash_alg -> tfm );
242
180
int err ;
243
181
244
- sg_init_table (& sg , 1 );
245
- sg_set_page (& sg , page , params -> block_size , offset );
246
- ahash_request_set_callback (req , CRYPTO_TFM_REQ_MAY_SLEEP |
247
- CRYPTO_TFM_REQ_MAY_BACKLOG ,
248
- crypto_req_done , & wait );
249
- ahash_request_set_crypt (req , & sg , out , params -> block_size );
182
+ desc -> tfm = params -> hash_alg -> tfm ;
250
183
251
184
if (params -> hashstate ) {
252
- err = crypto_ahash_import ( req , params -> hashstate );
185
+ err = crypto_shash_import ( desc , params -> hashstate );
253
186
if (err ) {
254
187
fsverity_err (inode ,
255
188
"Error %d importing hash state" , err );
256
189
return err ;
257
190
}
258
- err = crypto_ahash_finup ( req );
191
+ err = crypto_shash_finup ( desc , data , params -> block_size , out );
259
192
} else {
260
- err = crypto_ahash_digest ( req );
193
+ err = crypto_shash_digest ( desc , data , params -> block_size , out );
261
194
}
262
-
263
- err = crypto_wait_req (err , & wait );
264
195
if (err )
265
196
fsverity_err (inode , "Error %d computing block hash" , err );
266
197
return err ;
@@ -273,32 +204,12 @@ int fsverity_hash_block(const struct merkle_tree_params *params,
273
204
* @size: size of data to hash, in bytes
274
205
* @out: output digest, size 'alg->digest_size' bytes
275
206
*
276
- * Hash some data which is located in physically contiguous memory (i.e. memory
277
- * allocated by kmalloc(), not by vmalloc()). No salt is used.
278
- *
279
207
* Return: 0 on success, -errno on failure
280
208
*/
281
209
int fsverity_hash_buffer (struct fsverity_hash_alg * alg ,
282
210
const void * data , size_t size , u8 * out )
283
211
{
284
- struct ahash_request * req ;
285
- struct scatterlist sg ;
286
- DECLARE_CRYPTO_WAIT (wait );
287
- int err ;
288
-
289
- /* This allocation never fails, since it's mempool-backed. */
290
- req = fsverity_alloc_hash_request (alg , GFP_KERNEL );
291
-
292
- sg_init_one (& sg , data , size );
293
- ahash_request_set_callback (req , CRYPTO_TFM_REQ_MAY_SLEEP |
294
- CRYPTO_TFM_REQ_MAY_BACKLOG ,
295
- crypto_req_done , & wait );
296
- ahash_request_set_crypt (req , & sg , out , size );
297
-
298
- err = crypto_wait_req (crypto_ahash_digest (req ), & wait );
299
-
300
- fsverity_free_hash_request (alg , req );
301
- return err ;
212
+ return crypto_shash_tfm_digest (alg -> tfm , data , size , out );
302
213
}
303
214
304
215
void __init fsverity_check_hash_algs (void )
0 commit comments