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

crypto: powerpc - Stress test for vpmsum implementations

vpmsum implementations often don't kick in for short test vectors.
This is a simple test module that does a configurable number of
random tests, each up to 64kB and each with random offsets.

Both CRC-T10DIF and CRC32C are tested.

Cc: Anton Blanchard <anton@samba.org>
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Daniel Axtens and committed by
Herbert Xu
146c8688 b01df1c1

+146
+1
arch/powerpc/crypto/Makefile
··· 11 11 obj-$(CONFIG_CRYPTO_SHA256_PPC_SPE) += sha256-ppc-spe.o 12 12 obj-$(CONFIG_CRYPTO_CRC32C_VPMSUM) += crc32c-vpmsum.o 13 13 obj-$(CONFIG_CRYPTO_CRCT10DIF_VPMSUM) += crct10dif-vpmsum.o 14 + obj-$(CONFIG_CRYPTO_VPMSUM_TESTER) += crc-vpmsum_test.o 14 15 15 16 aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o 16 17 md5-ppc-y := md5-asm.o md5-glue.o
+137
arch/powerpc/crypto/crc-vpmsum_test.c
··· 1 + /* 2 + * CRC vpmsum tester 3 + * Copyright 2017 Daniel Axtens, IBM Corporation. 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/crc-t10dif.h> 11 + #include <linux/crc32.h> 12 + #include <crypto/internal/hash.h> 13 + #include <linux/init.h> 14 + #include <linux/module.h> 15 + #include <linux/string.h> 16 + #include <linux/kernel.h> 17 + #include <linux/cpufeature.h> 18 + #include <asm/switch_to.h> 19 + 20 + static unsigned long iterations = 10000; 21 + 22 + #define MAX_CRC_LENGTH 65535 23 + 24 + 25 + static int __init crc_test_init(void) 26 + { 27 + u16 crc16 = 0, verify16 = 0; 28 + u32 crc32 = 0, verify32 = 0; 29 + __le32 verify32le = 0; 30 + unsigned char *data; 31 + unsigned long i; 32 + int ret; 33 + 34 + struct crypto_shash *crct10dif_tfm; 35 + struct crypto_shash *crc32c_tfm; 36 + 37 + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) 38 + return -ENODEV; 39 + 40 + data = kmalloc(MAX_CRC_LENGTH, GFP_KERNEL); 41 + if (!data) 42 + return -ENOMEM; 43 + 44 + crct10dif_tfm = crypto_alloc_shash("crct10dif", 0, 0); 45 + 46 + if (IS_ERR(crct10dif_tfm)) { 47 + pr_err("Error allocating crc-t10dif\n"); 48 + goto free_buf; 49 + } 50 + 51 + crc32c_tfm = crypto_alloc_shash("crc32c", 0, 0); 52 + 53 + if (IS_ERR(crc32c_tfm)) { 54 + pr_err("Error allocating crc32c\n"); 55 + goto free_16; 56 + } 57 + 58 + do { 59 + SHASH_DESC_ON_STACK(crct10dif_shash, crct10dif_tfm); 60 + SHASH_DESC_ON_STACK(crc32c_shash, crc32c_tfm); 61 + 62 + crct10dif_shash->tfm = crct10dif_tfm; 63 + ret = crypto_shash_init(crct10dif_shash); 64 + 65 + if (ret) { 66 + pr_err("Error initing crc-t10dif\n"); 67 + goto free_32; 68 + } 69 + 70 + 71 + crc32c_shash->tfm = crc32c_tfm; 72 + ret = crypto_shash_init(crc32c_shash); 73 + 74 + if (ret) { 75 + pr_err("Error initing crc32c\n"); 76 + goto free_32; 77 + } 78 + 79 + pr_info("crc-vpmsum_test begins, %lu iterations\n", iterations); 80 + for (i=0; i<iterations; i++) { 81 + size_t len, offset; 82 + 83 + get_random_bytes(data, MAX_CRC_LENGTH); 84 + get_random_bytes(&len, sizeof(len)); 85 + get_random_bytes(&offset, sizeof(offset)); 86 + 87 + len %= MAX_CRC_LENGTH; 88 + offset &= 15; 89 + if (len <= offset) 90 + continue; 91 + len -= offset; 92 + 93 + crypto_shash_update(crct10dif_shash, data+offset, len); 94 + crypto_shash_final(crct10dif_shash, (u8 *)(&crc16)); 95 + verify16 = crc_t10dif_generic(verify16, data+offset, len); 96 + 97 + 98 + if (crc16 != verify16) { 99 + pr_err("FAILURE in CRC16: got 0x%04x expected 0x%04x (len %lu)\n", 100 + crc16, verify16, len); 101 + break; 102 + } 103 + 104 + crypto_shash_update(crc32c_shash, data+offset, len); 105 + crypto_shash_final(crc32c_shash, (u8 *)(&crc32)); 106 + verify32 = le32_to_cpu(verify32le); 107 + verify32le = ~cpu_to_le32(__crc32c_le(~verify32, data+offset, len)); 108 + if (crc32 != (u32)verify32le) { 109 + pr_err("FAILURE in CRC32: got 0x%08x expected 0x%08x (len %lu)\n", 110 + crc32, verify32, len); 111 + break; 112 + } 113 + } 114 + pr_info("crc-vpmsum_test done, completed %lu iterations\n", i); 115 + } while (0); 116 + 117 + free_32: 118 + crypto_free_shash(crc32c_tfm); 119 + 120 + free_16: 121 + crypto_free_shash(crct10dif_tfm); 122 + 123 + free_buf: 124 + kfree(data); 125 + 126 + return 0; 127 + } 128 + 129 + static void __exit crc_test_exit(void) {} 130 + 131 + module_init(crc_test_init); 132 + module_exit(crc_test_exit); 133 + module_param(iterations, long, 0400); 134 + 135 + MODULE_AUTHOR("Daniel Axtens <dja@axtens.net>"); 136 + MODULE_DESCRIPTION("Vector polynomial multiply-sum CRC tester"); 137 + MODULE_LICENSE("GPL");
+8
crypto/Kconfig
··· 522 522 multiply-sum (vpmsum) instructions, introduced in POWER8. Enable on 523 523 POWER8 and newer processors for improved performance. 524 524 525 + config CRYPTO_VPMSUM_TESTER 526 + tristate "Powerpc64 vpmsum hardware acceleration tester" 527 + depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C_VPMSUM 528 + help 529 + Stress test for CRC32c and CRC-T10DIF algorithms implemented with 530 + POWER8 vpmsum instructions. 531 + Unless you are testing these algorithms, you don't need this. 532 + 525 533 config CRYPTO_GHASH 526 534 tristate "GHASH digest algorithm" 527 535 select CRYPTO_GF128MUL