Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later 2 : : /* 3 : : * Asynchronous Compression operations 4 : : * 5 : : * Copyright (c) 2016, Intel Corporation 6 : : * Authors: Weigang Li <weigang.li@intel.com> 7 : : * Giovanni Cabiddu <giovanni.cabiddu@intel.com> 8 : : */ 9 : : #include <linux/errno.h> 10 : : #include <linux/kernel.h> 11 : : #include <linux/module.h> 12 : : #include <linux/seq_file.h> 13 : : #include <linux/slab.h> 14 : : #include <linux/string.h> 15 : : #include <linux/crypto.h> 16 : : #include <crypto/algapi.h> 17 : : #include <linux/cryptouser.h> 18 : : #include <linux/compiler.h> 19 : : #include <net/netlink.h> 20 : : #include <crypto/internal/acompress.h> 21 : : #include <crypto/internal/scompress.h> 22 : : #include "internal.h" 23 : : 24 : : static const struct crypto_type crypto_acomp_type; 25 : : 26 : : #ifdef CONFIG_NET 27 : 0 : static int crypto_acomp_report(struct sk_buff *skb, struct crypto_alg *alg) 28 : : { 29 : : struct crypto_report_acomp racomp; 30 : : 31 : 0 : memset(&racomp, 0, sizeof(racomp)); 32 : : 33 : 0 : strscpy(racomp.type, "acomp", sizeof(racomp.type)); 34 : : 35 : 0 : return nla_put(skb, CRYPTOCFGA_REPORT_ACOMP, sizeof(racomp), &racomp); 36 : : } 37 : : #else 38 : : static int crypto_acomp_report(struct sk_buff *skb, struct crypto_alg *alg) 39 : : { 40 : : return -ENOSYS; 41 : : } 42 : : #endif 43 : : 44 : : static void crypto_acomp_show(struct seq_file *m, struct crypto_alg *alg) 45 : : __maybe_unused; 46 : : 47 : 0 : static void crypto_acomp_show(struct seq_file *m, struct crypto_alg *alg) 48 : : { 49 : 0 : seq_puts(m, "type : acomp\n"); 50 : 0 : } 51 : : 52 : 0 : static void crypto_acomp_exit_tfm(struct crypto_tfm *tfm) 53 : : { 54 : : struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm); 55 : : struct acomp_alg *alg = crypto_acomp_alg(acomp); 56 : : 57 : 0 : alg->exit(acomp); 58 : 0 : } 59 : : 60 : 0 : static int crypto_acomp_init_tfm(struct crypto_tfm *tfm) 61 : : { 62 : : struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm); 63 : : struct acomp_alg *alg = crypto_acomp_alg(acomp); 64 : : 65 : 0 : if (tfm->__crt_alg->cra_type != &crypto_acomp_type) 66 : 0 : return crypto_init_scomp_ops_async(tfm); 67 : : 68 : 0 : acomp->compress = alg->compress; 69 : 0 : acomp->decompress = alg->decompress; 70 : 0 : acomp->dst_free = alg->dst_free; 71 : 0 : acomp->reqsize = alg->reqsize; 72 : : 73 : 0 : if (alg->exit) 74 : 0 : acomp->base.exit = crypto_acomp_exit_tfm; 75 : : 76 : 0 : if (alg->init) 77 : 0 : return alg->init(acomp); 78 : : 79 : : return 0; 80 : : } 81 : : 82 : 0 : static unsigned int crypto_acomp_extsize(struct crypto_alg *alg) 83 : : { 84 : 0 : int extsize = crypto_alg_extsize(alg); 85 : : 86 : 0 : if (alg->cra_type != &crypto_acomp_type) 87 : 0 : extsize += sizeof(struct crypto_scomp *); 88 : : 89 : 0 : return extsize; 90 : : } 91 : : 92 : : static const struct crypto_type crypto_acomp_type = { 93 : : .extsize = crypto_acomp_extsize, 94 : : .init_tfm = crypto_acomp_init_tfm, 95 : : #ifdef CONFIG_PROC_FS 96 : : .show = crypto_acomp_show, 97 : : #endif 98 : : .report = crypto_acomp_report, 99 : : .maskclear = ~CRYPTO_ALG_TYPE_MASK, 100 : : .maskset = CRYPTO_ALG_TYPE_ACOMPRESS_MASK, 101 : : .type = CRYPTO_ALG_TYPE_ACOMPRESS, 102 : : .tfmsize = offsetof(struct crypto_acomp, base), 103 : : }; 104 : : 105 : 0 : struct crypto_acomp *crypto_alloc_acomp(const char *alg_name, u32 type, 106 : : u32 mask) 107 : : { 108 : 0 : return crypto_alloc_tfm(alg_name, &crypto_acomp_type, type, mask); 109 : : } 110 : : EXPORT_SYMBOL_GPL(crypto_alloc_acomp); 111 : : 112 : 0 : struct acomp_req *acomp_request_alloc(struct crypto_acomp *acomp) 113 : : { 114 : : struct crypto_tfm *tfm = crypto_acomp_tfm(acomp); 115 : : struct acomp_req *req; 116 : : 117 : 0 : req = __acomp_request_alloc(acomp); 118 : 0 : if (req && (tfm->__crt_alg->cra_type != &crypto_acomp_type)) 119 : 0 : return crypto_acomp_scomp_alloc_ctx(req); 120 : : 121 : : return req; 122 : : } 123 : : EXPORT_SYMBOL_GPL(acomp_request_alloc); 124 : : 125 : 0 : void acomp_request_free(struct acomp_req *req) 126 : : { 127 : : struct crypto_acomp *acomp = crypto_acomp_reqtfm(req); 128 : : struct crypto_tfm *tfm = crypto_acomp_tfm(acomp); 129 : : 130 : 0 : if (tfm->__crt_alg->cra_type != &crypto_acomp_type) 131 : 0 : crypto_acomp_scomp_free_ctx(req); 132 : : 133 : 0 : if (req->flags & CRYPTO_ACOMP_ALLOC_OUTPUT) { 134 : 0 : acomp->dst_free(req->dst); 135 : 0 : req->dst = NULL; 136 : : } 137 : : 138 : : __acomp_request_free(req); 139 : 0 : } 140 : : EXPORT_SYMBOL_GPL(acomp_request_free); 141 : : 142 : 0 : int crypto_register_acomp(struct acomp_alg *alg) 143 : : { 144 : 0 : struct crypto_alg *base = &alg->base; 145 : : 146 : 0 : base->cra_type = &crypto_acomp_type; 147 : 0 : base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; 148 : 0 : base->cra_flags |= CRYPTO_ALG_TYPE_ACOMPRESS; 149 : : 150 : 0 : return crypto_register_alg(base); 151 : : } 152 : : EXPORT_SYMBOL_GPL(crypto_register_acomp); 153 : : 154 : 0 : int crypto_unregister_acomp(struct acomp_alg *alg) 155 : : { 156 : 0 : return crypto_unregister_alg(&alg->base); 157 : : } 158 : : EXPORT_SYMBOL_GPL(crypto_unregister_acomp); 159 : : 160 : 0 : int crypto_register_acomps(struct acomp_alg *algs, int count) 161 : : { 162 : : int i, ret; 163 : : 164 : 0 : for (i = 0; i < count; i++) { 165 : 0 : ret = crypto_register_acomp(&algs[i]); 166 : 0 : if (ret) 167 : : goto err; 168 : : } 169 : : 170 : : return 0; 171 : : 172 : : err: 173 : 0 : for (--i; i >= 0; --i) 174 : 0 : crypto_unregister_acomp(&algs[i]); 175 : : 176 : 0 : return ret; 177 : : } 178 : : EXPORT_SYMBOL_GPL(crypto_register_acomps); 179 : : 180 : 0 : void crypto_unregister_acomps(struct acomp_alg *algs, int count) 181 : : { 182 : : int i; 183 : : 184 : 0 : for (i = count - 1; i >= 0; --i) 185 : 0 : crypto_unregister_acomp(&algs[i]); 186 : 0 : } 187 : : EXPORT_SYMBOL_GPL(crypto_unregister_acomps); 188 : : 189 : : MODULE_LICENSE("GPL"); 190 : : MODULE_DESCRIPTION("Asynchronous compression type");