Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Haren Myneni and committed by
Herbert Xu
ea0b3984 f5128432

+40 -4
+2 -2
drivers/crypto/nx/nx-842-powernv.c
··· 491 491 void *wmem) 492 492 { 493 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 519 void *wmem) 520 520 { 521 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 525 525 static int __init nx842_powernv_probe(struct device_node *dn)
+6 -2
drivers/crypto/nx/nx-842-pseries.c
··· 234 234 dev_dbg(dev, "%s: Out of space in output buffer\n", 235 235 __func__); 236 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 241 case 66: /* Input data contains an illegal template field */ 238 242 case 67: /* Template indicates data past the end of the input stream */ 239 243 dev_dbg(dev, "%s: Bad data for decompression (code:%d)\n", ··· 328 324 slout.entries = (struct nx842_slentry *)workmem->slout; 329 325 330 326 /* Init operation */ 331 - op.flags = NX842_OP_COMPRESS; 327 + op.flags = NX842_OP_COMPRESS_CRC; 332 328 csbcpb = &workmem->csbcpb; 333 329 memset(csbcpb, 0, sizeof(*csbcpb)); 334 330 op.csbcpb = nx842_get_pa(csbcpb); ··· 461 457 slout.entries = (struct nx842_slentry *)workmem->slout; 462 458 463 459 /* Init operation */ 464 - op.flags = NX842_OP_DECOMPRESS; 460 + op.flags = NX842_OP_DECOMPRESS_CRC; 465 461 csbcpb = &workmem->csbcpb; 466 462 memset(csbcpb, 0, sizeof(*csbcpb)); 467 463 op.csbcpb = nx842_get_pa(csbcpb);
+2
lib/842/842.h
··· 76 76 #include <linux/module.h> 77 77 #include <linux/kernel.h> 78 78 #include <linux/bitops.h> 79 + #include <linux/crc32.h> 79 80 #include <asm/unaligned.h> 80 81 81 82 #include <linux/sw842.h> ··· 99 98 #define I2_BITS (8) 100 99 #define I4_BITS (9) 101 100 #define I8_BITS (8) 101 + #define CRC_BITS (32) 102 102 103 103 #define REPEAT_BITS_MAX (0x3f) 104 104 #define SHORT_DATA_BITS_MAX (0x7)
+13
lib/842/842_compress.c
··· 490 490 int ret; 491 491 u64 last, next, pad, total; 492 492 u8 repeat_count = 0; 493 + u32 crc; 493 494 494 495 BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS); 495 496 ··· 578 577 } 579 578 580 579 ret = add_end_template(p); 580 + if (ret) 581 + return ret; 582 + 583 + /* 584 + * crc(0:31) is appended to target data starting with the next 585 + * bit after End of stream template. 586 + * nx842 calculates CRC for data in big-endian format. So doing 587 + * same here so that sw842 decompression can be used for both 588 + * compressed data. 589 + */ 590 + crc = crc32_be(0, in, ilen); 591 + ret = add_bits(p, crc, CRC_BITS); 581 592 if (ret) 582 593 return ret; 583 594
+17
lib/842/842_decompress.c
··· 285 285 struct sw842_param p; 286 286 int ret; 287 287 u64 op, rep, tmp, bytes, total; 288 + u64 crc; 288 289 289 290 p.in = (u8 *)in; 290 291 p.bit = 0; ··· 375 374 break; 376 375 } 377 376 } while (op != OP_END); 377 + 378 + /* 379 + * crc(0:31) is saved in compressed data starting with the 380 + * next bit after End of stream template. 381 + */ 382 + ret = next_bits(&p, &crc, CRC_BITS); 383 + if (ret) 384 + return ret; 385 + 386 + /* 387 + * Validate CRC saved in compressed data. 388 + */ 389 + if (crc != (u64)crc32_be(0, out, total - p.olen)) { 390 + pr_debug("CRC mismatch for decompression\n"); 391 + return -EINVAL; 392 + } 378 393 379 394 if (unlikely((total - p.olen) > UINT_MAX)) 380 395 return -ENOSPC;