@@ -33,6 +33,55 @@ static inline struct acomp_alg *crypto_acomp_alg(struct crypto_acomp *tfm)
return __crypto_acomp_alg(crypto_acomp_tfm(tfm)->__crt_alg);
}
+static int acomp_no_setparam(struct crypto_acomp *tfm, const u8 *param,
+ unsigned int len)
+{
+ return -ENOSYS;
+}
+
+static int acomp_set_need_param(struct crypto_acomp *tfm,
+ struct acomp_alg *alg)
+{
+ if (alg->calg.base.cra_type != &crypto_acomp_type) {
+ struct crypto_scomp **ctx = acomp_tfm_ctx(tfm);
+ struct crypto_scomp *scomp = *ctx;
+
+ if (!crypto_scomp_alg_has_setparam(crypto_scomp_alg(scomp)))
+ return 0;
+ } else if (alg->setparam == acomp_no_setparam)
+ return 0;
+
+ if ((alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY))
+ crypto_acomp_set_flags(tfm, CRYPTO_TFM_NEED_KEY);
+
+ return 0;
+}
+
+int crypto_acomp_setparam(struct crypto_acomp *tfm, const u8 *param,
+ unsigned int len)
+{
+ struct acomp_alg *alg = crypto_acomp_alg(tfm);
+ int err;
+
+ if (alg->calg.base.cra_type == &crypto_acomp_type)
+ err = alg->setparam(tfm, param, len);
+ else {
+ struct crypto_scomp **ctx = acomp_tfm_ctx(tfm);
+ struct crypto_scomp *scomp = *ctx;
+
+ err = crypto_scomp_setparam(scomp, param, len);
+ }
+
+ if (unlikely(err)) {
+ acomp_set_need_param(tfm, alg);
+ return err;
+ }
+
+ crypto_acomp_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_acomp_setparam);
+
static int __maybe_unused crypto_acomp_report(
struct sk_buff *skb, struct crypto_alg *alg)
{
@@ -66,8 +115,9 @@ static int crypto_acomp_init_tfm(struct crypto_tfm *tfm)
struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm);
struct acomp_alg *alg = crypto_acomp_alg(acomp);
- if (tfm->__crt_alg->cra_type != &crypto_acomp_type)
- return crypto_init_scomp_ops_async(tfm);
+ if (alg->calg.base.cra_type != &crypto_acomp_type)
+ return crypto_init_scomp_ops_async(tfm) ?:
+ acomp_set_need_param(acomp, alg);
acomp->compress = alg->compress;
acomp->decompress = alg->decompress;
@@ -77,10 +127,8 @@ static int crypto_acomp_init_tfm(struct crypto_tfm *tfm)
if (alg->exit)
acomp->base.exit = crypto_acomp_exit_tfm;
- if (alg->init)
- return alg->init(acomp);
-
- return 0;
+ return (alg->init ? alg->init(acomp) : 0) ?:
+ acomp_set_need_param(acomp, alg);
}
static unsigned int crypto_acomp_extsize(struct crypto_alg *alg)
@@ -160,11 +208,19 @@ void comp_prepare_alg(struct comp_alg_common *alg)
base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
}
+static void acomp_prepare_alg(struct acomp_alg *alg)
+{
+ comp_prepare_alg(&alg->calg);
+
+ if (!alg->setparam)
+ alg->setparam = acomp_no_setparam;
+}
+
int crypto_register_acomp(struct acomp_alg *alg)
{
struct crypto_alg *base = &alg->calg.base;
- comp_prepare_alg(&alg->calg);
+ acomp_prepare_alg(alg);
base->cra_type = &crypto_acomp_type;
base->cra_flags |= CRYPTO_ALG_TYPE_ACOMPRESS;
@@ -9,15 +9,22 @@
#ifndef _LOCAL_CRYPTO_COMPRESS_H
#define _LOCAL_CRYPTO_COMPRESS_H
+#include <crypto/internal/scompress.h>
#include "internal.h"
struct acomp_req;
-struct comp_alg_common;
int crypto_init_scomp_ops_async(struct crypto_tfm *tfm);
struct acomp_req *crypto_acomp_scomp_alloc_ctx(struct acomp_req *req);
void crypto_acomp_scomp_free_ctx(struct acomp_req *req);
+int scomp_no_setparam(struct crypto_scomp *tfm, const u8 *param,
+ unsigned int len);
void comp_prepare_alg(struct comp_alg_common *alg);
+static inline bool crypto_scomp_alg_has_setparam(struct scomp_alg *alg)
+{
+ return alg->setparam != scomp_no_setparam;
+}
+
#endif /* _LOCAL_CRYPTO_COMPRESS_H */
@@ -42,17 +42,12 @@ static inline struct crypto_scomp *__crypto_scomp_cast(struct crypto_tfm *tfm)
return container_of(tfm, struct crypto_scomp, base);
}
-static int scomp_no_setparam(struct crypto_scomp *tfm, const u8 *param,
- unsigned int len)
+int scomp_no_setparam(struct crypto_scomp *tfm, const u8 *param,
+ unsigned int len)
{
return -ENOSYS;
}
-static bool crypto_scomp_alg_has_setparam(struct scomp_alg *alg)
-{
- return alg->setparam != scomp_no_setparam;
-}
-
static bool crypto_scomp_alg_needs_param(struct scomp_alg *alg)
{
return crypto_scomp_alg_has_setparam(alg) &&
@@ -125,6 +125,21 @@ static inline struct comp_alg_common *crypto_comp_alg_common(
return __crypto_comp_alg_common(crypto_acomp_tfm(tfm)->__crt_alg);
}
+static inline u32 crypto_acomp_get_flags(struct crypto_acomp *tfm)
+{
+ return crypto_tfm_get_flags(crypto_acomp_tfm(tfm));
+}
+
+static inline void crypto_acomp_set_flags(struct crypto_acomp *tfm, u32 flags)
+{
+ crypto_tfm_set_flags(crypto_acomp_tfm(tfm), flags);
+}
+
+static inline void crypto_acomp_clear_flags(struct crypto_acomp *tfm, u32 flags)
+{
+ crypto_tfm_clear_flags(crypto_acomp_tfm(tfm), flags);
+}
+
static inline unsigned int crypto_acomp_reqsize(struct crypto_acomp *tfm)
{
return tfm->reqsize;
@@ -248,7 +263,12 @@ static inline void acomp_request_set_params(struct acomp_req *req,
*/
static inline int crypto_acomp_compress(struct acomp_req *req)
{
- return crypto_acomp_reqtfm(req)->compress(req);
+ struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+
+ if (crypto_acomp_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
+ return -ENOKEY;
+
+ return tfm->compress(req);
}
/**
@@ -262,7 +282,15 @@ static inline int crypto_acomp_compress(struct acomp_req *req)
*/
static inline int crypto_acomp_decompress(struct acomp_req *req)
{
- return crypto_acomp_reqtfm(req)->decompress(req);
+ struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
+
+ if (crypto_acomp_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
+ return -ENOKEY;
+
+ return tfm->decompress(req);
}
+int crypto_acomp_setparam(struct crypto_acomp *tfm,
+ const u8 *param, unsigned int len);
+
#endif
@@ -17,6 +17,7 @@
*
* @compress: Function performs a compress operation
* @decompress: Function performs a de-compress operation
+ * @setparam: Set parameters of the algorithm (e.g., compression level)
* @dst_free: Frees destination buffer if allocated inside the algorithm
* @init: Initialize the cryptographic transformation object.
* This function is used to initialize the cryptographic
@@ -37,6 +38,8 @@
struct acomp_alg {
int (*compress)(struct acomp_req *req);
int (*decompress)(struct acomp_req *req);
+ int (*setparam)(struct crypto_acomp *tfm, const u8 *param,
+ unsigned int len);
void (*dst_free)(struct scatterlist *dst);
int (*init)(struct crypto_acomp *tfm);
void (*exit)(struct crypto_acomp *tfm);
Add the acompress plubming for setparam. This is modelled after setkey for ahash. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> --- crypto/acompress.c | 70 ++++++++++++++++++++++++++--- crypto/compress.h | 9 +++- crypto/scompress.c | 9 +--- include/crypto/acompress.h | 32 ++++++++++++- include/crypto/internal/acompress.h | 3 ++ 5 files changed, 106 insertions(+), 17 deletions(-)