1010#define _CRYPTO_ACOMP_H
1111
1212#include <linux/atomic.h>
13+ #include <linux/args.h>
1314#include <linux/compiler_types.h>
1415#include <linux/container_of.h>
1516#include <linux/crypto.h>
17+ #include <linux/err.h>
1618#include <linux/scatterlist.h>
1719#include <linux/slab.h>
1820#include <linux/spinlock_types.h>
3234
3335#define CRYPTO_ACOMP_DST_MAX 131072
3436
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+
3545struct acomp_req ;
3646
3747struct acomp_req_chain {
@@ -83,12 +93,14 @@ struct acomp_req {
8393 * @compress: Function performs a compress operation
8494 * @decompress: Function performs a de-compress operation
8595 * @reqsize: Context size for (de)compression requests
96+ * @fb: Synchronous fallback tfm
8697 * @base: Common crypto API algorithm data structure
8798 */
8899struct crypto_acomp {
89100 int (* compress )(struct acomp_req * req );
90101 int (* decompress )(struct acomp_req * req );
91102 unsigned int reqsize ;
103+ struct crypto_acomp * fb ;
92104 struct crypto_tfm base ;
93105};
94106
@@ -210,24 +222,68 @@ static inline int crypto_has_acomp(const char *alg_name, u32 type, u32 mask)
210222 return crypto_has_alg (alg_name , type , mask );
211223}
212224
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+
213235/**
214236 * acomp_request_alloc() -- allocates asynchronous (de)compression request
215237 *
216238 * @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp()
239+ * @gfp: gfp to pass to kzalloc (defaults to GFP_KERNEL)
217240 *
218241 * Return: allocated handle in case of success or NULL in case of an error
219242 */
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 )
221245{
222246 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 ;
223252
224- req = kzalloc_noprof (sizeof ( * req ) + crypto_acomp_reqsize ( tfm ), GFP_KERNEL );
253+ req = kzalloc_noprof (len , gfp );
225254 if (likely (req ))
226255 acomp_request_set_tfm (req , tfm );
227256 return req ;
228257}
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)
229265#define acomp_request_alloc (...) alloc_hooks(acomp_request_alloc_noprof(__VA_ARGS__))
230266
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+
231287/**
232288 * acomp_request_free() -- zeroize and free asynchronous (de)compression
233289 * 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 *
237293 */
238294static inline void acomp_request_free (struct acomp_req * req )
239295{
296+ if (!req || (req -> base .flags & CRYPTO_TFM_REQ_ON_STACK ))
297+ return ;
240298 kfree_sensitive (req );
241299}
242300
@@ -257,7 +315,8 @@ static inline void acomp_request_set_callback(struct acomp_req *req,
257315 void * data )
258316{
259317 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 ;
261320
262321 req -> base .complete = cmpl ;
263322 req -> base .data = data ;
@@ -446,4 +505,19 @@ int crypto_acomp_compress(struct acomp_req *req);
446505 */
447506int crypto_acomp_decompress (struct acomp_req * req );
448507
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+
449523#endif
0 commit comments