xref: /openbmc/linux/crypto/lzo-rle.c (revision 5f2fb52fac15a8a8e10ce020dd532504a8abfc4e)
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 lzorle_ctx {
15  	void *lzorle_comp_mem;
16  };
17  
18  static void *lzorle_alloc_ctx(struct crypto_scomp *tfm)
19  {
20  	void *ctx;
21  
22  	ctx = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
23  	if (!ctx)
24  		return ERR_PTR(-ENOMEM);
25  
26  	return ctx;
27  }
28  
29  static int lzorle_init(struct crypto_tfm *tfm)
30  {
31  	struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);
32  
33  	ctx->lzorle_comp_mem = lzorle_alloc_ctx(NULL);
34  	if (IS_ERR(ctx->lzorle_comp_mem))
35  		return -ENOMEM;
36  
37  	return 0;
38  }
39  
40  static void lzorle_free_ctx(struct crypto_scomp *tfm, void *ctx)
41  {
42  	kvfree(ctx);
43  }
44  
45  static void lzorle_exit(struct crypto_tfm *tfm)
46  {
47  	struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);
48  
49  	lzorle_free_ctx(NULL, ctx->lzorle_comp_mem);
50  }
51  
52  static int __lzorle_compress(const u8 *src, unsigned int slen,
53  			  u8 *dst, unsigned int *dlen, void *ctx)
54  {
55  	size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
56  	int err;
57  
58  	err = lzorle1x_1_compress(src, slen, dst, &tmp_len, ctx);
59  
60  	if (err != LZO_E_OK)
61  		return -EINVAL;
62  
63  	*dlen = tmp_len;
64  	return 0;
65  }
66  
67  static int lzorle_compress(struct crypto_tfm *tfm, const u8 *src,
68  			unsigned int slen, u8 *dst, unsigned int *dlen)
69  {
70  	struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);
71  
72  	return __lzorle_compress(src, slen, dst, dlen, ctx->lzorle_comp_mem);
73  }
74  
75  static int lzorle_scompress(struct crypto_scomp *tfm, const u8 *src,
76  			 unsigned int slen, u8 *dst, unsigned int *dlen,
77  			 void *ctx)
78  {
79  	return __lzorle_compress(src, slen, dst, dlen, ctx);
80  }
81  
82  static int __lzorle_decompress(const u8 *src, unsigned int slen,
83  			    u8 *dst, unsigned int *dlen)
84  {
85  	int err;
86  	size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
87  
88  	err = lzo1x_decompress_safe(src, slen, dst, &tmp_len);
89  
90  	if (err != LZO_E_OK)
91  		return -EINVAL;
92  
93  	*dlen = tmp_len;
94  	return 0;
95  }
96  
97  static int lzorle_decompress(struct crypto_tfm *tfm, const u8 *src,
98  			  unsigned int slen, u8 *dst, unsigned int *dlen)
99  {
100  	return __lzorle_decompress(src, slen, dst, dlen);
101  }
102  
103  static int lzorle_sdecompress(struct crypto_scomp *tfm, const u8 *src,
104  			   unsigned int slen, u8 *dst, unsigned int *dlen,
105  			   void *ctx)
106  {
107  	return __lzorle_decompress(src, slen, dst, dlen);
108  }
109  
110  static struct crypto_alg alg = {
111  	.cra_name		= "lzo-rle",
112  	.cra_driver_name	= "lzo-rle-generic",
113  	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
114  	.cra_ctxsize		= sizeof(struct lzorle_ctx),
115  	.cra_module		= THIS_MODULE,
116  	.cra_init		= lzorle_init,
117  	.cra_exit		= lzorle_exit,
118  	.cra_u			= { .compress = {
119  	.coa_compress		= lzorle_compress,
120  	.coa_decompress		= lzorle_decompress } }
121  };
122  
123  static struct scomp_alg scomp = {
124  	.alloc_ctx		= lzorle_alloc_ctx,
125  	.free_ctx		= lzorle_free_ctx,
126  	.compress		= lzorle_scompress,
127  	.decompress		= lzorle_sdecompress,
128  	.base			= {
129  		.cra_name	= "lzo-rle",
130  		.cra_driver_name = "lzo-rle-scomp",
131  		.cra_module	 = THIS_MODULE,
132  	}
133  };
134  
135  static int __init lzorle_mod_init(void)
136  {
137  	int ret;
138  
139  	ret = crypto_register_alg(&alg);
140  	if (ret)
141  		return ret;
142  
143  	ret = crypto_register_scomp(&scomp);
144  	if (ret) {
145  		crypto_unregister_alg(&alg);
146  		return ret;
147  	}
148  
149  	return ret;
150  }
151  
152  static void __exit lzorle_mod_fini(void)
153  {
154  	crypto_unregister_alg(&alg);
155  	crypto_unregister_scomp(&scomp);
156  }
157  
158  subsys_initcall(lzorle_mod_init);
159  module_exit(lzorle_mod_fini);
160  
161  MODULE_LICENSE("GPL");
162  MODULE_DESCRIPTION("LZO-RLE Compression Algorithm");
163  MODULE_ALIAS_CRYPTO("lzo-rle");
164