aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaren Myneni <haren@linux.vnet.ibm.com>2015-10-08 16:45:51 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-10-14 10:23:17 -0400
commitea0b3984c1cc8b28de27a3bec285102b4e366a4c (patch)
treeb0134466a5b790d4091dc16065257a00ea24bf00
parentf5128432b08c3e263e1a7ce709d686b1ded51131 (diff)
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: Haren Myneni <haren@us.ibm.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/nx/nx-842-powernv.c4
-rw-r--r--drivers/crypto/nx/nx-842-pseries.c8
-rw-r--r--lib/842/842.h2
-rw-r--r--lib/842/842_compress.c13
-rw-r--r--lib/842/842_decompress.c17
5 files changed, 40 insertions, 4 deletions
diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c
index 3750e13d8721..9ef51fafdbff 100644
--- a/drivers/crypto/nx/nx-842-powernv.c
+++ b/drivers/crypto/nx/nx-842-powernv.c
@@ -491,7 +491,7 @@ static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
491 void *wmem) 491 void *wmem)
492{ 492{
493 return nx842_powernv_function(in, inlen, out, outlenp, 493 return nx842_powernv_function(in, inlen, out, outlenp,
494 wmem, CCW_FC_842_COMP_NOCRC); 494 wmem, CCW_FC_842_COMP_CRC);
495} 495}
496 496
497/** 497/**
@@ -519,7 +519,7 @@ static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
519 void *wmem) 519 void *wmem)
520{ 520{
521 return nx842_powernv_function(in, inlen, out, outlenp, 521 return nx842_powernv_function(in, inlen, out, outlenp,
522 wmem, CCW_FC_842_DECOMP_NOCRC); 522 wmem, CCW_FC_842_DECOMP_CRC);
523} 523}
524 524
525static int __init nx842_powernv_probe(struct device_node *dn) 525static int __init nx842_powernv_probe(struct device_node *dn)
diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c
index f4cbde03c6ad..cddc6d8b55d9 100644
--- a/drivers/crypto/nx/nx-842-pseries.c
+++ b/drivers/crypto/nx/nx-842-pseries.c
@@ -234,6 +234,10 @@ static int nx842_validate_result(struct device *dev,
234 dev_dbg(dev, "%s: Out of space in output buffer\n", 234 dev_dbg(dev, "%s: Out of space in output buffer\n",
235 __func__); 235 __func__);
236 return -ENOSPC; 236 return -ENOSPC;
237 case 65: /* Calculated CRC doesn't match the passed value */
238 dev_dbg(dev, "%s: CRC mismatch for decompression\n",
239 __func__);
240 return -EINVAL;
237 case 66: /* Input data contains an illegal template field */ 241 case 66: /* Input data contains an illegal template field */
238 case 67: /* Template indicates data past the end of the input stream */ 242 case 67: /* Template indicates data past the end of the input stream */
239 dev_dbg(dev, "%s: Bad data for decompression (code:%d)\n", 243 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 slout.entries = (struct nx842_slentry *)workmem->slout; 328 slout.entries = (struct nx842_slentry *)workmem->slout;
325 329
326 /* Init operation */ 330 /* Init operation */
327 op.flags = NX842_OP_COMPRESS; 331 op.flags = NX842_OP_COMPRESS_CRC;
328 csbcpb = &workmem->csbcpb; 332 csbcpb = &workmem->csbcpb;
329 memset(csbcpb, 0, sizeof(*csbcpb)); 333 memset(csbcpb, 0, sizeof(*csbcpb));
330 op.csbcpb = nx842_get_pa(csbcpb); 334 op.csbcpb = nx842_get_pa(csbcpb);
@@ -457,7 +461,7 @@ static int nx842_pseries_decompress(const unsigned char *in, unsigned int inlen,
457 slout.entries = (struct nx842_slentry *)workmem->slout; 461 slout.entries = (struct nx842_slentry *)workmem->slout;
458 462
459 /* Init operation */ 463 /* Init operation */
460 op.flags = NX842_OP_DECOMPRESS; 464 op.flags = NX842_OP_DECOMPRESS_CRC;
461 csbcpb = &workmem->csbcpb; 465 csbcpb = &workmem->csbcpb;
462 memset(csbcpb, 0, sizeof(*csbcpb)); 466 memset(csbcpb, 0, sizeof(*csbcpb));
463 op.csbcpb = nx842_get_pa(csbcpb); 467 op.csbcpb = nx842_get_pa(csbcpb);
diff --git a/lib/842/842.h b/lib/842/842.h
index 7c200030acf7..e0a122bc1cdb 100644
--- a/lib/842/842.h
+++ b/lib/842/842.h
@@ -76,6 +76,7 @@
76#include <linux/module.h> 76#include <linux/module.h>
77#include <linux/kernel.h> 77#include <linux/kernel.h>
78#include <linux/bitops.h> 78#include <linux/bitops.h>
79#include <linux/crc32.h>
79#include <asm/unaligned.h> 80#include <asm/unaligned.h>
80 81
81#include <linux/sw842.h> 82#include <linux/sw842.h>
@@ -98,6 +99,7 @@
98#define I2_BITS (8) 99#define I2_BITS (8)
99#define I4_BITS (9) 100#define I4_BITS (9)
100#define I8_BITS (8) 101#define I8_BITS (8)
102#define CRC_BITS (32)
101 103
102#define REPEAT_BITS_MAX (0x3f) 104#define REPEAT_BITS_MAX (0x3f)
103#define SHORT_DATA_BITS_MAX (0x7) 105#define SHORT_DATA_BITS_MAX (0x7)
diff --git a/lib/842/842_compress.c b/lib/842/842_compress.c
index 7ce68948e68c..4051339bdfbd 100644
--- a/lib/842/842_compress.c
+++ b/lib/842/842_compress.c
@@ -490,6 +490,7 @@ int sw842_compress(const u8 *in, unsigned int ilen,
490 int ret; 490 int ret;
491 u64 last, next, pad, total; 491 u64 last, next, pad, total;
492 u8 repeat_count = 0; 492 u8 repeat_count = 0;
493 u32 crc;
493 494
494 BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS); 495 BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS);
495 496
@@ -580,6 +581,18 @@ skip_comp:
580 if (ret) 581 if (ret)
581 return ret; 582 return ret;
582 583
584 /*
585 * crc(0:31) is appended to target data starting with the next
586 * bit after End of stream template.
587 * nx842 calculates CRC for data in big-endian format. So doing
588 * same here so that sw842 decompression can be used for both
589 * compressed data.
590 */
591 crc = crc32_be(0, in, ilen);
592 ret = add_bits(p, crc, CRC_BITS);
593 if (ret)
594 return ret;
595
583 if (p->bit) { 596 if (p->bit) {
584 p->out++; 597 p->out++;
585 p->olen--; 598 p->olen--;
diff --git a/lib/842/842_decompress.c b/lib/842/842_decompress.c
index 5446ff0c9ba0..8881dad2a6a0 100644
--- a/lib/842/842_decompress.c
+++ b/lib/842/842_decompress.c
@@ -285,6 +285,7 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
285 struct sw842_param p; 285 struct sw842_param p;
286 int ret; 286 int ret;
287 u64 op, rep, tmp, bytes, total; 287 u64 op, rep, tmp, bytes, total;
288 u64 crc;
288 289
289 p.in = (u8 *)in; 290 p.in = (u8 *)in;
290 p.bit = 0; 291 p.bit = 0;
@@ -375,6 +376,22 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
375 } 376 }
376 } while (op != OP_END); 377 } while (op != OP_END);
377 378
379 /*
380 * crc(0:31) is saved in compressed data starting with the
381 * next bit after End of stream template.
382 */
383 ret = next_bits(&p, &crc, CRC_BITS);
384 if (ret)
385 return ret;
386
387 /*
388 * Validate CRC saved in compressed data.
389 */
390 if (crc != (u64)crc32_be(0, out, total - p.olen)) {
391 pr_debug("CRC mismatch for decompression\n");
392 return -EINVAL;
393 }
394
378 if (unlikely((total - p.olen) > UINT_MAX)) 395 if (unlikely((total - p.olen) > UINT_MAX))
379 return -ENOSPC; 396 return -ENOSPC;
380 397