Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Cryptographic API.
0004  *
0005  * Copyright (c) 2013 Chanho Min <chanho.min@lge.com>
0006  */
0007 
0008 #include <linux/init.h>
0009 #include <linux/module.h>
0010 #include <linux/crypto.h>
0011 #include <linux/vmalloc.h>
0012 #include <linux/lz4.h>
0013 #include <crypto/internal/scompress.h>
0014 
0015 struct lz4_ctx {
0016     void *lz4_comp_mem;
0017 };
0018 
0019 static void *lz4_alloc_ctx(struct crypto_scomp *tfm)
0020 {
0021     void *ctx;
0022 
0023     ctx = vmalloc(LZ4_MEM_COMPRESS);
0024     if (!ctx)
0025         return ERR_PTR(-ENOMEM);
0026 
0027     return ctx;
0028 }
0029 
0030 static int lz4_init(struct crypto_tfm *tfm)
0031 {
0032     struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
0033 
0034     ctx->lz4_comp_mem = lz4_alloc_ctx(NULL);
0035     if (IS_ERR(ctx->lz4_comp_mem))
0036         return -ENOMEM;
0037 
0038     return 0;
0039 }
0040 
0041 static void lz4_free_ctx(struct crypto_scomp *tfm, void *ctx)
0042 {
0043     vfree(ctx);
0044 }
0045 
0046 static void lz4_exit(struct crypto_tfm *tfm)
0047 {
0048     struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
0049 
0050     lz4_free_ctx(NULL, ctx->lz4_comp_mem);
0051 }
0052 
0053 static int __lz4_compress_crypto(const u8 *src, unsigned int slen,
0054                  u8 *dst, unsigned int *dlen, void *ctx)
0055 {
0056     int out_len = LZ4_compress_default(src, dst,
0057         slen, *dlen, ctx);
0058 
0059     if (!out_len)
0060         return -EINVAL;
0061 
0062     *dlen = out_len;
0063     return 0;
0064 }
0065 
0066 static int lz4_scompress(struct crypto_scomp *tfm, const u8 *src,
0067              unsigned int slen, u8 *dst, unsigned int *dlen,
0068              void *ctx)
0069 {
0070     return __lz4_compress_crypto(src, slen, dst, dlen, ctx);
0071 }
0072 
0073 static int lz4_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
0074                    unsigned int slen, u8 *dst, unsigned int *dlen)
0075 {
0076     struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
0077 
0078     return __lz4_compress_crypto(src, slen, dst, dlen, ctx->lz4_comp_mem);
0079 }
0080 
0081 static int __lz4_decompress_crypto(const u8 *src, unsigned int slen,
0082                    u8 *dst, unsigned int *dlen, void *ctx)
0083 {
0084     int out_len = LZ4_decompress_safe(src, dst, slen, *dlen);
0085 
0086     if (out_len < 0)
0087         return -EINVAL;
0088 
0089     *dlen = out_len;
0090     return 0;
0091 }
0092 
0093 static int lz4_sdecompress(struct crypto_scomp *tfm, const u8 *src,
0094                unsigned int slen, u8 *dst, unsigned int *dlen,
0095                void *ctx)
0096 {
0097     return __lz4_decompress_crypto(src, slen, dst, dlen, NULL);
0098 }
0099 
0100 static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
0101                  unsigned int slen, u8 *dst,
0102                  unsigned int *dlen)
0103 {
0104     return __lz4_decompress_crypto(src, slen, dst, dlen, NULL);
0105 }
0106 
0107 static struct crypto_alg alg_lz4 = {
0108     .cra_name       = "lz4",
0109     .cra_driver_name    = "lz4-generic",
0110     .cra_flags      = CRYPTO_ALG_TYPE_COMPRESS,
0111     .cra_ctxsize        = sizeof(struct lz4_ctx),
0112     .cra_module     = THIS_MODULE,
0113     .cra_init       = lz4_init,
0114     .cra_exit       = lz4_exit,
0115     .cra_u          = { .compress = {
0116     .coa_compress       = lz4_compress_crypto,
0117     .coa_decompress     = lz4_decompress_crypto } }
0118 };
0119 
0120 static struct scomp_alg scomp = {
0121     .alloc_ctx      = lz4_alloc_ctx,
0122     .free_ctx       = lz4_free_ctx,
0123     .compress       = lz4_scompress,
0124     .decompress     = lz4_sdecompress,
0125     .base           = {
0126         .cra_name   = "lz4",
0127         .cra_driver_name = "lz4-scomp",
0128         .cra_module  = THIS_MODULE,
0129     }
0130 };
0131 
0132 static int __init lz4_mod_init(void)
0133 {
0134     int ret;
0135 
0136     ret = crypto_register_alg(&alg_lz4);
0137     if (ret)
0138         return ret;
0139 
0140     ret = crypto_register_scomp(&scomp);
0141     if (ret) {
0142         crypto_unregister_alg(&alg_lz4);
0143         return ret;
0144     }
0145 
0146     return ret;
0147 }
0148 
0149 static void __exit lz4_mod_fini(void)
0150 {
0151     crypto_unregister_alg(&alg_lz4);
0152     crypto_unregister_scomp(&scomp);
0153 }
0154 
0155 subsys_initcall(lz4_mod_init);
0156 module_exit(lz4_mod_fini);
0157 
0158 MODULE_LICENSE("GPL");
0159 MODULE_DESCRIPTION("LZ4 Compression Algorithm");
0160 MODULE_ALIAS_CRYPTO("lz4");