summaryrefslogtreecommitdiffstats
path: root/crypto/842.c
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@ieee.org>2015-05-07 13:49:15 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-05-11 03:06:43 -0400
commit2062c5b6da758ca2bb64b698d7f9c5c45a06fcf9 (patch)
treea1be2f5e00261b99e8ab85864dbb16075d809eb7 /crypto/842.c
parent2da572c959dd5815aef153cf62010b16a498a0d3 (diff)
crypto: 842 - change 842 alg to use software
Change the crypto 842 compression alg to use the software 842 compression and decompression library. Add the crypto driver_name as "842-generic". Remove the fallback to LZO compression. Previously, this crypto compression alg attemped 842 compression using PowerPC hardware, and fell back to LZO compression and decompression if the 842 PowerPC hardware was unavailable or failed. This should not fall back to any other compression method, however; users of this crypto compression alg can fallback if desired, and transparent fallback tricks callers into thinking they are getting 842 compression when they actually get LZO compression - the failure of the 842 hardware should not be transparent to the caller. The crypto compression alg for a hardware device also should not be located in crypto/ so this is now a software-only implementation that uses the 842 software compression/decompression library. Signed-off-by: Dan Streetman <ddstreet@ieee.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/842.c')
-rw-r--r--crypto/842.c174
1 files changed, 37 insertions, 137 deletions
diff --git a/crypto/842.c b/crypto/842.c
index b48f4f108c47..98e387efb8c8 100644
--- a/crypto/842.c
+++ b/crypto/842.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Cryptographic API for the 842 compression algorithm. 2 * Cryptographic API for the 842 software compression algorithm.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -11,173 +11,73 @@
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * Copyright (C) IBM Corporation, 2011-2015
15 * along with this program; if not, write to the Free Software
16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 * 15 *
18 * Copyright (C) IBM Corporation, 2011 16 * Original Authors: Robert Jennings <rcj@linux.vnet.ibm.com>
17 * Seth Jennings <sjenning@linux.vnet.ibm.com>
19 * 18 *
20 * Authors: Robert Jennings <rcj@linux.vnet.ibm.com> 19 * Rewrite: Dan Streetman <ddstreet@ieee.org>
21 * Seth Jennings <sjenning@linux.vnet.ibm.com> 20 *
21 * This is the software implementation of compression and decompression using
22 * the 842 format. This uses the software 842 library at lib/842/ which is
23 * only a reference implementation, and is very, very slow as compared to other
24 * software compressors. You probably do not want to use this software
25 * compression. If you have access to the PowerPC 842 compression hardware, you
26 * want to use the 842 hardware compression interface, which is at:
27 * drivers/crypto/nx/nx-842-crypto.c
22 */ 28 */
23 29
24#include <linux/init.h> 30#include <linux/init.h>
25#include <linux/module.h> 31#include <linux/module.h>
26#include <linux/crypto.h> 32#include <linux/crypto.h>
27#include <linux/vmalloc.h> 33#include <linux/sw842.h>
28#include <linux/nx842.h>
29#include <linux/lzo.h>
30#include <linux/timer.h>
31
32static int nx842_uselzo;
33
34struct nx842_ctx {
35 void *nx842_wmem; /* working memory for 842/lzo */
36};
37 34
38enum nx842_crypto_type { 35struct crypto842_ctx {
39 NX842_CRYPTO_TYPE_842, 36 char wmem[SW842_MEM_COMPRESS]; /* working memory for compress */
40 NX842_CRYPTO_TYPE_LZO
41}; 37};
42 38
43#define NX842_SENTINEL 0xdeadbeef 39static int crypto842_compress(struct crypto_tfm *tfm,
44 40 const u8 *src, unsigned int slen,
45struct nx842_crypto_header { 41 u8 *dst, unsigned int *dlen)
46 unsigned int sentinel; /* debug */
47 enum nx842_crypto_type type;
48};
49
50static int nx842_init(struct crypto_tfm *tfm)
51{
52 struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
53 int wmemsize;
54
55 wmemsize = max_t(int, nx842_get_workmem_size(), LZO1X_MEM_COMPRESS);
56 ctx->nx842_wmem = kmalloc(wmemsize, GFP_NOFS);
57 if (!ctx->nx842_wmem)
58 return -ENOMEM;
59
60 return 0;
61}
62
63static void nx842_exit(struct crypto_tfm *tfm)
64{
65 struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
66
67 kfree(ctx->nx842_wmem);
68}
69
70static void nx842_reset_uselzo(unsigned long data)
71{ 42{
72 nx842_uselzo = 0; 43 struct crypto842_ctx *ctx = crypto_tfm_ctx(tfm);
73}
74
75static DEFINE_TIMER(failover_timer, nx842_reset_uselzo, 0, 0);
76
77static int nx842_crypto_compress(struct crypto_tfm *tfm, const u8 *src,
78 unsigned int slen, u8 *dst, unsigned int *dlen)
79{
80 struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
81 struct nx842_crypto_header *hdr;
82 unsigned int tmp_len = *dlen;
83 size_t lzodlen; /* needed for lzo */
84 int err;
85
86 *dlen = 0;
87 hdr = (struct nx842_crypto_header *)dst;
88 hdr->sentinel = NX842_SENTINEL; /* debug */
89 dst += sizeof(struct nx842_crypto_header);
90 tmp_len -= sizeof(struct nx842_crypto_header);
91 lzodlen = tmp_len;
92
93 if (likely(!nx842_uselzo)) {
94 err = nx842_compress(src, slen, dst, &tmp_len, ctx->nx842_wmem);
95
96 if (likely(!err)) {
97 hdr->type = NX842_CRYPTO_TYPE_842;
98 *dlen = tmp_len + sizeof(struct nx842_crypto_header);
99 return 0;
100 }
101
102 /* hardware failed */
103 nx842_uselzo = 1;
104 44
105 /* set timer to check for hardware again in 1 second */ 45 return sw842_compress(src, slen, dst, dlen, ctx->wmem);
106 mod_timer(&failover_timer, jiffies + msecs_to_jiffies(1000));
107 }
108
109 /* no hardware, use lzo */
110 err = lzo1x_1_compress(src, slen, dst, &lzodlen, ctx->nx842_wmem);
111 if (err != LZO_E_OK)
112 return -EINVAL;
113
114 hdr->type = NX842_CRYPTO_TYPE_LZO;
115 *dlen = lzodlen + sizeof(struct nx842_crypto_header);
116 return 0;
117} 46}
118 47
119static int nx842_crypto_decompress(struct crypto_tfm *tfm, const u8 *src, 48static int crypto842_decompress(struct crypto_tfm *tfm,
120 unsigned int slen, u8 *dst, unsigned int *dlen) 49 const u8 *src, unsigned int slen,
50 u8 *dst, unsigned int *dlen)
121{ 51{
122 struct nx842_ctx *ctx = crypto_tfm_ctx(tfm); 52 return sw842_decompress(src, slen, dst, dlen);
123 struct nx842_crypto_header *hdr;
124 unsigned int tmp_len = *dlen;
125 size_t lzodlen; /* needed for lzo */
126 int err;
127
128 *dlen = 0;
129 hdr = (struct nx842_crypto_header *)src;
130
131 if (unlikely(hdr->sentinel != NX842_SENTINEL))
132 return -EINVAL;
133
134 src += sizeof(struct nx842_crypto_header);
135 slen -= sizeof(struct nx842_crypto_header);
136
137 if (likely(hdr->type == NX842_CRYPTO_TYPE_842)) {
138 err = nx842_decompress(src, slen, dst, &tmp_len,
139 ctx->nx842_wmem);
140 if (err)
141 return -EINVAL;
142 *dlen = tmp_len;
143 } else if (hdr->type == NX842_CRYPTO_TYPE_LZO) {
144 lzodlen = tmp_len;
145 err = lzo1x_decompress_safe(src, slen, dst, &lzodlen);
146 if (err != LZO_E_OK)
147 return -EINVAL;
148 *dlen = lzodlen;
149 } else
150 return -EINVAL;
151
152 return 0;
153} 53}
154 54
155static struct crypto_alg alg = { 55static struct crypto_alg alg = {
156 .cra_name = "842", 56 .cra_name = "842",
57 .cra_driver_name = "842-generic",
58 .cra_priority = 100,
157 .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 59 .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
158 .cra_ctxsize = sizeof(struct nx842_ctx), 60 .cra_ctxsize = sizeof(struct crypto842_ctx),
159 .cra_module = THIS_MODULE, 61 .cra_module = THIS_MODULE,
160 .cra_init = nx842_init,
161 .cra_exit = nx842_exit,
162 .cra_u = { .compress = { 62 .cra_u = { .compress = {
163 .coa_compress = nx842_crypto_compress, 63 .coa_compress = crypto842_compress,
164 .coa_decompress = nx842_crypto_decompress } } 64 .coa_decompress = crypto842_decompress } }
165}; 65};
166 66
167static int __init nx842_mod_init(void) 67static int __init crypto842_mod_init(void)
168{ 68{
169 del_timer(&failover_timer);
170 return crypto_register_alg(&alg); 69 return crypto_register_alg(&alg);
171} 70}
71module_init(crypto842_mod_init);
172 72
173static void __exit nx842_mod_exit(void) 73static void __exit crypto842_mod_exit(void)
174{ 74{
175 crypto_unregister_alg(&alg); 75 crypto_unregister_alg(&alg);
176} 76}
177 77module_exit(crypto842_mod_exit);
178module_init(nx842_mod_init);
179module_exit(nx842_mod_exit);
180 78
181MODULE_LICENSE("GPL"); 79MODULE_LICENSE("GPL");
182MODULE_DESCRIPTION("842 Compression Algorithm"); 80MODULE_DESCRIPTION("842 Software Compression Algorithm");
183MODULE_ALIAS_CRYPTO("842"); 81MODULE_ALIAS_CRYPTO("842");
82MODULE_ALIAS_CRYPTO("842-generic");
83MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");