crypto: 842 - Add CRC and validation support
authorHaren Myneni <haren@linux.vnet.ibm.com>
Thu, 8 Oct 2015 20:45:51 +0000 (13:45 -0700)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 14 Oct 2015 14:23:17 +0000 (22:23 +0800)
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: Haren Myneni <haren@us.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/nx/nx-842-powernv.c
drivers/crypto/nx/nx-842-pseries.c
lib/842/842.h
lib/842/842_compress.c
lib/842/842_decompress.c

index 3750e13d872181c425feefafbc259c03024b75e0..9ef51fafdbffaef11b800619818e10ae5f52cc17 100644 (file)
@@ -491,7 +491,7 @@ static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
                                  void *wmem)
 {
        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,
                                    void *wmem)
 {
        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)
index f4cbde03c6adda03c497f0ce08a358081f78d6d6..cddc6d8b55d9c63d974c0fdc8341518f70afb527 100644 (file)
@@ -234,6 +234,10 @@ static int nx842_validate_result(struct device *dev,
                dev_dbg(dev, "%s: Out of space in output buffer\n",
                                        __func__);
                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 67: /* Template indicates data past the end of the input stream */
                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,
        slout.entries = (struct nx842_slentry *)workmem->slout;
 
        /* Init operation */
-       op.flags = NX842_OP_COMPRESS;
+       op.flags = NX842_OP_COMPRESS_CRC;
        csbcpb = &workmem->csbcpb;
        memset(csbcpb, 0, sizeof(*csbcpb));
        op.csbcpb = nx842_get_pa(csbcpb);
@@ -457,7 +461,7 @@ static int nx842_pseries_decompress(const unsigned char *in, unsigned int inlen,
        slout.entries = (struct nx842_slentry *)workmem->slout;
 
        /* Init operation */
-       op.flags = NX842_OP_DECOMPRESS;
+       op.flags = NX842_OP_DECOMPRESS_CRC;
        csbcpb = &workmem->csbcpb;
        memset(csbcpb, 0, sizeof(*csbcpb));
        op.csbcpb = nx842_get_pa(csbcpb);
index 7c200030acf77a76740fbe9288cefe10058e87a8..e0a122bc1cdb06d25c686d5e7fb68c7217169e96 100644 (file)
@@ -76,6 +76,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
+#include <linux/crc32.h>
 #include <asm/unaligned.h>
 
 #include <linux/sw842.h>
@@ -98,6 +99,7 @@
 #define I2_BITS                (8)
 #define I4_BITS                (9)
 #define I8_BITS                (8)
+#define CRC_BITS       (32)
 
 #define REPEAT_BITS_MAX                (0x3f)
 #define SHORT_DATA_BITS_MAX    (0x7)
index 7ce68948e68c84d41c796c70a726895e65c68d78..4051339bdfbda6e6869d7f7c669672ba65f3d3f1 100644 (file)
@@ -490,6 +490,7 @@ int sw842_compress(const u8 *in, unsigned int ilen,
        int ret;
        u64 last, next, pad, total;
        u8 repeat_count = 0;
+       u32 crc;
 
        BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS);
 
@@ -580,6 +581,18 @@ skip_comp:
        if (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) {
                p->out++;
                p->olen--;
index 5446ff0c9ba0f186448cffc34942858dc1a7d0a9..8881dad2a6a086ac7ca7fdb86bf4d238ac21539a 100644 (file)
@@ -285,6 +285,7 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
        struct sw842_param p;
        int ret;
        u64 op, rep, tmp, bytes, total;
+       u64 crc;
 
        p.in = (u8 *)in;
        p.bit = 0;
@@ -375,6 +376,22 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
                }
        } 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))
                return -ENOSPC;