Back to home page

LXR

 
 

    


0001 /*
0002  * Asynchronous Compression operations
0003  *
0004  * Copyright (c) 2016, Intel Corporation
0005  * Authors: Weigang Li <weigang.li@intel.com>
0006  *          Giovanni Cabiddu <giovanni.cabiddu@intel.com>
0007  *
0008  * This program is free software; you can redistribute it and/or modify it
0009  * under the terms of the GNU General Public License as published by the Free
0010  * Software Foundation; either version 2 of the License, or (at your option)
0011  * any later version.
0012  *
0013  */
0014 #include <linux/errno.h>
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/seq_file.h>
0018 #include <linux/slab.h>
0019 #include <linux/string.h>
0020 #include <linux/crypto.h>
0021 #include <crypto/algapi.h>
0022 #include <linux/cryptouser.h>
0023 #include <net/netlink.h>
0024 #include <crypto/internal/acompress.h>
0025 #include <crypto/internal/scompress.h>
0026 #include "internal.h"
0027 
0028 static const struct crypto_type crypto_acomp_type;
0029 
0030 #ifdef CONFIG_NET
0031 static int crypto_acomp_report(struct sk_buff *skb, struct crypto_alg *alg)
0032 {
0033     struct crypto_report_acomp racomp;
0034 
0035     strncpy(racomp.type, "acomp", sizeof(racomp.type));
0036 
0037     if (nla_put(skb, CRYPTOCFGA_REPORT_ACOMP,
0038             sizeof(struct crypto_report_acomp), &racomp))
0039         goto nla_put_failure;
0040     return 0;
0041 
0042 nla_put_failure:
0043     return -EMSGSIZE;
0044 }
0045 #else
0046 static int crypto_acomp_report(struct sk_buff *skb, struct crypto_alg *alg)
0047 {
0048     return -ENOSYS;
0049 }
0050 #endif
0051 
0052 static void crypto_acomp_show(struct seq_file *m, struct crypto_alg *alg)
0053     __attribute__ ((unused));
0054 
0055 static void crypto_acomp_show(struct seq_file *m, struct crypto_alg *alg)
0056 {
0057     seq_puts(m, "type         : acomp\n");
0058 }
0059 
0060 static void crypto_acomp_exit_tfm(struct crypto_tfm *tfm)
0061 {
0062     struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm);
0063     struct acomp_alg *alg = crypto_acomp_alg(acomp);
0064 
0065     alg->exit(acomp);
0066 }
0067 
0068 static int crypto_acomp_init_tfm(struct crypto_tfm *tfm)
0069 {
0070     struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm);
0071     struct acomp_alg *alg = crypto_acomp_alg(acomp);
0072 
0073     if (tfm->__crt_alg->cra_type != &crypto_acomp_type)
0074         return crypto_init_scomp_ops_async(tfm);
0075 
0076     acomp->compress = alg->compress;
0077     acomp->decompress = alg->decompress;
0078     acomp->dst_free = alg->dst_free;
0079     acomp->reqsize = alg->reqsize;
0080 
0081     if (alg->exit)
0082         acomp->base.exit = crypto_acomp_exit_tfm;
0083 
0084     if (alg->init)
0085         return alg->init(acomp);
0086 
0087     return 0;
0088 }
0089 
0090 static unsigned int crypto_acomp_extsize(struct crypto_alg *alg)
0091 {
0092     int extsize = crypto_alg_extsize(alg);
0093 
0094     if (alg->cra_type != &crypto_acomp_type)
0095         extsize += sizeof(struct crypto_scomp *);
0096 
0097     return extsize;
0098 }
0099 
0100 static const struct crypto_type crypto_acomp_type = {
0101     .extsize = crypto_acomp_extsize,
0102     .init_tfm = crypto_acomp_init_tfm,
0103 #ifdef CONFIG_PROC_FS
0104     .show = crypto_acomp_show,
0105 #endif
0106     .report = crypto_acomp_report,
0107     .maskclear = ~CRYPTO_ALG_TYPE_MASK,
0108     .maskset = CRYPTO_ALG_TYPE_ACOMPRESS_MASK,
0109     .type = CRYPTO_ALG_TYPE_ACOMPRESS,
0110     .tfmsize = offsetof(struct crypto_acomp, base),
0111 };
0112 
0113 struct crypto_acomp *crypto_alloc_acomp(const char *alg_name, u32 type,
0114                     u32 mask)
0115 {
0116     return crypto_alloc_tfm(alg_name, &crypto_acomp_type, type, mask);
0117 }
0118 EXPORT_SYMBOL_GPL(crypto_alloc_acomp);
0119 
0120 struct acomp_req *acomp_request_alloc(struct crypto_acomp *acomp)
0121 {
0122     struct crypto_tfm *tfm = crypto_acomp_tfm(acomp);
0123     struct acomp_req *req;
0124 
0125     req = __acomp_request_alloc(acomp);
0126     if (req && (tfm->__crt_alg->cra_type != &crypto_acomp_type))
0127         return crypto_acomp_scomp_alloc_ctx(req);
0128 
0129     return req;
0130 }
0131 EXPORT_SYMBOL_GPL(acomp_request_alloc);
0132 
0133 void acomp_request_free(struct acomp_req *req)
0134 {
0135     struct crypto_acomp *acomp = crypto_acomp_reqtfm(req);
0136     struct crypto_tfm *tfm = crypto_acomp_tfm(acomp);
0137 
0138     if (tfm->__crt_alg->cra_type != &crypto_acomp_type)
0139         crypto_acomp_scomp_free_ctx(req);
0140 
0141     if (req->flags & CRYPTO_ACOMP_ALLOC_OUTPUT) {
0142         acomp->dst_free(req->dst);
0143         req->dst = NULL;
0144     }
0145 
0146     __acomp_request_free(req);
0147 }
0148 EXPORT_SYMBOL_GPL(acomp_request_free);
0149 
0150 int crypto_register_acomp(struct acomp_alg *alg)
0151 {
0152     struct crypto_alg *base = &alg->base;
0153 
0154     base->cra_type = &crypto_acomp_type;
0155     base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
0156     base->cra_flags |= CRYPTO_ALG_TYPE_ACOMPRESS;
0157 
0158     return crypto_register_alg(base);
0159 }
0160 EXPORT_SYMBOL_GPL(crypto_register_acomp);
0161 
0162 int crypto_unregister_acomp(struct acomp_alg *alg)
0163 {
0164     return crypto_unregister_alg(&alg->base);
0165 }
0166 EXPORT_SYMBOL_GPL(crypto_unregister_acomp);
0167 
0168 MODULE_LICENSE("GPL");
0169 MODULE_DESCRIPTION("Asynchronous compression type");