11ab53a77SGiovanni Cabiddu /* 21ab53a77SGiovanni Cabiddu * Synchronous Compression operations 31ab53a77SGiovanni Cabiddu * 41ab53a77SGiovanni Cabiddu * Copyright 2015 LG Electronics Inc. 51ab53a77SGiovanni Cabiddu * Copyright (c) 2016, Intel Corporation 61ab53a77SGiovanni Cabiddu * Author: Giovanni Cabiddu <giovanni.cabiddu@intel.com> 71ab53a77SGiovanni Cabiddu * 81ab53a77SGiovanni Cabiddu * This program is free software; you can redistribute it and/or modify it 91ab53a77SGiovanni Cabiddu * under the terms of the GNU General Public License as published by the Free 101ab53a77SGiovanni Cabiddu * Software Foundation; either version 2 of the License, or (at your option) 111ab53a77SGiovanni Cabiddu * any later version. 121ab53a77SGiovanni Cabiddu * 131ab53a77SGiovanni Cabiddu */ 141ab53a77SGiovanni Cabiddu #include <linux/errno.h> 151ab53a77SGiovanni Cabiddu #include <linux/kernel.h> 161ab53a77SGiovanni Cabiddu #include <linux/module.h> 171ab53a77SGiovanni Cabiddu #include <linux/seq_file.h> 181ab53a77SGiovanni Cabiddu #include <linux/slab.h> 191ab53a77SGiovanni Cabiddu #include <linux/string.h> 201ab53a77SGiovanni Cabiddu #include <linux/crypto.h> 21d8c34b94SGideon Israel Dsouza #include <linux/compiler.h> 221ab53a77SGiovanni Cabiddu #include <linux/vmalloc.h> 231ab53a77SGiovanni Cabiddu #include <crypto/algapi.h> 241ab53a77SGiovanni Cabiddu #include <linux/cryptouser.h> 251ab53a77SGiovanni Cabiddu #include <net/netlink.h> 261ab53a77SGiovanni Cabiddu #include <linux/scatterlist.h> 271ab53a77SGiovanni Cabiddu #include <crypto/scatterwalk.h> 281ab53a77SGiovanni Cabiddu #include <crypto/internal/acompress.h> 291ab53a77SGiovanni Cabiddu #include <crypto/internal/scompress.h> 301ab53a77SGiovanni Cabiddu #include "internal.h" 311ab53a77SGiovanni Cabiddu 321ab53a77SGiovanni Cabiddu static const struct crypto_type crypto_scomp_type; 331ab53a77SGiovanni Cabiddu static void * __percpu *scomp_src_scratches; 341ab53a77SGiovanni Cabiddu static void * __percpu *scomp_dst_scratches; 351ab53a77SGiovanni Cabiddu static int scomp_scratch_users; 361ab53a77SGiovanni Cabiddu static DEFINE_MUTEX(scomp_lock); 371ab53a77SGiovanni Cabiddu 381ab53a77SGiovanni Cabiddu #ifdef CONFIG_NET 391ab53a77SGiovanni Cabiddu static int crypto_scomp_report(struct sk_buff *skb, struct crypto_alg *alg) 401ab53a77SGiovanni Cabiddu { 411ab53a77SGiovanni Cabiddu struct crypto_report_comp rscomp; 421ab53a77SGiovanni Cabiddu 431ab53a77SGiovanni Cabiddu strncpy(rscomp.type, "scomp", sizeof(rscomp.type)); 441ab53a77SGiovanni Cabiddu 451ab53a77SGiovanni Cabiddu if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS, 461ab53a77SGiovanni Cabiddu sizeof(struct crypto_report_comp), &rscomp)) 471ab53a77SGiovanni Cabiddu goto nla_put_failure; 481ab53a77SGiovanni Cabiddu return 0; 491ab53a77SGiovanni Cabiddu 501ab53a77SGiovanni Cabiddu nla_put_failure: 511ab53a77SGiovanni Cabiddu return -EMSGSIZE; 521ab53a77SGiovanni Cabiddu } 531ab53a77SGiovanni Cabiddu #else 541ab53a77SGiovanni Cabiddu static int crypto_scomp_report(struct sk_buff *skb, struct crypto_alg *alg) 551ab53a77SGiovanni Cabiddu { 561ab53a77SGiovanni Cabiddu return -ENOSYS; 571ab53a77SGiovanni Cabiddu } 581ab53a77SGiovanni Cabiddu #endif 591ab53a77SGiovanni Cabiddu 601ab53a77SGiovanni Cabiddu static void crypto_scomp_show(struct seq_file *m, struct crypto_alg *alg) 61d8c34b94SGideon Israel Dsouza __maybe_unused; 621ab53a77SGiovanni Cabiddu 631ab53a77SGiovanni Cabiddu static void crypto_scomp_show(struct seq_file *m, struct crypto_alg *alg) 641ab53a77SGiovanni Cabiddu { 651ab53a77SGiovanni Cabiddu seq_puts(m, "type : scomp\n"); 661ab53a77SGiovanni Cabiddu } 671ab53a77SGiovanni Cabiddu 681ab53a77SGiovanni Cabiddu static void crypto_scomp_free_scratches(void * __percpu *scratches) 691ab53a77SGiovanni Cabiddu { 701ab53a77SGiovanni Cabiddu int i; 711ab53a77SGiovanni Cabiddu 721ab53a77SGiovanni Cabiddu if (!scratches) 731ab53a77SGiovanni Cabiddu return; 741ab53a77SGiovanni Cabiddu 751ab53a77SGiovanni Cabiddu for_each_possible_cpu(i) 761ab53a77SGiovanni Cabiddu vfree(*per_cpu_ptr(scratches, i)); 771ab53a77SGiovanni Cabiddu 781ab53a77SGiovanni Cabiddu free_percpu(scratches); 791ab53a77SGiovanni Cabiddu } 801ab53a77SGiovanni Cabiddu 811ab53a77SGiovanni Cabiddu static void * __percpu *crypto_scomp_alloc_scratches(void) 821ab53a77SGiovanni Cabiddu { 831ab53a77SGiovanni Cabiddu void * __percpu *scratches; 841ab53a77SGiovanni Cabiddu int i; 851ab53a77SGiovanni Cabiddu 861ab53a77SGiovanni Cabiddu scratches = alloc_percpu(void *); 871ab53a77SGiovanni Cabiddu if (!scratches) 881ab53a77SGiovanni Cabiddu return NULL; 891ab53a77SGiovanni Cabiddu 901ab53a77SGiovanni Cabiddu for_each_possible_cpu(i) { 911ab53a77SGiovanni Cabiddu void *scratch; 921ab53a77SGiovanni Cabiddu 931ab53a77SGiovanni Cabiddu scratch = vmalloc_node(SCOMP_SCRATCH_SIZE, cpu_to_node(i)); 941ab53a77SGiovanni Cabiddu if (!scratch) 951ab53a77SGiovanni Cabiddu goto error; 961ab53a77SGiovanni Cabiddu *per_cpu_ptr(scratches, i) = scratch; 971ab53a77SGiovanni Cabiddu } 981ab53a77SGiovanni Cabiddu 991ab53a77SGiovanni Cabiddu return scratches; 1001ab53a77SGiovanni Cabiddu 1011ab53a77SGiovanni Cabiddu error: 1021ab53a77SGiovanni Cabiddu crypto_scomp_free_scratches(scratches); 1031ab53a77SGiovanni Cabiddu return NULL; 1041ab53a77SGiovanni Cabiddu } 1051ab53a77SGiovanni Cabiddu 1061ab53a77SGiovanni Cabiddu static void crypto_scomp_free_all_scratches(void) 1071ab53a77SGiovanni Cabiddu { 1081ab53a77SGiovanni Cabiddu if (!--scomp_scratch_users) { 1091ab53a77SGiovanni Cabiddu crypto_scomp_free_scratches(scomp_src_scratches); 1101ab53a77SGiovanni Cabiddu crypto_scomp_free_scratches(scomp_dst_scratches); 1111ab53a77SGiovanni Cabiddu scomp_src_scratches = NULL; 1121ab53a77SGiovanni Cabiddu scomp_dst_scratches = NULL; 1131ab53a77SGiovanni Cabiddu } 1141ab53a77SGiovanni Cabiddu } 1151ab53a77SGiovanni Cabiddu 1161ab53a77SGiovanni Cabiddu static int crypto_scomp_alloc_all_scratches(void) 1171ab53a77SGiovanni Cabiddu { 1181ab53a77SGiovanni Cabiddu if (!scomp_scratch_users++) { 1191ab53a77SGiovanni Cabiddu scomp_src_scratches = crypto_scomp_alloc_scratches(); 1201ab53a77SGiovanni Cabiddu if (!scomp_src_scratches) 1211ab53a77SGiovanni Cabiddu return -ENOMEM; 1221ab53a77SGiovanni Cabiddu scomp_dst_scratches = crypto_scomp_alloc_scratches(); 123cc4d110eSArd Biesheuvel if (!scomp_dst_scratches) { 124cc4d110eSArd Biesheuvel crypto_scomp_free_scratches(scomp_src_scratches); 125cc4d110eSArd Biesheuvel scomp_src_scratches = NULL; 1261ab53a77SGiovanni Cabiddu return -ENOMEM; 1271ab53a77SGiovanni Cabiddu } 128cc4d110eSArd Biesheuvel } 1291ab53a77SGiovanni Cabiddu return 0; 1301ab53a77SGiovanni Cabiddu } 1311ab53a77SGiovanni Cabiddu 1326a8487a1SArd Biesheuvel static int crypto_scomp_init_tfm(struct crypto_tfm *tfm) 1336a8487a1SArd Biesheuvel { 1346a8487a1SArd Biesheuvel int ret; 1356a8487a1SArd Biesheuvel 1366a8487a1SArd Biesheuvel mutex_lock(&scomp_lock); 1376a8487a1SArd Biesheuvel ret = crypto_scomp_alloc_all_scratches(); 1386a8487a1SArd Biesheuvel mutex_unlock(&scomp_lock); 1396a8487a1SArd Biesheuvel 1406a8487a1SArd Biesheuvel return ret; 1416a8487a1SArd Biesheuvel } 1426a8487a1SArd Biesheuvel 1431ab53a77SGiovanni Cabiddu static void crypto_scomp_sg_free(struct scatterlist *sgl) 1441ab53a77SGiovanni Cabiddu { 1451ab53a77SGiovanni Cabiddu int i, n; 1461ab53a77SGiovanni Cabiddu struct page *page; 1471ab53a77SGiovanni Cabiddu 1481ab53a77SGiovanni Cabiddu if (!sgl) 1491ab53a77SGiovanni Cabiddu return; 1501ab53a77SGiovanni Cabiddu 1511ab53a77SGiovanni Cabiddu n = sg_nents(sgl); 1521ab53a77SGiovanni Cabiddu for_each_sg(sgl, sgl, n, i) { 1531ab53a77SGiovanni Cabiddu page = sg_page(sgl); 1541ab53a77SGiovanni Cabiddu if (page) 1551ab53a77SGiovanni Cabiddu __free_page(page); 1561ab53a77SGiovanni Cabiddu } 1571ab53a77SGiovanni Cabiddu 1581ab53a77SGiovanni Cabiddu kfree(sgl); 1591ab53a77SGiovanni Cabiddu } 1601ab53a77SGiovanni Cabiddu 1611ab53a77SGiovanni Cabiddu static struct scatterlist *crypto_scomp_sg_alloc(size_t size, gfp_t gfp) 1621ab53a77SGiovanni Cabiddu { 1631ab53a77SGiovanni Cabiddu struct scatterlist *sgl; 1641ab53a77SGiovanni Cabiddu struct page *page; 1651ab53a77SGiovanni Cabiddu int i, n; 1661ab53a77SGiovanni Cabiddu 1671ab53a77SGiovanni Cabiddu n = ((size - 1) >> PAGE_SHIFT) + 1; 1681ab53a77SGiovanni Cabiddu 1691ab53a77SGiovanni Cabiddu sgl = kmalloc_array(n, sizeof(struct scatterlist), gfp); 1701ab53a77SGiovanni Cabiddu if (!sgl) 1711ab53a77SGiovanni Cabiddu return NULL; 1721ab53a77SGiovanni Cabiddu 1731ab53a77SGiovanni Cabiddu sg_init_table(sgl, n); 1741ab53a77SGiovanni Cabiddu 1751ab53a77SGiovanni Cabiddu for (i = 0; i < n; i++) { 1761ab53a77SGiovanni Cabiddu page = alloc_page(gfp); 1771ab53a77SGiovanni Cabiddu if (!page) 1781ab53a77SGiovanni Cabiddu goto err; 1791ab53a77SGiovanni Cabiddu sg_set_page(sgl + i, page, PAGE_SIZE, 0); 1801ab53a77SGiovanni Cabiddu } 1811ab53a77SGiovanni Cabiddu 1821ab53a77SGiovanni Cabiddu return sgl; 1831ab53a77SGiovanni Cabiddu 1841ab53a77SGiovanni Cabiddu err: 1851ab53a77SGiovanni Cabiddu sg_mark_end(sgl + i); 1861ab53a77SGiovanni Cabiddu crypto_scomp_sg_free(sgl); 1871ab53a77SGiovanni Cabiddu return NULL; 1881ab53a77SGiovanni Cabiddu } 1891ab53a77SGiovanni Cabiddu 1901ab53a77SGiovanni Cabiddu static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) 1911ab53a77SGiovanni Cabiddu { 1921ab53a77SGiovanni Cabiddu struct crypto_acomp *tfm = crypto_acomp_reqtfm(req); 1931ab53a77SGiovanni Cabiddu void **tfm_ctx = acomp_tfm_ctx(tfm); 1941ab53a77SGiovanni Cabiddu struct crypto_scomp *scomp = *tfm_ctx; 1951ab53a77SGiovanni Cabiddu void **ctx = acomp_request_ctx(req); 1961ab53a77SGiovanni Cabiddu const int cpu = get_cpu(); 1971ab53a77SGiovanni Cabiddu u8 *scratch_src = *per_cpu_ptr(scomp_src_scratches, cpu); 1981ab53a77SGiovanni Cabiddu u8 *scratch_dst = *per_cpu_ptr(scomp_dst_scratches, cpu); 1991ab53a77SGiovanni Cabiddu int ret; 2001ab53a77SGiovanni Cabiddu 2011ab53a77SGiovanni Cabiddu if (!req->src || !req->slen || req->slen > SCOMP_SCRATCH_SIZE) { 2021ab53a77SGiovanni Cabiddu ret = -EINVAL; 2031ab53a77SGiovanni Cabiddu goto out; 2041ab53a77SGiovanni Cabiddu } 2051ab53a77SGiovanni Cabiddu 2061ab53a77SGiovanni Cabiddu if (req->dst && !req->dlen) { 2071ab53a77SGiovanni Cabiddu ret = -EINVAL; 2081ab53a77SGiovanni Cabiddu goto out; 2091ab53a77SGiovanni Cabiddu } 2101ab53a77SGiovanni Cabiddu 2111ab53a77SGiovanni Cabiddu if (!req->dlen || req->dlen > SCOMP_SCRATCH_SIZE) 2121ab53a77SGiovanni Cabiddu req->dlen = SCOMP_SCRATCH_SIZE; 2131ab53a77SGiovanni Cabiddu 2141ab53a77SGiovanni Cabiddu scatterwalk_map_and_copy(scratch_src, req->src, 0, req->slen, 0); 2151ab53a77SGiovanni Cabiddu if (dir) 2161ab53a77SGiovanni Cabiddu ret = crypto_scomp_compress(scomp, scratch_src, req->slen, 2171ab53a77SGiovanni Cabiddu scratch_dst, &req->dlen, *ctx); 2181ab53a77SGiovanni Cabiddu else 2191ab53a77SGiovanni Cabiddu ret = crypto_scomp_decompress(scomp, scratch_src, req->slen, 2201ab53a77SGiovanni Cabiddu scratch_dst, &req->dlen, *ctx); 2211ab53a77SGiovanni Cabiddu if (!ret) { 2221ab53a77SGiovanni Cabiddu if (!req->dst) { 2233c083772SArd Biesheuvel req->dst = crypto_scomp_sg_alloc(req->dlen, GFP_ATOMIC); 2241ab53a77SGiovanni Cabiddu if (!req->dst) 2251ab53a77SGiovanni Cabiddu goto out; 2261ab53a77SGiovanni Cabiddu } 2271ab53a77SGiovanni Cabiddu scatterwalk_map_and_copy(scratch_dst, req->dst, 0, req->dlen, 2281ab53a77SGiovanni Cabiddu 1); 2291ab53a77SGiovanni Cabiddu } 2301ab53a77SGiovanni Cabiddu out: 2311ab53a77SGiovanni Cabiddu put_cpu(); 2321ab53a77SGiovanni Cabiddu return ret; 2331ab53a77SGiovanni Cabiddu } 2341ab53a77SGiovanni Cabiddu 2351ab53a77SGiovanni Cabiddu static int scomp_acomp_compress(struct acomp_req *req) 2361ab53a77SGiovanni Cabiddu { 2371ab53a77SGiovanni Cabiddu return scomp_acomp_comp_decomp(req, 1); 2381ab53a77SGiovanni Cabiddu } 2391ab53a77SGiovanni Cabiddu 2401ab53a77SGiovanni Cabiddu static int scomp_acomp_decompress(struct acomp_req *req) 2411ab53a77SGiovanni Cabiddu { 2421ab53a77SGiovanni Cabiddu return scomp_acomp_comp_decomp(req, 0); 2431ab53a77SGiovanni Cabiddu } 2441ab53a77SGiovanni Cabiddu 2451ab53a77SGiovanni Cabiddu static void crypto_exit_scomp_ops_async(struct crypto_tfm *tfm) 2461ab53a77SGiovanni Cabiddu { 2471ab53a77SGiovanni Cabiddu struct crypto_scomp **ctx = crypto_tfm_ctx(tfm); 2481ab53a77SGiovanni Cabiddu 2491ab53a77SGiovanni Cabiddu crypto_free_scomp(*ctx); 2506a8487a1SArd Biesheuvel 2516a8487a1SArd Biesheuvel mutex_lock(&scomp_lock); 2526a8487a1SArd Biesheuvel crypto_scomp_free_all_scratches(); 2536a8487a1SArd Biesheuvel mutex_unlock(&scomp_lock); 2541ab53a77SGiovanni Cabiddu } 2551ab53a77SGiovanni Cabiddu 2561ab53a77SGiovanni Cabiddu int crypto_init_scomp_ops_async(struct crypto_tfm *tfm) 2571ab53a77SGiovanni Cabiddu { 2581ab53a77SGiovanni Cabiddu struct crypto_alg *calg = tfm->__crt_alg; 2591ab53a77SGiovanni Cabiddu struct crypto_acomp *crt = __crypto_acomp_tfm(tfm); 2601ab53a77SGiovanni Cabiddu struct crypto_scomp **ctx = crypto_tfm_ctx(tfm); 2611ab53a77SGiovanni Cabiddu struct crypto_scomp *scomp; 2621ab53a77SGiovanni Cabiddu 2631ab53a77SGiovanni Cabiddu if (!crypto_mod_get(calg)) 2641ab53a77SGiovanni Cabiddu return -EAGAIN; 2651ab53a77SGiovanni Cabiddu 2661ab53a77SGiovanni Cabiddu scomp = crypto_create_tfm(calg, &crypto_scomp_type); 2671ab53a77SGiovanni Cabiddu if (IS_ERR(scomp)) { 2681ab53a77SGiovanni Cabiddu crypto_mod_put(calg); 2691ab53a77SGiovanni Cabiddu return PTR_ERR(scomp); 2701ab53a77SGiovanni Cabiddu } 2711ab53a77SGiovanni Cabiddu 2721ab53a77SGiovanni Cabiddu *ctx = scomp; 2731ab53a77SGiovanni Cabiddu tfm->exit = crypto_exit_scomp_ops_async; 2741ab53a77SGiovanni Cabiddu 2751ab53a77SGiovanni Cabiddu crt->compress = scomp_acomp_compress; 2761ab53a77SGiovanni Cabiddu crt->decompress = scomp_acomp_decompress; 2771ab53a77SGiovanni Cabiddu crt->dst_free = crypto_scomp_sg_free; 2781ab53a77SGiovanni Cabiddu crt->reqsize = sizeof(void *); 2791ab53a77SGiovanni Cabiddu 2801ab53a77SGiovanni Cabiddu return 0; 2811ab53a77SGiovanni Cabiddu } 2821ab53a77SGiovanni Cabiddu 2831ab53a77SGiovanni Cabiddu struct acomp_req *crypto_acomp_scomp_alloc_ctx(struct acomp_req *req) 2841ab53a77SGiovanni Cabiddu { 2851ab53a77SGiovanni Cabiddu struct crypto_acomp *acomp = crypto_acomp_reqtfm(req); 2861ab53a77SGiovanni Cabiddu struct crypto_tfm *tfm = crypto_acomp_tfm(acomp); 2871ab53a77SGiovanni Cabiddu struct crypto_scomp **tfm_ctx = crypto_tfm_ctx(tfm); 2881ab53a77SGiovanni Cabiddu struct crypto_scomp *scomp = *tfm_ctx; 2891ab53a77SGiovanni Cabiddu void *ctx; 2901ab53a77SGiovanni Cabiddu 2911ab53a77SGiovanni Cabiddu ctx = crypto_scomp_alloc_ctx(scomp); 2921ab53a77SGiovanni Cabiddu if (IS_ERR(ctx)) { 2931ab53a77SGiovanni Cabiddu kfree(req); 2941ab53a77SGiovanni Cabiddu return NULL; 2951ab53a77SGiovanni Cabiddu } 2961ab53a77SGiovanni Cabiddu 2971ab53a77SGiovanni Cabiddu *req->__ctx = ctx; 2981ab53a77SGiovanni Cabiddu 2991ab53a77SGiovanni Cabiddu return req; 3001ab53a77SGiovanni Cabiddu } 3011ab53a77SGiovanni Cabiddu 3021ab53a77SGiovanni Cabiddu void crypto_acomp_scomp_free_ctx(struct acomp_req *req) 3031ab53a77SGiovanni Cabiddu { 3041ab53a77SGiovanni Cabiddu struct crypto_acomp *acomp = crypto_acomp_reqtfm(req); 3051ab53a77SGiovanni Cabiddu struct crypto_tfm *tfm = crypto_acomp_tfm(acomp); 3061ab53a77SGiovanni Cabiddu struct crypto_scomp **tfm_ctx = crypto_tfm_ctx(tfm); 3071ab53a77SGiovanni Cabiddu struct crypto_scomp *scomp = *tfm_ctx; 3081ab53a77SGiovanni Cabiddu void *ctx = *req->__ctx; 3091ab53a77SGiovanni Cabiddu 3101ab53a77SGiovanni Cabiddu if (ctx) 3111ab53a77SGiovanni Cabiddu crypto_scomp_free_ctx(scomp, ctx); 3121ab53a77SGiovanni Cabiddu } 3131ab53a77SGiovanni Cabiddu 3141ab53a77SGiovanni Cabiddu static const struct crypto_type crypto_scomp_type = { 3151ab53a77SGiovanni Cabiddu .extsize = crypto_alg_extsize, 3161ab53a77SGiovanni Cabiddu .init_tfm = crypto_scomp_init_tfm, 3171ab53a77SGiovanni Cabiddu #ifdef CONFIG_PROC_FS 3181ab53a77SGiovanni Cabiddu .show = crypto_scomp_show, 3191ab53a77SGiovanni Cabiddu #endif 3201ab53a77SGiovanni Cabiddu .report = crypto_scomp_report, 3211ab53a77SGiovanni Cabiddu .maskclear = ~CRYPTO_ALG_TYPE_MASK, 3221ab53a77SGiovanni Cabiddu .maskset = CRYPTO_ALG_TYPE_MASK, 3231ab53a77SGiovanni Cabiddu .type = CRYPTO_ALG_TYPE_SCOMPRESS, 3241ab53a77SGiovanni Cabiddu .tfmsize = offsetof(struct crypto_scomp, base), 3251ab53a77SGiovanni Cabiddu }; 3261ab53a77SGiovanni Cabiddu 3271ab53a77SGiovanni Cabiddu int crypto_register_scomp(struct scomp_alg *alg) 3281ab53a77SGiovanni Cabiddu { 3291ab53a77SGiovanni Cabiddu struct crypto_alg *base = &alg->base; 3301ab53a77SGiovanni Cabiddu 3311ab53a77SGiovanni Cabiddu base->cra_type = &crypto_scomp_type; 3321ab53a77SGiovanni Cabiddu base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; 3331ab53a77SGiovanni Cabiddu base->cra_flags |= CRYPTO_ALG_TYPE_SCOMPRESS; 3341ab53a77SGiovanni Cabiddu 3356a8487a1SArd Biesheuvel return crypto_register_alg(base); 3361ab53a77SGiovanni Cabiddu } 3371ab53a77SGiovanni Cabiddu EXPORT_SYMBOL_GPL(crypto_register_scomp); 3381ab53a77SGiovanni Cabiddu 3391ab53a77SGiovanni Cabiddu int crypto_unregister_scomp(struct scomp_alg *alg) 3401ab53a77SGiovanni Cabiddu { 3416a8487a1SArd Biesheuvel return crypto_unregister_alg(&alg->base); 3421ab53a77SGiovanni Cabiddu } 3431ab53a77SGiovanni Cabiddu EXPORT_SYMBOL_GPL(crypto_unregister_scomp); 3441ab53a77SGiovanni Cabiddu 3453de4f5e1SGiovanni Cabiddu int crypto_register_scomps(struct scomp_alg *algs, int count) 3463de4f5e1SGiovanni Cabiddu { 3473de4f5e1SGiovanni Cabiddu int i, ret; 3483de4f5e1SGiovanni Cabiddu 3493de4f5e1SGiovanni Cabiddu for (i = 0; i < count; i++) { 3503de4f5e1SGiovanni Cabiddu ret = crypto_register_scomp(&algs[i]); 3513de4f5e1SGiovanni Cabiddu if (ret) 3523de4f5e1SGiovanni Cabiddu goto err; 3533de4f5e1SGiovanni Cabiddu } 3543de4f5e1SGiovanni Cabiddu 3553de4f5e1SGiovanni Cabiddu return 0; 3563de4f5e1SGiovanni Cabiddu 3573de4f5e1SGiovanni Cabiddu err: 3583de4f5e1SGiovanni Cabiddu for (--i; i >= 0; --i) 3593de4f5e1SGiovanni Cabiddu crypto_unregister_scomp(&algs[i]); 3603de4f5e1SGiovanni Cabiddu 3613de4f5e1SGiovanni Cabiddu return ret; 3623de4f5e1SGiovanni Cabiddu } 3633de4f5e1SGiovanni Cabiddu EXPORT_SYMBOL_GPL(crypto_register_scomps); 3643de4f5e1SGiovanni Cabiddu 3653de4f5e1SGiovanni Cabiddu void crypto_unregister_scomps(struct scomp_alg *algs, int count) 3663de4f5e1SGiovanni Cabiddu { 3673de4f5e1SGiovanni Cabiddu int i; 3683de4f5e1SGiovanni Cabiddu 3693de4f5e1SGiovanni Cabiddu for (i = count - 1; i >= 0; --i) 3703de4f5e1SGiovanni Cabiddu crypto_unregister_scomp(&algs[i]); 3713de4f5e1SGiovanni Cabiddu } 3723de4f5e1SGiovanni Cabiddu EXPORT_SYMBOL_GPL(crypto_unregister_scomps); 3733de4f5e1SGiovanni Cabiddu 3741ab53a77SGiovanni Cabiddu MODULE_LICENSE("GPL"); 3751ab53a77SGiovanni Cabiddu MODULE_DESCRIPTION("Synchronous compression type"); 376