123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- /***********************license start************************************
- * Copyright (c) 2003-2017 Cavium, Inc.
- * All rights reserved.
- *
- * License: one of 'Cavium License' or 'GNU General Public License Version 2'
- *
- * This file is provided under the terms of the Cavium License (see below)
- * or under the terms of GNU General Public License, Version 2, as
- * published by the Free Software Foundation. When using or redistributing
- * this file, you may do so under either license.
- *
- * Cavium License: Redistribution and use in source and binary forms, with
- * or without modification, are permitted provided that the following
- * conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * * Neither the name of Cavium Inc. nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * This Software, including technical data, may be subject to U.S. export
- * control laws, including the U.S. Export Administration Act and its
- * associated regulations, and may be subject to export or import
- * regulations in other countries.
- *
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS
- * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
- * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
- * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
- * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY)
- * WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A
- * PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET
- * ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE
- * ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES
- * WITH YOU.
- ***********************license end**************************************/
- #include "zip_crypto.h"
- static void zip_static_init_zip_ops(struct zip_operation *zip_ops,
- int lzs_flag)
- {
- zip_ops->flush = ZIP_FLUSH_FINISH;
- /* equivalent to level 6 of opensource zlib */
- zip_ops->speed = 1;
- if (!lzs_flag) {
- zip_ops->ccode = 0; /* Auto Huffman */
- zip_ops->lzs_flag = 0;
- zip_ops->format = ZLIB_FORMAT;
- } else {
- zip_ops->ccode = 3; /* LZS Encoding */
- zip_ops->lzs_flag = 1;
- zip_ops->format = LZS_FORMAT;
- }
- zip_ops->begin_file = 1;
- zip_ops->history_len = 0;
- zip_ops->end_file = 1;
- zip_ops->compcode = 0;
- zip_ops->csum = 1; /* Adler checksum desired */
- }
- static int zip_ctx_init(struct zip_kernel_ctx *zip_ctx, int lzs_flag)
- {
- struct zip_operation *comp_ctx = &zip_ctx->zip_comp;
- struct zip_operation *decomp_ctx = &zip_ctx->zip_decomp;
- zip_static_init_zip_ops(comp_ctx, lzs_flag);
- zip_static_init_zip_ops(decomp_ctx, lzs_flag);
- comp_ctx->input = zip_data_buf_alloc(MAX_INPUT_BUFFER_SIZE);
- if (!comp_ctx->input)
- return -ENOMEM;
- comp_ctx->output = zip_data_buf_alloc(MAX_OUTPUT_BUFFER_SIZE);
- if (!comp_ctx->output)
- goto err_comp_input;
- decomp_ctx->input = zip_data_buf_alloc(MAX_INPUT_BUFFER_SIZE);
- if (!decomp_ctx->input)
- goto err_comp_output;
- decomp_ctx->output = zip_data_buf_alloc(MAX_OUTPUT_BUFFER_SIZE);
- if (!decomp_ctx->output)
- goto err_decomp_input;
- return 0;
- err_decomp_input:
- zip_data_buf_free(decomp_ctx->input, MAX_INPUT_BUFFER_SIZE);
- err_comp_output:
- zip_data_buf_free(comp_ctx->output, MAX_OUTPUT_BUFFER_SIZE);
- err_comp_input:
- zip_data_buf_free(comp_ctx->input, MAX_INPUT_BUFFER_SIZE);
- return -ENOMEM;
- }
- static void zip_ctx_exit(struct zip_kernel_ctx *zip_ctx)
- {
- struct zip_operation *comp_ctx = &zip_ctx->zip_comp;
- struct zip_operation *dec_ctx = &zip_ctx->zip_decomp;
- zip_data_buf_free(comp_ctx->input, MAX_INPUT_BUFFER_SIZE);
- zip_data_buf_free(comp_ctx->output, MAX_OUTPUT_BUFFER_SIZE);
- zip_data_buf_free(dec_ctx->input, MAX_INPUT_BUFFER_SIZE);
- zip_data_buf_free(dec_ctx->output, MAX_OUTPUT_BUFFER_SIZE);
- }
- static int zip_compress(const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen,
- struct zip_kernel_ctx *zip_ctx)
- {
- struct zip_operation *zip_ops = NULL;
- struct zip_state *zip_state;
- struct zip_device *zip = NULL;
- int ret;
- if (!zip_ctx || !src || !dst || !dlen)
- return -ENOMEM;
- zip = zip_get_device(zip_get_node_id());
- if (!zip)
- return -ENODEV;
- zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC);
- if (!zip_state)
- return -ENOMEM;
- zip_ops = &zip_ctx->zip_comp;
- zip_ops->input_len = slen;
- zip_ops->output_len = *dlen;
- memcpy(zip_ops->input, src, slen);
- ret = zip_deflate(zip_ops, zip_state, zip);
- if (!ret) {
- *dlen = zip_ops->output_len;
- memcpy(dst, zip_ops->output, *dlen);
- }
- kfree(zip_state);
- return ret;
- }
- static int zip_decompress(const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen,
- struct zip_kernel_ctx *zip_ctx)
- {
- struct zip_operation *zip_ops = NULL;
- struct zip_state *zip_state;
- struct zip_device *zip = NULL;
- int ret;
- if (!zip_ctx || !src || !dst || !dlen)
- return -ENOMEM;
- zip = zip_get_device(zip_get_node_id());
- if (!zip)
- return -ENODEV;
- zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC);
- if (!zip_state)
- return -ENOMEM;
- zip_ops = &zip_ctx->zip_decomp;
- memcpy(zip_ops->input, src, slen);
- /* Work around for a bug in zlib which needs an extra bytes sometimes */
- if (zip_ops->ccode != 3) /* Not LZS Encoding */
- zip_ops->input[slen++] = 0;
- zip_ops->input_len = slen;
- zip_ops->output_len = *dlen;
- ret = zip_inflate(zip_ops, zip_state, zip);
- if (!ret) {
- *dlen = zip_ops->output_len;
- memcpy(dst, zip_ops->output, *dlen);
- }
- kfree(zip_state);
- return ret;
- }
- /* Legacy Compress framework start */
- int zip_alloc_comp_ctx_deflate(struct crypto_tfm *tfm)
- {
- struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
- return zip_ctx_init(zip_ctx, 0);
- }
- int zip_alloc_comp_ctx_lzs(struct crypto_tfm *tfm)
- {
- struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
- return zip_ctx_init(zip_ctx, 1);
- }
- void zip_free_comp_ctx(struct crypto_tfm *tfm)
- {
- struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
- zip_ctx_exit(zip_ctx);
- }
- int zip_comp_compress(struct crypto_tfm *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen)
- {
- struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
- return zip_compress(src, slen, dst, dlen, zip_ctx);
- }
- int zip_comp_decompress(struct crypto_tfm *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen)
- {
- struct zip_kernel_ctx *zip_ctx = crypto_tfm_ctx(tfm);
- return zip_decompress(src, slen, dst, dlen, zip_ctx);
- } /* Legacy compress framework end */
- /* SCOMP framework start */
- void *zip_alloc_scomp_ctx_deflate(struct crypto_scomp *tfm)
- {
- int ret;
- struct zip_kernel_ctx *zip_ctx;
- zip_ctx = kzalloc(sizeof(*zip_ctx), GFP_KERNEL);
- if (!zip_ctx)
- return ERR_PTR(-ENOMEM);
- ret = zip_ctx_init(zip_ctx, 0);
- if (ret) {
- kfree_sensitive(zip_ctx);
- return ERR_PTR(ret);
- }
- return zip_ctx;
- }
- void *zip_alloc_scomp_ctx_lzs(struct crypto_scomp *tfm)
- {
- int ret;
- struct zip_kernel_ctx *zip_ctx;
- zip_ctx = kzalloc(sizeof(*zip_ctx), GFP_KERNEL);
- if (!zip_ctx)
- return ERR_PTR(-ENOMEM);
- ret = zip_ctx_init(zip_ctx, 1);
- if (ret) {
- kfree_sensitive(zip_ctx);
- return ERR_PTR(ret);
- }
- return zip_ctx;
- }
- void zip_free_scomp_ctx(struct crypto_scomp *tfm, void *ctx)
- {
- struct zip_kernel_ctx *zip_ctx = ctx;
- zip_ctx_exit(zip_ctx);
- kfree_sensitive(zip_ctx);
- }
- int zip_scomp_compress(struct crypto_scomp *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen, void *ctx)
- {
- struct zip_kernel_ctx *zip_ctx = ctx;
- return zip_compress(src, slen, dst, dlen, zip_ctx);
- }
- int zip_scomp_decompress(struct crypto_scomp *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen, void *ctx)
- {
- struct zip_kernel_ctx *zip_ctx = ctx;
- return zip_decompress(src, slen, dst, dlen, zip_ctx);
- } /* SCOMP framework end */
|