1*2ebda74fSGiovanni Cabiddu /* 2*2ebda74fSGiovanni Cabiddu * Asynchronous Compression operations 3*2ebda74fSGiovanni Cabiddu * 4*2ebda74fSGiovanni Cabiddu * Copyright (c) 2016, Intel Corporation 5*2ebda74fSGiovanni Cabiddu * Authors: Weigang Li <weigang.li@intel.com> 6*2ebda74fSGiovanni Cabiddu * Giovanni Cabiddu <giovanni.cabiddu@intel.com> 7*2ebda74fSGiovanni Cabiddu * 8*2ebda74fSGiovanni Cabiddu * This program is free software; you can redistribute it and/or modify it 9*2ebda74fSGiovanni Cabiddu * under the terms of the GNU General Public License as published by the Free 10*2ebda74fSGiovanni Cabiddu * Software Foundation; either version 2 of the License, or (at your option) 11*2ebda74fSGiovanni Cabiddu * any later version. 12*2ebda74fSGiovanni Cabiddu * 13*2ebda74fSGiovanni Cabiddu */ 14*2ebda74fSGiovanni Cabiddu #ifndef _CRYPTO_ACOMP_H 15*2ebda74fSGiovanni Cabiddu #define _CRYPTO_ACOMP_H 16*2ebda74fSGiovanni Cabiddu #include <linux/crypto.h> 17*2ebda74fSGiovanni Cabiddu 18*2ebda74fSGiovanni Cabiddu #define CRYPTO_ACOMP_ALLOC_OUTPUT 0x00000001 19*2ebda74fSGiovanni Cabiddu 20*2ebda74fSGiovanni Cabiddu /** 21*2ebda74fSGiovanni Cabiddu * struct acomp_req - asynchronous (de)compression request 22*2ebda74fSGiovanni Cabiddu * 23*2ebda74fSGiovanni Cabiddu * @base: Common attributes for asynchronous crypto requests 24*2ebda74fSGiovanni Cabiddu * @src: Source Data 25*2ebda74fSGiovanni Cabiddu * @dst: Destination data 26*2ebda74fSGiovanni Cabiddu * @slen: Size of the input buffer 27*2ebda74fSGiovanni Cabiddu * @dlen: Size of the output buffer and number of bytes produced 28*2ebda74fSGiovanni Cabiddu * @flags: Internal flags 29*2ebda74fSGiovanni Cabiddu * @__ctx: Start of private context data 30*2ebda74fSGiovanni Cabiddu */ 31*2ebda74fSGiovanni Cabiddu struct acomp_req { 32*2ebda74fSGiovanni Cabiddu struct crypto_async_request base; 33*2ebda74fSGiovanni Cabiddu struct scatterlist *src; 34*2ebda74fSGiovanni Cabiddu struct scatterlist *dst; 35*2ebda74fSGiovanni Cabiddu unsigned int slen; 36*2ebda74fSGiovanni Cabiddu unsigned int dlen; 37*2ebda74fSGiovanni Cabiddu u32 flags; 38*2ebda74fSGiovanni Cabiddu void *__ctx[] CRYPTO_MINALIGN_ATTR; 39*2ebda74fSGiovanni Cabiddu }; 40*2ebda74fSGiovanni Cabiddu 41*2ebda74fSGiovanni Cabiddu /** 42*2ebda74fSGiovanni Cabiddu * struct crypto_acomp - user-instantiated objects which encapsulate 43*2ebda74fSGiovanni Cabiddu * algorithms and core processing logic 44*2ebda74fSGiovanni Cabiddu * 45*2ebda74fSGiovanni Cabiddu * @base: Common crypto API algorithm data structure 46*2ebda74fSGiovanni Cabiddu */ 47*2ebda74fSGiovanni Cabiddu struct crypto_acomp { 48*2ebda74fSGiovanni Cabiddu struct crypto_tfm base; 49*2ebda74fSGiovanni Cabiddu }; 50*2ebda74fSGiovanni Cabiddu 51*2ebda74fSGiovanni Cabiddu /** 52*2ebda74fSGiovanni Cabiddu * struct acomp_alg - asynchronous compression algorithm 53*2ebda74fSGiovanni Cabiddu * 54*2ebda74fSGiovanni Cabiddu * @compress: Function performs a compress operation 55*2ebda74fSGiovanni Cabiddu * @decompress: Function performs a de-compress operation 56*2ebda74fSGiovanni Cabiddu * @dst_free: Frees destination buffer if allocated inside the algorithm 57*2ebda74fSGiovanni Cabiddu * @init: Initialize the cryptographic transformation object. 58*2ebda74fSGiovanni Cabiddu * This function is used to initialize the cryptographic 59*2ebda74fSGiovanni Cabiddu * transformation object. This function is called only once at 60*2ebda74fSGiovanni Cabiddu * the instantiation time, right after the transformation context 61*2ebda74fSGiovanni Cabiddu * was allocated. In case the cryptographic hardware has some 62*2ebda74fSGiovanni Cabiddu * special requirements which need to be handled by software, this 63*2ebda74fSGiovanni Cabiddu * function shall check for the precise requirement of the 64*2ebda74fSGiovanni Cabiddu * transformation and put any software fallbacks in place. 65*2ebda74fSGiovanni Cabiddu * @exit: Deinitialize the cryptographic transformation object. This is a 66*2ebda74fSGiovanni Cabiddu * counterpart to @init, used to remove various changes set in 67*2ebda74fSGiovanni Cabiddu * @init. 68*2ebda74fSGiovanni Cabiddu * 69*2ebda74fSGiovanni Cabiddu * @reqsize: Context size for (de)compression requests 70*2ebda74fSGiovanni Cabiddu * @base: Common crypto API algorithm data structure 71*2ebda74fSGiovanni Cabiddu */ 72*2ebda74fSGiovanni Cabiddu struct acomp_alg { 73*2ebda74fSGiovanni Cabiddu int (*compress)(struct acomp_req *req); 74*2ebda74fSGiovanni Cabiddu int (*decompress)(struct acomp_req *req); 75*2ebda74fSGiovanni Cabiddu void (*dst_free)(struct scatterlist *dst); 76*2ebda74fSGiovanni Cabiddu int (*init)(struct crypto_acomp *tfm); 77*2ebda74fSGiovanni Cabiddu void (*exit)(struct crypto_acomp *tfm); 78*2ebda74fSGiovanni Cabiddu unsigned int reqsize; 79*2ebda74fSGiovanni Cabiddu struct crypto_alg base; 80*2ebda74fSGiovanni Cabiddu }; 81*2ebda74fSGiovanni Cabiddu 82*2ebda74fSGiovanni Cabiddu /** 83*2ebda74fSGiovanni Cabiddu * DOC: Asynchronous Compression API 84*2ebda74fSGiovanni Cabiddu * 85*2ebda74fSGiovanni Cabiddu * The Asynchronous Compression API is used with the algorithms of type 86*2ebda74fSGiovanni Cabiddu * CRYPTO_ALG_TYPE_ACOMPRESS (listed as type "acomp" in /proc/crypto) 87*2ebda74fSGiovanni Cabiddu */ 88*2ebda74fSGiovanni Cabiddu 89*2ebda74fSGiovanni Cabiddu /** 90*2ebda74fSGiovanni Cabiddu * crypto_alloc_acomp() -- allocate ACOMPRESS tfm handle 91*2ebda74fSGiovanni Cabiddu * @alg_name: is the cra_name / name or cra_driver_name / driver name of the 92*2ebda74fSGiovanni Cabiddu * compression algorithm e.g. "deflate" 93*2ebda74fSGiovanni Cabiddu * @type: specifies the type of the algorithm 94*2ebda74fSGiovanni Cabiddu * @mask: specifies the mask for the algorithm 95*2ebda74fSGiovanni Cabiddu * 96*2ebda74fSGiovanni Cabiddu * Allocate a handle for a compression algorithm. The returned struct 97*2ebda74fSGiovanni Cabiddu * crypto_acomp is the handle that is required for any subsequent 98*2ebda74fSGiovanni Cabiddu * API invocation for the compression operations. 99*2ebda74fSGiovanni Cabiddu * 100*2ebda74fSGiovanni Cabiddu * Return: allocated handle in case of success; IS_ERR() is true in case 101*2ebda74fSGiovanni Cabiddu * of an error, PTR_ERR() returns the error code. 102*2ebda74fSGiovanni Cabiddu */ 103*2ebda74fSGiovanni Cabiddu struct crypto_acomp *crypto_alloc_acomp(const char *alg_name, u32 type, 104*2ebda74fSGiovanni Cabiddu u32 mask); 105*2ebda74fSGiovanni Cabiddu 106*2ebda74fSGiovanni Cabiddu static inline struct crypto_tfm *crypto_acomp_tfm(struct crypto_acomp *tfm) 107*2ebda74fSGiovanni Cabiddu { 108*2ebda74fSGiovanni Cabiddu return &tfm->base; 109*2ebda74fSGiovanni Cabiddu } 110*2ebda74fSGiovanni Cabiddu 111*2ebda74fSGiovanni Cabiddu static inline struct acomp_alg *__crypto_acomp_alg(struct crypto_alg *alg) 112*2ebda74fSGiovanni Cabiddu { 113*2ebda74fSGiovanni Cabiddu return container_of(alg, struct acomp_alg, base); 114*2ebda74fSGiovanni Cabiddu } 115*2ebda74fSGiovanni Cabiddu 116*2ebda74fSGiovanni Cabiddu static inline struct crypto_acomp *__crypto_acomp_tfm(struct crypto_tfm *tfm) 117*2ebda74fSGiovanni Cabiddu { 118*2ebda74fSGiovanni Cabiddu return container_of(tfm, struct crypto_acomp, base); 119*2ebda74fSGiovanni Cabiddu } 120*2ebda74fSGiovanni Cabiddu 121*2ebda74fSGiovanni Cabiddu static inline struct acomp_alg *crypto_acomp_alg(struct crypto_acomp *tfm) 122*2ebda74fSGiovanni Cabiddu { 123*2ebda74fSGiovanni Cabiddu return __crypto_acomp_alg(crypto_acomp_tfm(tfm)->__crt_alg); 124*2ebda74fSGiovanni Cabiddu } 125*2ebda74fSGiovanni Cabiddu 126*2ebda74fSGiovanni Cabiddu static inline unsigned int crypto_acomp_reqsize(struct crypto_acomp *tfm) 127*2ebda74fSGiovanni Cabiddu { 128*2ebda74fSGiovanni Cabiddu return crypto_acomp_alg(tfm)->reqsize; 129*2ebda74fSGiovanni Cabiddu } 130*2ebda74fSGiovanni Cabiddu 131*2ebda74fSGiovanni Cabiddu static inline void acomp_request_set_tfm(struct acomp_req *req, 132*2ebda74fSGiovanni Cabiddu struct crypto_acomp *tfm) 133*2ebda74fSGiovanni Cabiddu { 134*2ebda74fSGiovanni Cabiddu req->base.tfm = crypto_acomp_tfm(tfm); 135*2ebda74fSGiovanni Cabiddu } 136*2ebda74fSGiovanni Cabiddu 137*2ebda74fSGiovanni Cabiddu static inline struct crypto_acomp *crypto_acomp_reqtfm(struct acomp_req *req) 138*2ebda74fSGiovanni Cabiddu { 139*2ebda74fSGiovanni Cabiddu return __crypto_acomp_tfm(req->base.tfm); 140*2ebda74fSGiovanni Cabiddu } 141*2ebda74fSGiovanni Cabiddu 142*2ebda74fSGiovanni Cabiddu /** 143*2ebda74fSGiovanni Cabiddu * crypto_free_acomp() -- free ACOMPRESS tfm handle 144*2ebda74fSGiovanni Cabiddu * 145*2ebda74fSGiovanni Cabiddu * @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp() 146*2ebda74fSGiovanni Cabiddu */ 147*2ebda74fSGiovanni Cabiddu static inline void crypto_free_acomp(struct crypto_acomp *tfm) 148*2ebda74fSGiovanni Cabiddu { 149*2ebda74fSGiovanni Cabiddu crypto_destroy_tfm(tfm, crypto_acomp_tfm(tfm)); 150*2ebda74fSGiovanni Cabiddu } 151*2ebda74fSGiovanni Cabiddu 152*2ebda74fSGiovanni Cabiddu static inline int crypto_has_acomp(const char *alg_name, u32 type, u32 mask) 153*2ebda74fSGiovanni Cabiddu { 154*2ebda74fSGiovanni Cabiddu type &= ~CRYPTO_ALG_TYPE_MASK; 155*2ebda74fSGiovanni Cabiddu type |= CRYPTO_ALG_TYPE_ACOMPRESS; 156*2ebda74fSGiovanni Cabiddu mask |= CRYPTO_ALG_TYPE_MASK; 157*2ebda74fSGiovanni Cabiddu 158*2ebda74fSGiovanni Cabiddu return crypto_has_alg(alg_name, type, mask); 159*2ebda74fSGiovanni Cabiddu } 160*2ebda74fSGiovanni Cabiddu 161*2ebda74fSGiovanni Cabiddu /** 162*2ebda74fSGiovanni Cabiddu * acomp_request_alloc() -- allocates asynchronous (de)compression request 163*2ebda74fSGiovanni Cabiddu * 164*2ebda74fSGiovanni Cabiddu * @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp() 165*2ebda74fSGiovanni Cabiddu * 166*2ebda74fSGiovanni Cabiddu * Return: allocated handle in case of success or NULL in case of an error 167*2ebda74fSGiovanni Cabiddu */ 168*2ebda74fSGiovanni Cabiddu static inline struct acomp_req *acomp_request_alloc(struct crypto_acomp *tfm) 169*2ebda74fSGiovanni Cabiddu { 170*2ebda74fSGiovanni Cabiddu struct acomp_req *req; 171*2ebda74fSGiovanni Cabiddu 172*2ebda74fSGiovanni Cabiddu req = kzalloc(sizeof(*req) + crypto_acomp_reqsize(tfm), GFP_KERNEL); 173*2ebda74fSGiovanni Cabiddu if (likely(req)) 174*2ebda74fSGiovanni Cabiddu acomp_request_set_tfm(req, tfm); 175*2ebda74fSGiovanni Cabiddu 176*2ebda74fSGiovanni Cabiddu return req; 177*2ebda74fSGiovanni Cabiddu } 178*2ebda74fSGiovanni Cabiddu 179*2ebda74fSGiovanni Cabiddu /** 180*2ebda74fSGiovanni Cabiddu * acomp_request_free() -- zeroize and free asynchronous (de)compression 181*2ebda74fSGiovanni Cabiddu * request as well as the output buffer if allocated 182*2ebda74fSGiovanni Cabiddu * inside the algorithm 183*2ebda74fSGiovanni Cabiddu * 184*2ebda74fSGiovanni Cabiddu * @req: request to free 185*2ebda74fSGiovanni Cabiddu */ 186*2ebda74fSGiovanni Cabiddu static inline void acomp_request_free(struct acomp_req *req) 187*2ebda74fSGiovanni Cabiddu { 188*2ebda74fSGiovanni Cabiddu struct crypto_acomp *tfm = crypto_acomp_reqtfm(req); 189*2ebda74fSGiovanni Cabiddu struct acomp_alg *alg = crypto_acomp_alg(tfm); 190*2ebda74fSGiovanni Cabiddu 191*2ebda74fSGiovanni Cabiddu if (req->flags & CRYPTO_ACOMP_ALLOC_OUTPUT) { 192*2ebda74fSGiovanni Cabiddu alg->dst_free(req->dst); 193*2ebda74fSGiovanni Cabiddu req->dst = NULL; 194*2ebda74fSGiovanni Cabiddu } 195*2ebda74fSGiovanni Cabiddu kzfree(req); 196*2ebda74fSGiovanni Cabiddu } 197*2ebda74fSGiovanni Cabiddu 198*2ebda74fSGiovanni Cabiddu /** 199*2ebda74fSGiovanni Cabiddu * acomp_request_set_callback() -- Sets an asynchronous callback 200*2ebda74fSGiovanni Cabiddu * 201*2ebda74fSGiovanni Cabiddu * Callback will be called when an asynchronous operation on a given 202*2ebda74fSGiovanni Cabiddu * request is finished. 203*2ebda74fSGiovanni Cabiddu * 204*2ebda74fSGiovanni Cabiddu * @req: request that the callback will be set for 205*2ebda74fSGiovanni Cabiddu * @flgs: specify for instance if the operation may backlog 206*2ebda74fSGiovanni Cabiddu * @cmlp: callback which will be called 207*2ebda74fSGiovanni Cabiddu * @data: private data used by the caller 208*2ebda74fSGiovanni Cabiddu */ 209*2ebda74fSGiovanni Cabiddu static inline void acomp_request_set_callback(struct acomp_req *req, 210*2ebda74fSGiovanni Cabiddu u32 flgs, 211*2ebda74fSGiovanni Cabiddu crypto_completion_t cmpl, 212*2ebda74fSGiovanni Cabiddu void *data) 213*2ebda74fSGiovanni Cabiddu { 214*2ebda74fSGiovanni Cabiddu req->base.complete = cmpl; 215*2ebda74fSGiovanni Cabiddu req->base.data = data; 216*2ebda74fSGiovanni Cabiddu req->base.flags = flgs; 217*2ebda74fSGiovanni Cabiddu } 218*2ebda74fSGiovanni Cabiddu 219*2ebda74fSGiovanni Cabiddu /** 220*2ebda74fSGiovanni Cabiddu * acomp_request_set_params() -- Sets request parameters 221*2ebda74fSGiovanni Cabiddu * 222*2ebda74fSGiovanni Cabiddu * Sets parameters required by an acomp operation 223*2ebda74fSGiovanni Cabiddu * 224*2ebda74fSGiovanni Cabiddu * @req: asynchronous compress request 225*2ebda74fSGiovanni Cabiddu * @src: pointer to input buffer scatterlist 226*2ebda74fSGiovanni Cabiddu * @dst: pointer to output buffer scatterlist. If this is NULL, the 227*2ebda74fSGiovanni Cabiddu * acomp layer will allocate the output memory 228*2ebda74fSGiovanni Cabiddu * @slen: size of the input buffer 229*2ebda74fSGiovanni Cabiddu * @dlen: size of the output buffer. If dst is NULL, this can be used by 230*2ebda74fSGiovanni Cabiddu * the user to specify the maximum amount of memory to allocate 231*2ebda74fSGiovanni Cabiddu */ 232*2ebda74fSGiovanni Cabiddu static inline void acomp_request_set_params(struct acomp_req *req, 233*2ebda74fSGiovanni Cabiddu struct scatterlist *src, 234*2ebda74fSGiovanni Cabiddu struct scatterlist *dst, 235*2ebda74fSGiovanni Cabiddu unsigned int slen, 236*2ebda74fSGiovanni Cabiddu unsigned int dlen) 237*2ebda74fSGiovanni Cabiddu { 238*2ebda74fSGiovanni Cabiddu req->src = src; 239*2ebda74fSGiovanni Cabiddu req->dst = dst; 240*2ebda74fSGiovanni Cabiddu req->slen = slen; 241*2ebda74fSGiovanni Cabiddu req->dlen = dlen; 242*2ebda74fSGiovanni Cabiddu 243*2ebda74fSGiovanni Cabiddu if (!req->dst) 244*2ebda74fSGiovanni Cabiddu req->flags |= CRYPTO_ACOMP_ALLOC_OUTPUT; 245*2ebda74fSGiovanni Cabiddu } 246*2ebda74fSGiovanni Cabiddu 247*2ebda74fSGiovanni Cabiddu /** 248*2ebda74fSGiovanni Cabiddu * crypto_acomp_compress() -- Invoke asynchronous compress operation 249*2ebda74fSGiovanni Cabiddu * 250*2ebda74fSGiovanni Cabiddu * Function invokes the asynchronous compress operation 251*2ebda74fSGiovanni Cabiddu * 252*2ebda74fSGiovanni Cabiddu * @req: asynchronous compress request 253*2ebda74fSGiovanni Cabiddu * 254*2ebda74fSGiovanni Cabiddu * Return: zero on success; error code in case of error 255*2ebda74fSGiovanni Cabiddu */ 256*2ebda74fSGiovanni Cabiddu static inline int crypto_acomp_compress(struct acomp_req *req) 257*2ebda74fSGiovanni Cabiddu { 258*2ebda74fSGiovanni Cabiddu struct crypto_acomp *tfm = crypto_acomp_reqtfm(req); 259*2ebda74fSGiovanni Cabiddu struct acomp_alg *alg = crypto_acomp_alg(tfm); 260*2ebda74fSGiovanni Cabiddu 261*2ebda74fSGiovanni Cabiddu return alg->compress(req); 262*2ebda74fSGiovanni Cabiddu } 263*2ebda74fSGiovanni Cabiddu 264*2ebda74fSGiovanni Cabiddu /** 265*2ebda74fSGiovanni Cabiddu * crypto_acomp_decompress() -- Invoke asynchronous decompress operation 266*2ebda74fSGiovanni Cabiddu * 267*2ebda74fSGiovanni Cabiddu * Function invokes the asynchronous decompress operation 268*2ebda74fSGiovanni Cabiddu * 269*2ebda74fSGiovanni Cabiddu * @req: asynchronous compress request 270*2ebda74fSGiovanni Cabiddu * 271*2ebda74fSGiovanni Cabiddu * Return: zero on success; error code in case of error 272*2ebda74fSGiovanni Cabiddu */ 273*2ebda74fSGiovanni Cabiddu static inline int crypto_acomp_decompress(struct acomp_req *req) 274*2ebda74fSGiovanni Cabiddu { 275*2ebda74fSGiovanni Cabiddu struct crypto_acomp *tfm = crypto_acomp_reqtfm(req); 276*2ebda74fSGiovanni Cabiddu struct acomp_alg *alg = crypto_acomp_alg(tfm); 277*2ebda74fSGiovanni Cabiddu 278*2ebda74fSGiovanni Cabiddu return alg->decompress(req); 279*2ebda74fSGiovanni Cabiddu } 280*2ebda74fSGiovanni Cabiddu 281*2ebda74fSGiovanni Cabiddu #endif 282