xref: /linux/drivers/crypto/cavium/zip/zip_crypto.c (revision f05845fcba12579ad84f58386b60adbfc14397b2)
1*f05845fcSMahipal Challa /***********************license start************************************
2*f05845fcSMahipal Challa  * Copyright (c) 2003-2017 Cavium, Inc.
3*f05845fcSMahipal Challa  * All rights reserved.
4*f05845fcSMahipal Challa  *
5*f05845fcSMahipal Challa  * License: one of 'Cavium License' or 'GNU General Public License Version 2'
6*f05845fcSMahipal Challa  *
7*f05845fcSMahipal Challa  * This file is provided under the terms of the Cavium License (see below)
8*f05845fcSMahipal Challa  * or under the terms of GNU General Public License, Version 2, as
9*f05845fcSMahipal Challa  * published by the Free Software Foundation. When using or redistributing
10*f05845fcSMahipal Challa  * this file, you may do so under either license.
11*f05845fcSMahipal Challa  *
12*f05845fcSMahipal Challa  * Cavium License:  Redistribution and use in source and binary forms, with
13*f05845fcSMahipal Challa  * or without modification, are permitted provided that the following
14*f05845fcSMahipal Challa  * conditions are met:
15*f05845fcSMahipal Challa  *
16*f05845fcSMahipal Challa  *  * Redistributions of source code must retain the above copyright
17*f05845fcSMahipal Challa  *    notice, this list of conditions and the following disclaimer.
18*f05845fcSMahipal Challa  *
19*f05845fcSMahipal Challa  *  * Redistributions in binary form must reproduce the above
20*f05845fcSMahipal Challa  *    copyright notice, this list of conditions and the following
21*f05845fcSMahipal Challa  *    disclaimer in the documentation and/or other materials provided
22*f05845fcSMahipal Challa  *    with the distribution.
23*f05845fcSMahipal Challa  *
24*f05845fcSMahipal Challa  *  * Neither the name of Cavium Inc. nor the names of its contributors may be
25*f05845fcSMahipal Challa  *    used to endorse or promote products derived from this software without
26*f05845fcSMahipal Challa  *    specific prior written permission.
27*f05845fcSMahipal Challa  *
28*f05845fcSMahipal Challa  * This Software, including technical data, may be subject to U.S. export
29*f05845fcSMahipal Challa  * control laws, including the U.S. Export Administration Act and its
30*f05845fcSMahipal Challa  * associated regulations, and may be subject to export or import
31*f05845fcSMahipal Challa  * regulations in other countries.
32*f05845fcSMahipal Challa  *
33*f05845fcSMahipal Challa  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
34*f05845fcSMahipal Challa  * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS
35*f05845fcSMahipal Challa  * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
36*f05845fcSMahipal Challa  * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
37*f05845fcSMahipal Challa  * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
38*f05845fcSMahipal Challa  * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY)
39*f05845fcSMahipal Challa  * WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A
40*f05845fcSMahipal Challa  * PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET
41*f05845fcSMahipal Challa  * ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE
42*f05845fcSMahipal Challa  * ENTIRE  RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES
43*f05845fcSMahipal Challa  * WITH YOU.
44*f05845fcSMahipal Challa  ***********************license end**************************************/
45*f05845fcSMahipal Challa 
46*f05845fcSMahipal Challa #include "zip_crypto.h"
47*f05845fcSMahipal Challa 
48*f05845fcSMahipal Challa static void zip_static_init_zip_ops(struct zip_operation *zip_ops,
49*f05845fcSMahipal Challa 				    int lzs_flag)
50*f05845fcSMahipal Challa {
51*f05845fcSMahipal Challa 	zip_ops->flush        = ZIP_FLUSH_FINISH;
52*f05845fcSMahipal Challa 
53*f05845fcSMahipal Challa 	/* equivalent to level 6 of opensource zlib */
54*f05845fcSMahipal Challa 	zip_ops->speed          = 1;
55*f05845fcSMahipal Challa 
56*f05845fcSMahipal Challa 	if (!lzs_flag) {
57*f05845fcSMahipal Challa 		zip_ops->ccode		= 0; /* Auto Huffman */
58*f05845fcSMahipal Challa 		zip_ops->lzs_flag	= 0;
59*f05845fcSMahipal Challa 		zip_ops->format		= ZLIB_FORMAT;
60*f05845fcSMahipal Challa 	} else {
61*f05845fcSMahipal Challa 		zip_ops->ccode		= 3; /* LZS Encoding */
62*f05845fcSMahipal Challa 		zip_ops->lzs_flag	= 1;
63*f05845fcSMahipal Challa 		zip_ops->format		= LZS_FORMAT;
64*f05845fcSMahipal Challa 	}
65*f05845fcSMahipal Challa 	zip_ops->begin_file   = 1;
66*f05845fcSMahipal Challa 	zip_ops->history_len  = 0;
67*f05845fcSMahipal Challa 	zip_ops->end_file     = 1;
68*f05845fcSMahipal Challa 	zip_ops->compcode     = 0;
69*f05845fcSMahipal Challa 	zip_ops->csum	      = 1; /* Adler checksum desired */
70*f05845fcSMahipal Challa }
71*f05845fcSMahipal Challa 
72*f05845fcSMahipal Challa int zip_ctx_init(struct zip_kernel_ctx *zip_ctx, int lzs_flag)
73*f05845fcSMahipal Challa {
74*f05845fcSMahipal Challa 	struct zip_operation  *comp_ctx   = &zip_ctx->zip_comp;
75*f05845fcSMahipal Challa 	struct zip_operation  *decomp_ctx = &zip_ctx->zip_decomp;
76*f05845fcSMahipal Challa 
77*f05845fcSMahipal Challa 	zip_static_init_zip_ops(comp_ctx, lzs_flag);
78*f05845fcSMahipal Challa 	zip_static_init_zip_ops(decomp_ctx, lzs_flag);
79*f05845fcSMahipal Challa 
80*f05845fcSMahipal Challa 	comp_ctx->input  = zip_data_buf_alloc(MAX_INPUT_BUFFER_SIZE);
81*f05845fcSMahipal Challa 	if (!comp_ctx->input)
82*f05845fcSMahipal Challa 		return -ENOMEM;
83*f05845fcSMahipal Challa 
84*f05845fcSMahipal Challa 	comp_ctx->output = zip_data_buf_alloc(MAX_OUTPUT_BUFFER_SIZE);
85*f05845fcSMahipal Challa 	if (!comp_ctx->output)
86*f05845fcSMahipal Challa 		goto err_comp_input;
87*f05845fcSMahipal Challa 
88*f05845fcSMahipal Challa 	decomp_ctx->input  = zip_data_buf_alloc(MAX_INPUT_BUFFER_SIZE);
89*f05845fcSMahipal Challa 	if (!decomp_ctx->input)
90*f05845fcSMahipal Challa 		goto err_comp_output;
91*f05845fcSMahipal Challa 
92*f05845fcSMahipal Challa 	decomp_ctx->output = zip_data_buf_alloc(MAX_OUTPUT_BUFFER_SIZE);
93*f05845fcSMahipal Challa 	if (!decomp_ctx->output)
94*f05845fcSMahipal Challa 		goto err_decomp_input;
95*f05845fcSMahipal Challa 
96*f05845fcSMahipal Challa 	return 0;
97*f05845fcSMahipal Challa 
98*f05845fcSMahipal Challa err_decomp_input:
99*f05845fcSMahipal Challa 	zip_data_buf_free(decomp_ctx->input, MAX_INPUT_BUFFER_SIZE);
100*f05845fcSMahipal Challa 
101*f05845fcSMahipal Challa err_comp_output:
102*f05845fcSMahipal Challa 	zip_data_buf_free(comp_ctx->output, MAX_OUTPUT_BUFFER_SIZE);
103*f05845fcSMahipal Challa 
104*f05845fcSMahipal Challa err_comp_input:
105*f05845fcSMahipal Challa 	zip_data_buf_free(comp_ctx->input, MAX_INPUT_BUFFER_SIZE);
106*f05845fcSMahipal Challa 
107*f05845fcSMahipal Challa 	return -ENOMEM;
108*f05845fcSMahipal Challa }
109*f05845fcSMahipal Challa 
110*f05845fcSMahipal Challa void zip_ctx_exit(struct zip_kernel_ctx *zip_ctx)
111*f05845fcSMahipal Challa {
112*f05845fcSMahipal Challa 	struct zip_operation  *comp_ctx   = &zip_ctx->zip_comp;
113*f05845fcSMahipal Challa 	struct zip_operation  *dec_ctx = &zip_ctx->zip_decomp;
114*f05845fcSMahipal Challa 
115*f05845fcSMahipal Challa 	zip_data_buf_free(comp_ctx->input, MAX_INPUT_BUFFER_SIZE);
116*f05845fcSMahipal Challa 	zip_data_buf_free(comp_ctx->output, MAX_OUTPUT_BUFFER_SIZE);
117*f05845fcSMahipal Challa 
118*f05845fcSMahipal Challa 	zip_data_buf_free(dec_ctx->input, MAX_INPUT_BUFFER_SIZE);
119*f05845fcSMahipal Challa 	zip_data_buf_free(dec_ctx->output, MAX_OUTPUT_BUFFER_SIZE);
120*f05845fcSMahipal Challa }
121*f05845fcSMahipal Challa 
122*f05845fcSMahipal Challa int zip_compress(const u8 *src, unsigned int slen,
123*f05845fcSMahipal Challa 		 u8 *dst, unsigned int *dlen,
124*f05845fcSMahipal Challa 		 struct zip_kernel_ctx *zip_ctx)
125*f05845fcSMahipal Challa {
126*f05845fcSMahipal Challa 	struct zip_operation  *zip_ops   = NULL;
127*f05845fcSMahipal Challa 	struct zip_state      zip_state;
128*f05845fcSMahipal Challa 	struct zip_device     *zip = NULL;
129*f05845fcSMahipal Challa 	int ret;
130*f05845fcSMahipal Challa 
131*f05845fcSMahipal Challa 	if (!zip_ctx || !src || !dst || !dlen)
132*f05845fcSMahipal Challa 		return -ENOMEM;
133*f05845fcSMahipal Challa 
134*f05845fcSMahipal Challa 	zip = zip_get_device(zip_get_node_id());
135*f05845fcSMahipal Challa 	if (!zip)
136*f05845fcSMahipal Challa 		return -ENODEV;
137*f05845fcSMahipal Challa 
138*f05845fcSMahipal Challa 	memset(&zip_state, 0, sizeof(struct zip_state));
139*f05845fcSMahipal Challa 	zip_ops = &zip_ctx->zip_comp;
140*f05845fcSMahipal Challa 
141*f05845fcSMahipal Challa 	zip_ops->input_len  = slen;
142*f05845fcSMahipal Challa 	zip_ops->output_len = *dlen;
143*f05845fcSMahipal Challa 	memcpy(zip_ops->input, src, slen);
144*f05845fcSMahipal Challa 
145*f05845fcSMahipal Challa 	ret = zip_deflate(zip_ops, &zip_state, zip);
146*f05845fcSMahipal Challa 
147*f05845fcSMahipal Challa 	if (!ret) {
148*f05845fcSMahipal Challa 		*dlen = zip_ops->output_len;
149*f05845fcSMahipal Challa 		memcpy(dst, zip_ops->output, *dlen);
150*f05845fcSMahipal Challa 	}
151*f05845fcSMahipal Challa 
152*f05845fcSMahipal Challa 	return ret;
153*f05845fcSMahipal Challa }
154*f05845fcSMahipal Challa 
155*f05845fcSMahipal Challa int zip_decompress(const u8 *src, unsigned int slen,
156*f05845fcSMahipal Challa 		   u8 *dst, unsigned int *dlen,
157*f05845fcSMahipal Challa 		   struct zip_kernel_ctx *zip_ctx)
158*f05845fcSMahipal Challa {
159*f05845fcSMahipal Challa 	struct zip_operation  *zip_ops   = NULL;
160*f05845fcSMahipal Challa 	struct zip_state      zip_state;
161*f05845fcSMahipal Challa 	struct zip_device     *zip = NULL;
162*f05845fcSMahipal Challa 	int ret;
163*f05845fcSMahipal Challa 
164*f05845fcSMahipal Challa 	if (!zip_ctx || !src || !dst || !dlen)
165*f05845fcSMahipal Challa 		return -ENOMEM;
166*f05845fcSMahipal Challa 
167*f05845fcSMahipal Challa 	zip = zip_get_device(zip_get_node_id());
168*f05845fcSMahipal Challa 	if (!zip)
169*f05845fcSMahipal Challa 		return -ENODEV;
170*f05845fcSMahipal Challa 
171*f05845fcSMahipal Challa 	memset(&zip_state, 0, sizeof(struct zip_state));
172*f05845fcSMahipal Challa 	zip_ops = &zip_ctx->zip_decomp;
173*f05845fcSMahipal Challa 	memcpy(zip_ops->input, src, slen);
174*f05845fcSMahipal Challa 
175*f05845fcSMahipal Challa 	/* Work around for a bug in zlib which needs an extra bytes sometimes */
176*f05845fcSMahipal Challa 	if (zip_ops->ccode != 3) /* Not LZS Encoding */
177*f05845fcSMahipal Challa 		zip_ops->input[slen++] = 0;
178*f05845fcSMahipal Challa 
179*f05845fcSMahipal Challa 	zip_ops->input_len  = slen;
180*f05845fcSMahipal Challa 	zip_ops->output_len = *dlen;
181*f05845fcSMahipal Challa 
182*f05845fcSMahipal Challa 	ret = zip_inflate(zip_ops, &zip_state, zip);
183*f05845fcSMahipal Challa 
184*f05845fcSMahipal Challa 	if (!ret) {
185*f05845fcSMahipal Challa 		*dlen = zip_ops->output_len;
186*f05845fcSMahipal Challa 		memcpy(dst, zip_ops->output, *dlen);
187*f05845fcSMahipal Challa 	}
188*f05845fcSMahipal Challa 
189*f05845fcSMahipal Challa 	return ret;
190*f05845fcSMahipal Challa }
191*f05845fcSMahipal Challa 
192*f05845fcSMahipal Challa /* Legacy Compress framework start */
193*f05845fcSMahipal Challa int zip_alloc_comp_ctx_deflate(struct crypto_tfm *tfm)
194*f05845fcSMahipal Challa {
195*f05845fcSMahipal Challa 	int ret;
196*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
197*f05845fcSMahipal Challa 
198*f05845fcSMahipal Challa 	ret = zip_ctx_init(zip_ctx, 0);
199*f05845fcSMahipal Challa 
200*f05845fcSMahipal Challa 	return ret;
201*f05845fcSMahipal Challa }
202*f05845fcSMahipal Challa 
203*f05845fcSMahipal Challa int zip_alloc_comp_ctx_lzs(struct crypto_tfm *tfm)
204*f05845fcSMahipal Challa {
205*f05845fcSMahipal Challa 	int ret;
206*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
207*f05845fcSMahipal Challa 
208*f05845fcSMahipal Challa 	ret = zip_ctx_init(zip_ctx, 1);
209*f05845fcSMahipal Challa 
210*f05845fcSMahipal Challa 	return ret;
211*f05845fcSMahipal Challa }
212*f05845fcSMahipal Challa 
213*f05845fcSMahipal Challa void zip_free_comp_ctx(struct crypto_tfm *tfm)
214*f05845fcSMahipal Challa {
215*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
216*f05845fcSMahipal Challa 
217*f05845fcSMahipal Challa 	zip_ctx_exit(zip_ctx);
218*f05845fcSMahipal Challa }
219*f05845fcSMahipal Challa 
220*f05845fcSMahipal Challa int  zip_comp_compress(struct crypto_tfm *tfm,
221*f05845fcSMahipal Challa 		       const u8 *src, unsigned int slen,
222*f05845fcSMahipal Challa 		       u8 *dst, unsigned int *dlen)
223*f05845fcSMahipal Challa {
224*f05845fcSMahipal Challa 	int ret;
225*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
226*f05845fcSMahipal Challa 
227*f05845fcSMahipal Challa 	ret = zip_compress(src, slen, dst, dlen, zip_ctx);
228*f05845fcSMahipal Challa 
229*f05845fcSMahipal Challa 	return ret;
230*f05845fcSMahipal Challa }
231*f05845fcSMahipal Challa 
232*f05845fcSMahipal Challa int  zip_comp_decompress(struct crypto_tfm *tfm,
233*f05845fcSMahipal Challa 			 const u8 *src, unsigned int slen,
234*f05845fcSMahipal Challa 			 u8 *dst, unsigned int *dlen)
235*f05845fcSMahipal Challa {
236*f05845fcSMahipal Challa 	int ret;
237*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
238*f05845fcSMahipal Challa 
239*f05845fcSMahipal Challa 	ret = zip_decompress(src, slen, dst, dlen, zip_ctx);
240*f05845fcSMahipal Challa 
241*f05845fcSMahipal Challa 	return ret;
242*f05845fcSMahipal Challa } /* Legacy compress framework end */
243*f05845fcSMahipal Challa 
244*f05845fcSMahipal Challa /* SCOMP framework start */
245*f05845fcSMahipal Challa void *zip_alloc_scomp_ctx_deflate(struct crypto_scomp *tfm)
246*f05845fcSMahipal Challa {
247*f05845fcSMahipal Challa 	int ret;
248*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx;
249*f05845fcSMahipal Challa 
250*f05845fcSMahipal Challa 	zip_ctx = kzalloc(sizeof(*zip_ctx), GFP_KERNEL);
251*f05845fcSMahipal Challa 	if (!zip_ctx)
252*f05845fcSMahipal Challa 		return ERR_PTR(-ENOMEM);
253*f05845fcSMahipal Challa 
254*f05845fcSMahipal Challa 	ret = zip_ctx_init(zip_ctx, 0);
255*f05845fcSMahipal Challa 
256*f05845fcSMahipal Challa 	if (ret) {
257*f05845fcSMahipal Challa 		kzfree(zip_ctx);
258*f05845fcSMahipal Challa 		return ERR_PTR(ret);
259*f05845fcSMahipal Challa 	}
260*f05845fcSMahipal Challa 
261*f05845fcSMahipal Challa 	return zip_ctx;
262*f05845fcSMahipal Challa }
263*f05845fcSMahipal Challa 
264*f05845fcSMahipal Challa void *zip_alloc_scomp_ctx_lzs(struct crypto_scomp *tfm)
265*f05845fcSMahipal Challa {
266*f05845fcSMahipal Challa 	int ret;
267*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx;
268*f05845fcSMahipal Challa 
269*f05845fcSMahipal Challa 	zip_ctx = kzalloc(sizeof(*zip_ctx), GFP_KERNEL);
270*f05845fcSMahipal Challa 	if (!zip_ctx)
271*f05845fcSMahipal Challa 		return ERR_PTR(-ENOMEM);
272*f05845fcSMahipal Challa 
273*f05845fcSMahipal Challa 	ret = zip_ctx_init(zip_ctx, 1);
274*f05845fcSMahipal Challa 
275*f05845fcSMahipal Challa 	if (ret) {
276*f05845fcSMahipal Challa 		kzfree(zip_ctx);
277*f05845fcSMahipal Challa 		return ERR_PTR(ret);
278*f05845fcSMahipal Challa 	}
279*f05845fcSMahipal Challa 
280*f05845fcSMahipal Challa 	return zip_ctx;
281*f05845fcSMahipal Challa }
282*f05845fcSMahipal Challa 
283*f05845fcSMahipal Challa void zip_free_scomp_ctx(struct crypto_scomp *tfm, void *ctx)
284*f05845fcSMahipal Challa {
285*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx = ctx;
286*f05845fcSMahipal Challa 
287*f05845fcSMahipal Challa 	zip_ctx_exit(zip_ctx);
288*f05845fcSMahipal Challa 	kzfree(zip_ctx);
289*f05845fcSMahipal Challa }
290*f05845fcSMahipal Challa 
291*f05845fcSMahipal Challa int zip_scomp_compress(struct crypto_scomp *tfm,
292*f05845fcSMahipal Challa 		       const u8 *src, unsigned int slen,
293*f05845fcSMahipal Challa 		       u8 *dst, unsigned int *dlen, void *ctx)
294*f05845fcSMahipal Challa {
295*f05845fcSMahipal Challa 	int ret;
296*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx  = ctx;
297*f05845fcSMahipal Challa 
298*f05845fcSMahipal Challa 	ret = zip_compress(src, slen, dst, dlen, zip_ctx);
299*f05845fcSMahipal Challa 
300*f05845fcSMahipal Challa 	return ret;
301*f05845fcSMahipal Challa }
302*f05845fcSMahipal Challa 
303*f05845fcSMahipal Challa int zip_scomp_decompress(struct crypto_scomp *tfm,
304*f05845fcSMahipal Challa 			 const u8 *src, unsigned int slen,
305*f05845fcSMahipal Challa 			 u8 *dst, unsigned int *dlen, void *ctx)
306*f05845fcSMahipal Challa {
307*f05845fcSMahipal Challa 	int ret;
308*f05845fcSMahipal Challa 	struct zip_kernel_ctx *zip_ctx = ctx;
309*f05845fcSMahipal Challa 
310*f05845fcSMahipal Challa 	ret = zip_decompress(src, slen, dst, dlen, zip_ctx);
311*f05845fcSMahipal Challa 
312*f05845fcSMahipal Challa 	return ret;
313*f05845fcSMahipal Challa } /* SCOMP framework end */
314