10
10
#define _CRYPTO_ACOMP_H
11
11
12
12
#include <linux/atomic.h>
13
+ #include <linux/args.h>
13
14
#include <linux/compiler_types.h>
14
15
#include <linux/container_of.h>
15
16
#include <linux/crypto.h>
17
+ #include <linux/err.h>
16
18
#include <linux/scatterlist.h>
17
19
#include <linux/slab.h>
18
20
#include <linux/spinlock_types.h>
32
34
33
35
#define CRYPTO_ACOMP_DST_MAX 131072
34
36
37
+ #define MAX_SYNC_COMP_REQSIZE 0
38
+
39
+ #define ACOMP_REQUEST_ALLOC (name , tfm , gfp ) \
40
+ char __##name##_req[sizeof(struct acomp_req) + \
41
+ MAX_SYNC_COMP_REQSIZE] CRYPTO_MINALIGN_ATTR; \
42
+ struct acomp_req *name = acomp_request_on_stack_init( \
43
+ __##name##_req, (tfm), (gfp), false)
44
+
35
45
struct acomp_req ;
36
46
37
47
struct acomp_req_chain {
@@ -83,12 +93,14 @@ struct acomp_req {
83
93
* @compress: Function performs a compress operation
84
94
* @decompress: Function performs a de-compress operation
85
95
* @reqsize: Context size for (de)compression requests
96
+ * @fb: Synchronous fallback tfm
86
97
* @base: Common crypto API algorithm data structure
87
98
*/
88
99
struct crypto_acomp {
89
100
int (* compress )(struct acomp_req * req );
90
101
int (* decompress )(struct acomp_req * req );
91
102
unsigned int reqsize ;
103
+ struct crypto_acomp * fb ;
92
104
struct crypto_tfm base ;
93
105
};
94
106
@@ -210,24 +222,68 @@ static inline int crypto_has_acomp(const char *alg_name, u32 type, u32 mask)
210
222
return crypto_has_alg (alg_name , type , mask );
211
223
}
212
224
225
+ static inline const char * crypto_acomp_alg_name (struct crypto_acomp * tfm )
226
+ {
227
+ return crypto_tfm_alg_name (crypto_acomp_tfm (tfm ));
228
+ }
229
+
230
+ static inline const char * crypto_acomp_driver_name (struct crypto_acomp * tfm )
231
+ {
232
+ return crypto_tfm_alg_driver_name (crypto_acomp_tfm (tfm ));
233
+ }
234
+
213
235
/**
214
236
* acomp_request_alloc() -- allocates asynchronous (de)compression request
215
237
*
216
238
* @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp()
239
+ * @gfp: gfp to pass to kzalloc (defaults to GFP_KERNEL)
217
240
*
218
241
* Return: allocated handle in case of success or NULL in case of an error
219
242
*/
220
- static inline struct acomp_req * acomp_request_alloc_noprof (struct crypto_acomp * tfm )
243
+ static inline struct acomp_req * acomp_request_alloc_extra_noprof (
244
+ struct crypto_acomp * tfm , size_t extra , gfp_t gfp )
221
245
{
222
246
struct acomp_req * req ;
247
+ size_t len ;
248
+
249
+ len = ALIGN (sizeof (* req ) + crypto_acomp_reqsize (tfm ), CRYPTO_MINALIGN );
250
+ if (check_add_overflow (len , extra , & len ))
251
+ return NULL ;
223
252
224
- req = kzalloc_noprof (sizeof ( * req ) + crypto_acomp_reqsize ( tfm ), GFP_KERNEL );
253
+ req = kzalloc_noprof (len , gfp );
225
254
if (likely (req ))
226
255
acomp_request_set_tfm (req , tfm );
227
256
return req ;
228
257
}
258
+ #define acomp_request_alloc_noprof (tfm , ...) \
259
+ CONCATENATE(acomp_request_alloc_noprof_, COUNT_ARGS(__VA_ARGS__))( \
260
+ tfm, ##__VA_ARGS__)
261
+ #define acomp_request_alloc_noprof_0 (tfm ) \
262
+ acomp_request_alloc_noprof_1(tfm, GFP_KERNEL)
263
+ #define acomp_request_alloc_noprof_1 (tfm , gfp ) \
264
+ acomp_request_alloc_extra_noprof(tfm, 0, gfp)
229
265
#define acomp_request_alloc (...) alloc_hooks(acomp_request_alloc_noprof(__VA_ARGS__))
230
266
267
+ /**
268
+ * acomp_request_alloc_extra() -- allocate acomp request with extra memory
269
+ *
270
+ * @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp()
271
+ * @extra: amount of extra memory
272
+ * @gfp: gfp to pass to kzalloc
273
+ *
274
+ * Return: allocated handle in case of success or NULL in case of an error
275
+ */
276
+ #define acomp_request_alloc_extra (...) alloc_hooks(acomp_request_alloc_extra_noprof(__VA_ARGS__))
277
+
278
+ static inline void * acomp_request_extra (struct acomp_req * req )
279
+ {
280
+ struct crypto_acomp * tfm = crypto_acomp_reqtfm (req );
281
+ size_t len ;
282
+
283
+ len = ALIGN (sizeof (* req ) + crypto_acomp_reqsize (tfm ), CRYPTO_MINALIGN );
284
+ return (void * )((char * )req + len );
285
+ }
286
+
231
287
/**
232
288
* acomp_request_free() -- zeroize and free asynchronous (de)compression
233
289
* request as well as the output buffer if allocated
@@ -237,6 +293,8 @@ static inline struct acomp_req *acomp_request_alloc_noprof(struct crypto_acomp *
237
293
*/
238
294
static inline void acomp_request_free (struct acomp_req * req )
239
295
{
296
+ if (!req || (req -> base .flags & CRYPTO_TFM_REQ_ON_STACK ))
297
+ return ;
240
298
kfree_sensitive (req );
241
299
}
242
300
@@ -257,7 +315,8 @@ static inline void acomp_request_set_callback(struct acomp_req *req,
257
315
void * data )
258
316
{
259
317
u32 keep = CRYPTO_ACOMP_REQ_SRC_VIRT | CRYPTO_ACOMP_REQ_SRC_NONDMA |
260
- CRYPTO_ACOMP_REQ_DST_VIRT | CRYPTO_ACOMP_REQ_DST_NONDMA ;
318
+ CRYPTO_ACOMP_REQ_DST_VIRT | CRYPTO_ACOMP_REQ_DST_NONDMA |
319
+ CRYPTO_TFM_REQ_ON_STACK ;
261
320
262
321
req -> base .complete = cmpl ;
263
322
req -> base .data = data ;
@@ -446,4 +505,19 @@ int crypto_acomp_compress(struct acomp_req *req);
446
505
*/
447
506
int crypto_acomp_decompress (struct acomp_req * req );
448
507
508
+ static inline struct acomp_req * acomp_request_on_stack_init (
509
+ char * buf , struct crypto_acomp * tfm , gfp_t gfp , bool stackonly )
510
+ {
511
+ struct acomp_req * req ;
512
+
513
+ if (!stackonly && (req = acomp_request_alloc (tfm , gfp )))
514
+ return req ;
515
+
516
+ req = (void * )buf ;
517
+ acomp_request_set_tfm (req , tfm -> fb );
518
+ req -> base .flags = CRYPTO_TFM_REQ_ON_STACK ;
519
+
520
+ return req ;
521
+ }
522
+
449
523
#endif
0 commit comments