Commit ea0b3984 authored by Haren Myneni's avatar Haren Myneni Committed by Herbert Xu

crypto: 842 - Add CRC and validation support

This patch adds CRC generation and validation support for nx-842.
Add CRC flag so that nx842 coprocessor includes CRC during compression
and validates during decompression.

Also changes in 842 SW compression to append CRC value at the end
of template and checks during decompression.
Signed-off-by: default avatarHaren Myneni <haren@us.ibm.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent f5128432
...@@ -491,7 +491,7 @@ static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen, ...@@ -491,7 +491,7 @@ static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
void *wmem) void *wmem)
{ {
return nx842_powernv_function(in, inlen, out, outlenp, return nx842_powernv_function(in, inlen, out, outlenp,
wmem, CCW_FC_842_COMP_NOCRC); wmem, CCW_FC_842_COMP_CRC);
} }
/** /**
...@@ -519,7 +519,7 @@ static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen, ...@@ -519,7 +519,7 @@ static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
void *wmem) void *wmem)
{ {
return nx842_powernv_function(in, inlen, out, outlenp, return nx842_powernv_function(in, inlen, out, outlenp,
wmem, CCW_FC_842_DECOMP_NOCRC); wmem, CCW_FC_842_DECOMP_CRC);
} }
static int __init nx842_powernv_probe(struct device_node *dn) static int __init nx842_powernv_probe(struct device_node *dn)
......
...@@ -234,6 +234,10 @@ static int nx842_validate_result(struct device *dev, ...@@ -234,6 +234,10 @@ static int nx842_validate_result(struct device *dev,
dev_dbg(dev, "%s: Out of space in output buffer\n", dev_dbg(dev, "%s: Out of space in output buffer\n",
__func__); __func__);
return -ENOSPC; return -ENOSPC;
case 65: /* Calculated CRC doesn't match the passed value */
dev_dbg(dev, "%s: CRC mismatch for decompression\n",
__func__);
return -EINVAL;
case 66: /* Input data contains an illegal template field */ case 66: /* Input data contains an illegal template field */
case 67: /* Template indicates data past the end of the input stream */ case 67: /* Template indicates data past the end of the input stream */
dev_dbg(dev, "%s: Bad data for decompression (code:%d)\n", dev_dbg(dev, "%s: Bad data for decompression (code:%d)\n",
...@@ -324,7 +328,7 @@ static int nx842_pseries_compress(const unsigned char *in, unsigned int inlen, ...@@ -324,7 +328,7 @@ static int nx842_pseries_compress(const unsigned char *in, unsigned int inlen,
slout.entries = (struct nx842_slentry *)workmem->slout; slout.entries = (struct nx842_slentry *)workmem->slout;
/* Init operation */ /* Init operation */
op.flags = NX842_OP_COMPRESS; op.flags = NX842_OP_COMPRESS_CRC;
csbcpb = &workmem->csbcpb; csbcpb = &workmem->csbcpb;
memset(csbcpb, 0, sizeof(*csbcpb)); memset(csbcpb, 0, sizeof(*csbcpb));
op.csbcpb = nx842_get_pa(csbcpb); op.csbcpb = nx842_get_pa(csbcpb);
...@@ -457,7 +461,7 @@ static int nx842_pseries_decompress(const unsigned char *in, unsigned int inlen, ...@@ -457,7 +461,7 @@ static int nx842_pseries_decompress(const unsigned char *in, unsigned int inlen,
slout.entries = (struct nx842_slentry *)workmem->slout; slout.entries = (struct nx842_slentry *)workmem->slout;
/* Init operation */ /* Init operation */
op.flags = NX842_OP_DECOMPRESS; op.flags = NX842_OP_DECOMPRESS_CRC;
csbcpb = &workmem->csbcpb; csbcpb = &workmem->csbcpb;
memset(csbcpb, 0, sizeof(*csbcpb)); memset(csbcpb, 0, sizeof(*csbcpb));
op.csbcpb = nx842_get_pa(csbcpb); op.csbcpb = nx842_get_pa(csbcpb);
......
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/crc32.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/sw842.h> #include <linux/sw842.h>
...@@ -98,6 +99,7 @@ ...@@ -98,6 +99,7 @@
#define I2_BITS (8) #define I2_BITS (8)
#define I4_BITS (9) #define I4_BITS (9)
#define I8_BITS (8) #define I8_BITS (8)
#define CRC_BITS (32)
#define REPEAT_BITS_MAX (0x3f) #define REPEAT_BITS_MAX (0x3f)
#define SHORT_DATA_BITS_MAX (0x7) #define SHORT_DATA_BITS_MAX (0x7)
......
...@@ -490,6 +490,7 @@ int sw842_compress(const u8 *in, unsigned int ilen, ...@@ -490,6 +490,7 @@ int sw842_compress(const u8 *in, unsigned int ilen,
int ret; int ret;
u64 last, next, pad, total; u64 last, next, pad, total;
u8 repeat_count = 0; u8 repeat_count = 0;
u32 crc;
BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS); BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS);
...@@ -580,6 +581,18 @@ int sw842_compress(const u8 *in, unsigned int ilen, ...@@ -580,6 +581,18 @@ int sw842_compress(const u8 *in, unsigned int ilen,
if (ret) if (ret)
return ret; return ret;
/*
* crc(0:31) is appended to target data starting with the next
* bit after End of stream template.
* nx842 calculates CRC for data in big-endian format. So doing
* same here so that sw842 decompression can be used for both
* compressed data.
*/
crc = crc32_be(0, in, ilen);
ret = add_bits(p, crc, CRC_BITS);
if (ret)
return ret;
if (p->bit) { if (p->bit) {
p->out++; p->out++;
p->olen--; p->olen--;
......
...@@ -285,6 +285,7 @@ int sw842_decompress(const u8 *in, unsigned int ilen, ...@@ -285,6 +285,7 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
struct sw842_param p; struct sw842_param p;
int ret; int ret;
u64 op, rep, tmp, bytes, total; u64 op, rep, tmp, bytes, total;
u64 crc;
p.in = (u8 *)in; p.in = (u8 *)in;
p.bit = 0; p.bit = 0;
...@@ -375,6 +376,22 @@ int sw842_decompress(const u8 *in, unsigned int ilen, ...@@ -375,6 +376,22 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
} }
} while (op != OP_END); } while (op != OP_END);
/*
* crc(0:31) is saved in compressed data starting with the
* next bit after End of stream template.
*/
ret = next_bits(&p, &crc, CRC_BITS);
if (ret)
return ret;
/*
* Validate CRC saved in compressed data.
*/
if (crc != (u64)crc32_be(0, out, total - p.olen)) {
pr_debug("CRC mismatch for decompression\n");
return -EINVAL;
}
if (unlikely((total - p.olen) > UINT_MAX)) if (unlikely((total - p.olen) > UINT_MAX))
return -ENOSPC; return -ENOSPC;
......
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