Commit 0946befc authored by James Morris's avatar James Morris Committed by Linus Torvalds

[CRYPTO]: Add Deflate algorithm to crypto API.

parent df7a3f34
......@@ -131,6 +131,16 @@ config CRYPTO_AES
See http://csrc.nist.gov/encryption/aes/ for more information.
config CRYPTO_DEFLATE
tristate "Deflate compression algorithm"
depends on CRYPTO
default y if INET_IPCOMP=y || INET_IPCOMP=m
help
This is the Deflate algorithm (RFC1951), specified for use in
IPSec with the IPCOMP protocol (RFC3173, RFC2394).
You will most probably want this if using IPSec.
config CRYPTO_TEST
tristate "Testing module"
depends on CRYPTO
......
......@@ -20,5 +20,6 @@ obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
obj-$(CONFIG_CRYPTO_AES) += aes.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
......@@ -127,7 +127,7 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
if (tfm == NULL)
goto out_put;
memset(tfm, 0, sizeof(*tfm));
memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
tfm->__crt_alg = alg;
......
......@@ -18,29 +18,46 @@
#include <linux/string.h>
#include "internal.h"
static void crypto_compress(struct crypto_tfm *tfm)
static int crypto_compress(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
tfm->__crt_alg->cra_compress.coa_compress();
return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm),
src, slen, dst,
dlen);
}
static void crypto_decompress(struct crypto_tfm *tfm)
static int crypto_decompress(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
tfm->__crt_alg->cra_compress.coa_decompress();
return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm),
src, slen, dst,
dlen);
}
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
{
return crypto_cipher_flags(flags) ? -EINVAL : 0;
return flags ? -EINVAL : 0;
}
int crypto_init_compress_ops(struct crypto_tfm *tfm)
{
int ret = 0;
struct compress_tfm *ops = &tfm->crt_compress;
ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm));
if (ret)
goto out;
ops->cot_compress = crypto_compress;
ops->cot_decompress = crypto_decompress;
return 0;
out:
return ret;
}
void crypto_exit_compress_ops(struct crypto_tfm *tfm)
{ }
{
tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
}
......@@ -26,11 +26,13 @@
#define NULL_BLOCK_SIZE 1
#define NULL_DIGEST_SIZE 0
static void null_compress(void)
{ }
static int null_compress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{ return 0; }
static void null_decompress(void)
{ }
static int null_decompress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{ return 0; }
static void null_init(void *ctx)
{ }
......
/*
* Cryptographic API.
*
* Deflate algorithm (RFC 1951), implemented here primarily for use
* by IPCOMP (RFC 3173 & RFC 2394).
*
* Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* FIXME: deflate transforms will require up to a total of about 436k of kernel
* memory on i386 (390k for compression, the rest for decompression), as the
* current zlib kernel code uses a worst case pre-allocation system by default.
* This needs to be fixed so that the amount of memory required is properly
* related to the winbits and memlevel parameters.
*
* The default winbits of 11 should suit most packets, and it may be something
* to configure on a per-tfm basis in the future.
*
* Currently, compression history is not maintained between tfm calls, as
* it is not needed for IPCOMP and keeps the code simpler. It can be
* implemented if someone wants it.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/zlib.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/net.h>
#define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION
#define DEFLATE_DEF_WINBITS 11
#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
struct deflate_ctx {
int comp_initialized;
int decomp_initialized;
struct z_stream_s comp_stream;
struct z_stream_s decomp_stream;
};
static inline int deflate_gfp(void)
{
return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
}
static int deflate_init(void *ctx)
{
return 0;
}
static void deflate_exit(void *ctx)
{
struct deflate_ctx *dctx = ctx;
if (dctx->comp_initialized)
vfree(dctx->comp_stream.workspace);
if (dctx->decomp_initialized)
kfree(dctx->decomp_stream.workspace);
}
/*
* Lazy initialization to make interface simple without allocating
* un-needed workspaces. Thus can be called in softirq context.
*/
static int deflate_comp_init(struct deflate_ctx *ctx)
{
int ret = 0;
struct z_stream_s *stream = &ctx->comp_stream;
stream->workspace = __vmalloc(zlib_deflate_workspacesize(),
deflate_gfp()|__GFP_HIGHMEM,
PAGE_KERNEL);
if (!stream->workspace ) {
ret = -ENOMEM;
goto out;
}
memset(stream->workspace, 0, sizeof(stream->workspace));
ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
-DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
Z_DEFAULT_STRATEGY);
if (ret != Z_OK) {
ret = -EINVAL;
goto out_free;
}
ctx->comp_initialized = 1;
out:
return ret;
out_free:
vfree(stream->workspace);
goto out;
}
static int deflate_decomp_init(struct deflate_ctx *ctx)
{
int ret = 0;
struct z_stream_s *stream = &ctx->decomp_stream;
stream->workspace = kmalloc(zlib_inflate_workspacesize(),
deflate_gfp());
if (!stream->workspace ) {
ret = -ENOMEM;
goto out;
}
memset(stream->workspace, 0, sizeof(stream->workspace));
ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
if (ret != Z_OK) {
ret = -EINVAL;
goto out_free;
}
ctx->decomp_initialized = 1;
out:
return ret;
out_free:
kfree(stream->workspace);
goto out;
}
static int deflate_compress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
int ret = 0;
struct deflate_ctx *dctx = ctx;
struct z_stream_s *stream = &dctx->comp_stream;
if (!dctx->comp_initialized) {
ret = deflate_comp_init(dctx);
if (ret)
goto out;
}
ret = zlib_deflateReset(stream);
if (ret != Z_OK) {
ret = -EINVAL;
goto out;
}
stream->next_in = (u8 *)src;
stream->avail_in = slen;
stream->next_out = (u8 *)dst;
stream->avail_out = *dlen;
ret = zlib_deflate(stream, Z_FINISH);
if (ret != Z_STREAM_END) {
ret = -EINVAL;
goto out;
}
ret = 0;
*dlen = stream->total_out;
out:
return ret;
}
static int deflate_decompress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
int ret = 0;
struct deflate_ctx *dctx = ctx;
struct z_stream_s *stream = &dctx->decomp_stream;
if (!dctx->decomp_initialized) {
ret = deflate_decomp_init(dctx);
if (ret)
goto out;
}
ret = zlib_inflateReset(stream);
if (ret != Z_OK) {
ret = -EINVAL;
goto out;
}
stream->next_in = (u8 *)src;
stream->avail_in = slen;
stream->next_out = (u8 *)dst;
stream->avail_out = *dlen;
ret = zlib_inflate(stream, Z_FINISH);
if (ret != Z_STREAM_END) {
ret = -EINVAL;
goto out;
}
ret = 0;
*dlen = stream->total_out;
out:
return ret;
}
static struct crypto_alg alg = {
.cra_name = "deflate",
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
.cra_ctxsize = sizeof(struct deflate_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .compress = {
.coa_init = deflate_init,
.coa_exit = deflate_exit,
.coa_compress = deflate_compress,
.coa_decompress = deflate_decompress } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
......@@ -61,7 +61,7 @@ static void digest(struct crypto_tfm *tfm,
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
{
return crypto_cipher_flags(flags) ? -EINVAL : 0;
return flags ? -EINVAL : 0;
}
int crypto_init_digest_ops(struct crypto_tfm *tfm)
......
......@@ -41,11 +41,6 @@ static inline void crypto_yield(struct crypto_tfm *tfm)
cond_resched();
}
static inline u32 crypto_cipher_flags(u32 flags)
{
return flags & (CRYPTO_TFM_MODE_MASK|CRYPTO_TFM_REQ_WEAK_KEY);
}
static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
{
return (void *)&tfm[1];
......
......@@ -54,10 +54,10 @@ static int c_show(struct seq_file *m, void *p)
seq_printf(m, "name : %s\n", alg->cra_name);
seq_printf(m, "module : %s\n", module_name(alg->cra_module));
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_ALG_TYPE_CIPHER:
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "min keysize : %u\n",
alg->cra_cipher.cia_min_keysize);
seq_printf(m, "max keysize : %u\n",
......@@ -67,6 +67,7 @@ static int c_show(struct seq_file *m, void *p)
break;
case CRYPTO_ALG_TYPE_DIGEST:
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "digestsize : %u\n",
alg->cra_digest.dia_digestsize);
break;
......
......@@ -48,7 +48,7 @@ static char *tvmem;
static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "deflate",
NULL
};
......@@ -2192,6 +2192,86 @@ test_aes(void)
crypto_free_tfm(tfm);
}
static void
test_deflate(void)
{
unsigned int i;
char result[COMP_BUF_SIZE];
struct crypto_tfm *tfm;
struct comp_testvec *tv;
unsigned int tsize;
printk("\ntesting deflate compression\n");
tsize = sizeof (deflate_comp_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, deflate_comp_tv_template, tsize);
tv = (void *) tvmem;
tfm = crypto_alloc_tfm("deflate", 0);
if (tfm == NULL) {
printk("failed to load transform for deflate\n");
return;
}
for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) {
int ilen, ret, dlen = COMP_BUF_SIZE;
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
ilen = tv[i].inlen;
ret = crypto_comp_compress(tfm, tv[i].input,
ilen, result, &dlen);
if (ret) {
printk("fail: ret=%d\n", ret);
continue;
}
hexdump(result, dlen);
printk("%s (ratio %d:%d)\n",
memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
ilen, dlen);
}
printk("\ntesting deflate decompression\n");
tsize = sizeof (deflate_decomp_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, deflate_decomp_tv_template, tsize);
tv = (void *) tvmem;
for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
int ilen, ret, dlen = COMP_BUF_SIZE;
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
ilen = tv[i].inlen;
ret = crypto_comp_decompress(tfm, tv[i].input,
ilen, result, &dlen);
if (ret) {
printk("fail: ret=%d\n", ret);
continue;
}
hexdump(result, dlen);
printk("%s (ratio %d:%d)\n",
memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
ilen, dlen);
}
out:
crypto_free_tfm(tfm);
}
static void
test_available(void)
{
......@@ -2223,6 +2303,7 @@ do_test(void)
test_aes();
test_sha384();
test_sha512();
test_deflate();
#ifdef CONFIG_CRYPTO_HMAC
test_hmac_md5();
test_hmac_sha1();
......@@ -2278,6 +2359,10 @@ do_test(void)
test_sha512();
break;
case 13:
test_deflate();
break;
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac_md5();
......
......@@ -1682,4 +1682,104 @@ struct aes_tv aes_dec_tv_template[] = {
},
};
/*
* Compression stuff.
*/
#define COMP_BUF_SIZE 512
struct comp_testvec {
int inlen, outlen;
char input[COMP_BUF_SIZE];
char output[COMP_BUF_SIZE];
};
/*
* Deflate test vectors (null-terminated strings).
* Params: winbits=11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
*/
#define DEFLATE_COMP_TEST_VECTORS 2
#define DEFLATE_DECOMP_TEST_VECTORS 2
struct comp_testvec deflate_comp_tv_template[] = {
{
70, 38,
"Join us now and share the software "
"Join us now and share the software ",
{ 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00
},
},
{
191, 122,
"This document describes a compression method based on the DEFLATE"
"compression algorithm. This document defines the application of "
"the DEFLATE algorithm to the IP Payload Compression Protocol.",
{ 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
0xfa, 0x02 },
},
};
struct comp_testvec deflate_decomp_tv_template[] = {
{
122, 191,
{ 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
0xfa, 0x02 },
"This document describes a compression method based on the DEFLATE"
"compression algorithm. This document defines the application of "
"the DEFLATE algorithm to the IP Payload Compression Protocol.",
},
{
38, 70,
{ 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00
},
"Join us now and share the software "
"Join us now and share the software ",
},
};
#endif /* _CRYPTO_TCRYPT_H */
......@@ -31,7 +31,6 @@
#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
/*
* Transform masks and values (for crt_flags).
*/
......@@ -45,14 +44,12 @@
#define CRYPTO_TFM_MODE_CTR 0x00000008
#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
/*
* Miscellaneous stuff.
*/
......@@ -83,8 +80,12 @@ struct digest_alg {
};
struct compress_alg {
void (*coa_compress)(void);
void (*coa_decompress)(void);
int (*coa_init)(void *ctx);
void (*coa_exit)(void *ctx);
int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen);
int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen);
};
#define cra_cipher cra_u.cipher
......@@ -162,8 +163,12 @@ struct digest_tfm {
};
struct compress_tfm {
void (*cot_compress)(struct crypto_tfm *tfm);
void (*cot_decompress)(struct crypto_tfm *tfm);
int (*cot_compress)(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen);
int (*cot_decompress)(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen);
};
#define crt_cipher crt_u.cipher
......@@ -336,16 +341,20 @@ static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
memcpy(dst, tfm->crt_cipher.cit_iv, len);
}
static inline void crypto_comp_compress(struct crypto_tfm *tfm)
static inline int crypto_comp_compress(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
tfm->crt_compress.cot_compress(tfm);
return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
}
static inline void crypto_comp_decompress(struct crypto_tfm *tfm)
static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
tfm->crt_compress.cot_decompress(tfm);
return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
}
/*
......
......@@ -17,13 +17,14 @@ config CRC32
#
config ZLIB_INFLATE
tristate
default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y
default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m
default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y || CRYPTO_DEFLATE=y
default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m || CRYPTO_DEFLATE=m
config ZLIB_DEFLATE
tristate
default m if PPP_DEFLATE!=y && JFFS2_FS!=y && (PPP_DEFLATE=m || JFFS2_FS=m)
default y if PPP_DEFLATE=y || JFFS2_FS=y
default m if PPP_DEFLATE!=y && JFFS2_FS!=y && CRYPTO_DEFLATE!=y && \
(PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m)
default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y
endmenu
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment