root/crypto/zstd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zstd_params
  2. zstd_comp_init
  3. zstd_decomp_init
  4. zstd_comp_exit
  5. zstd_decomp_exit
  6. __zstd_init
  7. zstd_alloc_ctx
  8. zstd_init
  9. __zstd_exit
  10. zstd_free_ctx
  11. zstd_exit
  12. __zstd_compress
  13. zstd_compress
  14. zstd_scompress
  15. __zstd_decompress
  16. zstd_decompress
  17. zstd_sdecompress
  18. zstd_mod_init
  19. zstd_mod_fini

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Cryptographic API.
   4  *
   5  * Copyright (c) 2017-present, Facebook, Inc.
   6  */
   7 #include <linux/crypto.h>
   8 #include <linux/init.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/mm.h>
  11 #include <linux/module.h>
  12 #include <linux/net.h>
  13 #include <linux/vmalloc.h>
  14 #include <linux/zstd.h>
  15 #include <crypto/internal/scompress.h>
  16 
  17 
  18 #define ZSTD_DEF_LEVEL  3
  19 
  20 struct zstd_ctx {
  21         ZSTD_CCtx *cctx;
  22         ZSTD_DCtx *dctx;
  23         void *cwksp;
  24         void *dwksp;
  25 };
  26 
  27 static ZSTD_parameters zstd_params(void)
  28 {
  29         return ZSTD_getParams(ZSTD_DEF_LEVEL, 0, 0);
  30 }
  31 
  32 static int zstd_comp_init(struct zstd_ctx *ctx)
  33 {
  34         int ret = 0;
  35         const ZSTD_parameters params = zstd_params();
  36         const size_t wksp_size = ZSTD_CCtxWorkspaceBound(params.cParams);
  37 
  38         ctx->cwksp = vzalloc(wksp_size);
  39         if (!ctx->cwksp) {
  40                 ret = -ENOMEM;
  41                 goto out;
  42         }
  43 
  44         ctx->cctx = ZSTD_initCCtx(ctx->cwksp, wksp_size);
  45         if (!ctx->cctx) {
  46                 ret = -EINVAL;
  47                 goto out_free;
  48         }
  49 out:
  50         return ret;
  51 out_free:
  52         vfree(ctx->cwksp);
  53         goto out;
  54 }
  55 
  56 static int zstd_decomp_init(struct zstd_ctx *ctx)
  57 {
  58         int ret = 0;
  59         const size_t wksp_size = ZSTD_DCtxWorkspaceBound();
  60 
  61         ctx->dwksp = vzalloc(wksp_size);
  62         if (!ctx->dwksp) {
  63                 ret = -ENOMEM;
  64                 goto out;
  65         }
  66 
  67         ctx->dctx = ZSTD_initDCtx(ctx->dwksp, wksp_size);
  68         if (!ctx->dctx) {
  69                 ret = -EINVAL;
  70                 goto out_free;
  71         }
  72 out:
  73         return ret;
  74 out_free:
  75         vfree(ctx->dwksp);
  76         goto out;
  77 }
  78 
  79 static void zstd_comp_exit(struct zstd_ctx *ctx)
  80 {
  81         vfree(ctx->cwksp);
  82         ctx->cwksp = NULL;
  83         ctx->cctx = NULL;
  84 }
  85 
  86 static void zstd_decomp_exit(struct zstd_ctx *ctx)
  87 {
  88         vfree(ctx->dwksp);
  89         ctx->dwksp = NULL;
  90         ctx->dctx = NULL;
  91 }
  92 
  93 static int __zstd_init(void *ctx)
  94 {
  95         int ret;
  96 
  97         ret = zstd_comp_init(ctx);
  98         if (ret)
  99                 return ret;
 100         ret = zstd_decomp_init(ctx);
 101         if (ret)
 102                 zstd_comp_exit(ctx);
 103         return ret;
 104 }
 105 
 106 static void *zstd_alloc_ctx(struct crypto_scomp *tfm)
 107 {
 108         int ret;
 109         struct zstd_ctx *ctx;
 110 
 111         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 112         if (!ctx)
 113                 return ERR_PTR(-ENOMEM);
 114 
 115         ret = __zstd_init(ctx);
 116         if (ret) {
 117                 kfree(ctx);
 118                 return ERR_PTR(ret);
 119         }
 120 
 121         return ctx;
 122 }
 123 
 124 static int zstd_init(struct crypto_tfm *tfm)
 125 {
 126         struct zstd_ctx *ctx = crypto_tfm_ctx(tfm);
 127 
 128         return __zstd_init(ctx);
 129 }
 130 
 131 static void __zstd_exit(void *ctx)
 132 {
 133         zstd_comp_exit(ctx);
 134         zstd_decomp_exit(ctx);
 135 }
 136 
 137 static void zstd_free_ctx(struct crypto_scomp *tfm, void *ctx)
 138 {
 139         __zstd_exit(ctx);
 140         kzfree(ctx);
 141 }
 142 
 143 static void zstd_exit(struct crypto_tfm *tfm)
 144 {
 145         struct zstd_ctx *ctx = crypto_tfm_ctx(tfm);
 146 
 147         __zstd_exit(ctx);
 148 }
 149 
 150 static int __zstd_compress(const u8 *src, unsigned int slen,
 151                            u8 *dst, unsigned int *dlen, void *ctx)
 152 {
 153         size_t out_len;
 154         struct zstd_ctx *zctx = ctx;
 155         const ZSTD_parameters params = zstd_params();
 156 
 157         out_len = ZSTD_compressCCtx(zctx->cctx, dst, *dlen, src, slen, params);
 158         if (ZSTD_isError(out_len))
 159                 return -EINVAL;
 160         *dlen = out_len;
 161         return 0;
 162 }
 163 
 164 static int zstd_compress(struct crypto_tfm *tfm, const u8 *src,
 165                          unsigned int slen, u8 *dst, unsigned int *dlen)
 166 {
 167         struct zstd_ctx *ctx = crypto_tfm_ctx(tfm);
 168 
 169         return __zstd_compress(src, slen, dst, dlen, ctx);
 170 }
 171 
 172 static int zstd_scompress(struct crypto_scomp *tfm, const u8 *src,
 173                           unsigned int slen, u8 *dst, unsigned int *dlen,
 174                           void *ctx)
 175 {
 176         return __zstd_compress(src, slen, dst, dlen, ctx);
 177 }
 178 
 179 static int __zstd_decompress(const u8 *src, unsigned int slen,
 180                              u8 *dst, unsigned int *dlen, void *ctx)
 181 {
 182         size_t out_len;
 183         struct zstd_ctx *zctx = ctx;
 184 
 185         out_len = ZSTD_decompressDCtx(zctx->dctx, dst, *dlen, src, slen);
 186         if (ZSTD_isError(out_len))
 187                 return -EINVAL;
 188         *dlen = out_len;
 189         return 0;
 190 }
 191 
 192 static int zstd_decompress(struct crypto_tfm *tfm, const u8 *src,
 193                            unsigned int slen, u8 *dst, unsigned int *dlen)
 194 {
 195         struct zstd_ctx *ctx = crypto_tfm_ctx(tfm);
 196 
 197         return __zstd_decompress(src, slen, dst, dlen, ctx);
 198 }
 199 
 200 static int zstd_sdecompress(struct crypto_scomp *tfm, const u8 *src,
 201                             unsigned int slen, u8 *dst, unsigned int *dlen,
 202                             void *ctx)
 203 {
 204         return __zstd_decompress(src, slen, dst, dlen, ctx);
 205 }
 206 
 207 static struct crypto_alg alg = {
 208         .cra_name               = "zstd",
 209         .cra_driver_name        = "zstd-generic",
 210         .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
 211         .cra_ctxsize            = sizeof(struct zstd_ctx),
 212         .cra_module             = THIS_MODULE,
 213         .cra_init               = zstd_init,
 214         .cra_exit               = zstd_exit,
 215         .cra_u                  = { .compress = {
 216         .coa_compress           = zstd_compress,
 217         .coa_decompress         = zstd_decompress } }
 218 };
 219 
 220 static struct scomp_alg scomp = {
 221         .alloc_ctx              = zstd_alloc_ctx,
 222         .free_ctx               = zstd_free_ctx,
 223         .compress               = zstd_scompress,
 224         .decompress             = zstd_sdecompress,
 225         .base                   = {
 226                 .cra_name       = "zstd",
 227                 .cra_driver_name = "zstd-scomp",
 228                 .cra_module      = THIS_MODULE,
 229         }
 230 };
 231 
 232 static int __init zstd_mod_init(void)
 233 {
 234         int ret;
 235 
 236         ret = crypto_register_alg(&alg);
 237         if (ret)
 238                 return ret;
 239 
 240         ret = crypto_register_scomp(&scomp);
 241         if (ret)
 242                 crypto_unregister_alg(&alg);
 243 
 244         return ret;
 245 }
 246 
 247 static void __exit zstd_mod_fini(void)
 248 {
 249         crypto_unregister_alg(&alg);
 250         crypto_unregister_scomp(&scomp);
 251 }
 252 
 253 subsys_initcall(zstd_mod_init);
 254 module_exit(zstd_mod_fini);
 255 
 256 MODULE_LICENSE("GPL");
 257 MODULE_DESCRIPTION("Zstd Compression Algorithm");
 258 MODULE_ALIAS_CRYPTO("zstd");

/* [<][>][^][v][top][bottom][index][help] */