Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Asynchronous Compression operations
4 : *
5 : * Copyright (c) 2016, Intel Corporation
6 : * Authors: Weigang Li <weigang.li@intel.com>
7 : * Giovanni Cabiddu <giovanni.cabiddu@intel.com>
8 : */
9 : #include <linux/errno.h>
10 : #include <linux/kernel.h>
11 : #include <linux/module.h>
12 : #include <linux/seq_file.h>
13 : #include <linux/slab.h>
14 : #include <linux/string.h>
15 : #include <linux/crypto.h>
16 : #include <crypto/algapi.h>
17 : #include <linux/cryptouser.h>
18 : #include <linux/compiler.h>
19 : #include <net/netlink.h>
20 : #include <crypto/internal/acompress.h>
21 : #include <crypto/internal/scompress.h>
22 : #include "internal.h"
23 :
24 : static const struct crypto_type crypto_acomp_type;
25 :
26 : #ifdef CONFIG_NET
27 0 : static int crypto_acomp_report(struct sk_buff *skb, struct crypto_alg *alg)
28 : {
29 0 : struct crypto_report_acomp racomp;
30 :
31 0 : memset(&racomp, 0, sizeof(racomp));
32 :
33 0 : strscpy(racomp.type, "acomp", sizeof(racomp.type));
34 :
35 0 : return nla_put(skb, CRYPTOCFGA_REPORT_ACOMP, sizeof(racomp), &racomp);
36 : }
37 : #else
38 : static int crypto_acomp_report(struct sk_buff *skb, struct crypto_alg *alg)
39 : {
40 : return -ENOSYS;
41 : }
42 : #endif
43 :
44 : static void crypto_acomp_show(struct seq_file *m, struct crypto_alg *alg)
45 : __maybe_unused;
46 :
47 0 : static void crypto_acomp_show(struct seq_file *m, struct crypto_alg *alg)
48 : {
49 0 : seq_puts(m, "type : acomp\n");
50 0 : }
51 :
52 0 : static void crypto_acomp_exit_tfm(struct crypto_tfm *tfm)
53 : {
54 0 : struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm);
55 0 : struct acomp_alg *alg = crypto_acomp_alg(acomp);
56 :
57 0 : alg->exit(acomp);
58 0 : }
59 :
60 0 : static int crypto_acomp_init_tfm(struct crypto_tfm *tfm)
61 : {
62 0 : struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm);
63 0 : struct acomp_alg *alg = crypto_acomp_alg(acomp);
64 :
65 0 : if (tfm->__crt_alg->cra_type != &crypto_acomp_type)
66 0 : return crypto_init_scomp_ops_async(tfm);
67 :
68 0 : acomp->compress = alg->compress;
69 0 : acomp->decompress = alg->decompress;
70 0 : acomp->dst_free = alg->dst_free;
71 0 : acomp->reqsize = alg->reqsize;
72 :
73 0 : if (alg->exit)
74 0 : acomp->base.exit = crypto_acomp_exit_tfm;
75 :
76 0 : if (alg->init)
77 0 : return alg->init(acomp);
78 :
79 : return 0;
80 : }
81 :
82 0 : static unsigned int crypto_acomp_extsize(struct crypto_alg *alg)
83 : {
84 0 : int extsize = crypto_alg_extsize(alg);
85 :
86 0 : if (alg->cra_type != &crypto_acomp_type)
87 0 : extsize += sizeof(struct crypto_scomp *);
88 :
89 0 : return extsize;
90 : }
91 :
92 : static const struct crypto_type crypto_acomp_type = {
93 : .extsize = crypto_acomp_extsize,
94 : .init_tfm = crypto_acomp_init_tfm,
95 : #ifdef CONFIG_PROC_FS
96 : .show = crypto_acomp_show,
97 : #endif
98 : .report = crypto_acomp_report,
99 : .maskclear = ~CRYPTO_ALG_TYPE_MASK,
100 : .maskset = CRYPTO_ALG_TYPE_ACOMPRESS_MASK,
101 : .type = CRYPTO_ALG_TYPE_ACOMPRESS,
102 : .tfmsize = offsetof(struct crypto_acomp, base),
103 : };
104 :
105 0 : struct crypto_acomp *crypto_alloc_acomp(const char *alg_name, u32 type,
106 : u32 mask)
107 : {
108 0 : return crypto_alloc_tfm(alg_name, &crypto_acomp_type, type, mask);
109 : }
110 : EXPORT_SYMBOL_GPL(crypto_alloc_acomp);
111 :
112 0 : struct crypto_acomp *crypto_alloc_acomp_node(const char *alg_name, u32 type,
113 : u32 mask, int node)
114 : {
115 0 : return crypto_alloc_tfm_node(alg_name, &crypto_acomp_type, type, mask,
116 : node);
117 : }
118 : EXPORT_SYMBOL_GPL(crypto_alloc_acomp_node);
119 :
120 0 : struct acomp_req *acomp_request_alloc(struct crypto_acomp *acomp)
121 : {
122 0 : struct crypto_tfm *tfm = crypto_acomp_tfm(acomp);
123 0 : struct acomp_req *req;
124 :
125 0 : req = __acomp_request_alloc(acomp);
126 0 : if (req && (tfm->__crt_alg->cra_type != &crypto_acomp_type))
127 0 : return crypto_acomp_scomp_alloc_ctx(req);
128 :
129 : return req;
130 : }
131 : EXPORT_SYMBOL_GPL(acomp_request_alloc);
132 :
133 0 : void acomp_request_free(struct acomp_req *req)
134 : {
135 0 : struct crypto_acomp *acomp = crypto_acomp_reqtfm(req);
136 0 : struct crypto_tfm *tfm = crypto_acomp_tfm(acomp);
137 :
138 0 : if (tfm->__crt_alg->cra_type != &crypto_acomp_type)
139 0 : crypto_acomp_scomp_free_ctx(req);
140 :
141 0 : if (req->flags & CRYPTO_ACOMP_ALLOC_OUTPUT) {
142 0 : acomp->dst_free(req->dst);
143 0 : req->dst = NULL;
144 : }
145 :
146 0 : __acomp_request_free(req);
147 0 : }
148 : EXPORT_SYMBOL_GPL(acomp_request_free);
149 :
150 0 : int crypto_register_acomp(struct acomp_alg *alg)
151 : {
152 0 : struct crypto_alg *base = &alg->base;
153 :
154 0 : base->cra_type = &crypto_acomp_type;
155 0 : base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
156 0 : base->cra_flags |= CRYPTO_ALG_TYPE_ACOMPRESS;
157 :
158 0 : return crypto_register_alg(base);
159 : }
160 : EXPORT_SYMBOL_GPL(crypto_register_acomp);
161 :
162 0 : void crypto_unregister_acomp(struct acomp_alg *alg)
163 : {
164 0 : crypto_unregister_alg(&alg->base);
165 0 : }
166 : EXPORT_SYMBOL_GPL(crypto_unregister_acomp);
167 :
168 0 : int crypto_register_acomps(struct acomp_alg *algs, int count)
169 : {
170 0 : int i, ret;
171 :
172 0 : for (i = 0; i < count; i++) {
173 0 : ret = crypto_register_acomp(&algs[i]);
174 0 : if (ret)
175 0 : goto err;
176 : }
177 :
178 : return 0;
179 :
180 0 : err:
181 0 : for (--i; i >= 0; --i)
182 0 : crypto_unregister_acomp(&algs[i]);
183 :
184 : return ret;
185 : }
186 : EXPORT_SYMBOL_GPL(crypto_register_acomps);
187 :
188 0 : void crypto_unregister_acomps(struct acomp_alg *algs, int count)
189 : {
190 0 : int i;
191 :
192 0 : for (i = count - 1; i >= 0; --i)
193 0 : crypto_unregister_acomp(&algs[i]);
194 0 : }
195 : EXPORT_SYMBOL_GPL(crypto_unregister_acomps);
196 :
197 : MODULE_LICENSE("GPL");
198 : MODULE_DESCRIPTION("Asynchronous compression type");
|