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