Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * Cryptographic API.
4 : : */
5 : :
6 : : #include <linux/init.h>
7 : : #include <linux/module.h>
8 : : #include <linux/crypto.h>
9 : : #include <linux/vmalloc.h>
10 : : #include <linux/mm.h>
11 : : #include <linux/lzo.h>
12 : : #include <crypto/internal/scompress.h>
13 : :
14 : : struct lzo_ctx {
15 : : void *lzo_comp_mem;
16 : : };
17 : :
18 : 0 : static void *lzo_alloc_ctx(struct crypto_scomp *tfm)
19 : : {
20 : : void *ctx;
21 : :
22 : : ctx = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
23 [ # # # # ]: 0 : if (!ctx)
24 : : return ERR_PTR(-ENOMEM);
25 : :
26 : 0 : return ctx;
27 : : }
28 : :
29 : 0 : static int lzo_init(struct crypto_tfm *tfm)
30 : : {
31 : : struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
32 : :
33 : 0 : ctx->lzo_comp_mem = lzo_alloc_ctx(NULL);
34 [ # # ]: 0 : if (IS_ERR(ctx->lzo_comp_mem))
35 : : return -ENOMEM;
36 : :
37 : 0 : return 0;
38 : : }
39 : :
40 : 0 : static void lzo_free_ctx(struct crypto_scomp *tfm, void *ctx)
41 : : {
42 : 0 : kvfree(ctx);
43 : 0 : }
44 : :
45 : 0 : static void lzo_exit(struct crypto_tfm *tfm)
46 : : {
47 : : struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
48 : :
49 : 0 : lzo_free_ctx(NULL, ctx->lzo_comp_mem);
50 : 0 : }
51 : :
52 : : static int __lzo_compress(const u8 *src, unsigned int slen,
53 : : u8 *dst, unsigned int *dlen, void *ctx)
54 : : {
55 : 0 : size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
56 : : int err;
57 : :
58 : 0 : err = lzo1x_1_compress(src, slen, dst, &tmp_len, ctx);
59 : :
60 [ # # # # ]: 0 : if (err != LZO_E_OK)
61 : : return -EINVAL;
62 : :
63 : 0 : *dlen = tmp_len;
64 : : return 0;
65 : : }
66 : :
67 : 0 : static int lzo_compress(struct crypto_tfm *tfm, const u8 *src,
68 : : unsigned int slen, u8 *dst, unsigned int *dlen)
69 : : {
70 : : struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
71 : :
72 : 0 : return __lzo_compress(src, slen, dst, dlen, ctx->lzo_comp_mem);
73 : : }
74 : :
75 : 0 : static int lzo_scompress(struct crypto_scomp *tfm, const u8 *src,
76 : : unsigned int slen, u8 *dst, unsigned int *dlen,
77 : : void *ctx)
78 : : {
79 : 0 : return __lzo_compress(src, slen, dst, dlen, ctx);
80 : : }
81 : :
82 : : static int __lzo_decompress(const u8 *src, unsigned int slen,
83 : : u8 *dst, unsigned int *dlen)
84 : : {
85 : : int err;
86 : 0 : size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
87 : :
88 : 0 : err = lzo1x_decompress_safe(src, slen, dst, &tmp_len);
89 : :
90 [ # # # # ]: 0 : if (err != LZO_E_OK)
91 : : return -EINVAL;
92 : :
93 : 0 : *dlen = tmp_len;
94 : : return 0;
95 : : }
96 : :
97 : 0 : static int lzo_decompress(struct crypto_tfm *tfm, const u8 *src,
98 : : unsigned int slen, u8 *dst, unsigned int *dlen)
99 : : {
100 : 0 : return __lzo_decompress(src, slen, dst, dlen);
101 : : }
102 : :
103 : 0 : static int lzo_sdecompress(struct crypto_scomp *tfm, const u8 *src,
104 : : unsigned int slen, u8 *dst, unsigned int *dlen,
105 : : void *ctx)
106 : : {
107 : 0 : return __lzo_decompress(src, slen, dst, dlen);
108 : : }
109 : :
110 : : static struct crypto_alg alg = {
111 : : .cra_name = "lzo",
112 : : .cra_driver_name = "lzo-generic",
113 : : .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
114 : : .cra_ctxsize = sizeof(struct lzo_ctx),
115 : : .cra_module = THIS_MODULE,
116 : : .cra_init = lzo_init,
117 : : .cra_exit = lzo_exit,
118 : : .cra_u = { .compress = {
119 : : .coa_compress = lzo_compress,
120 : : .coa_decompress = lzo_decompress } }
121 : : };
122 : :
123 : : static struct scomp_alg scomp = {
124 : : .alloc_ctx = lzo_alloc_ctx,
125 : : .free_ctx = lzo_free_ctx,
126 : : .compress = lzo_scompress,
127 : : .decompress = lzo_sdecompress,
128 : : .base = {
129 : : .cra_name = "lzo",
130 : : .cra_driver_name = "lzo-scomp",
131 : : .cra_module = THIS_MODULE,
132 : : }
133 : : };
134 : :
135 : 404 : static int __init lzo_mod_init(void)
136 : : {
137 : : int ret;
138 : :
139 : 404 : ret = crypto_register_alg(&alg);
140 [ + - ]: 404 : if (ret)
141 : : return ret;
142 : :
143 : 404 : ret = crypto_register_scomp(&scomp);
144 [ - + ]: 404 : if (ret) {
145 : 0 : crypto_unregister_alg(&alg);
146 : 0 : return ret;
147 : : }
148 : :
149 : : return ret;
150 : : }
151 : :
152 : 0 : static void __exit lzo_mod_fini(void)
153 : : {
154 : 0 : crypto_unregister_alg(&alg);
155 : 0 : crypto_unregister_scomp(&scomp);
156 : 0 : }
157 : :
158 : : subsys_initcall(lzo_mod_init);
159 : : module_exit(lzo_mod_fini);
160 : :
161 : : MODULE_LICENSE("GPL");
162 : : MODULE_DESCRIPTION("LZO Compression Algorithm");
163 : : MODULE_ALIAS_CRYPTO("lzo");
|