// SPDX-License-Identifier: GPL-2.0-or-later/* * Algorithm testing framework and tests. * * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> * Copyright (c) 2007 Nokia Siemens Networks * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> * Copyright (c) 2019 Google LLC * * Updated RFC4106 AES-GCM testing. * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) * Adrian Hoban <adrian.hoban@intel.com> * Gabriele Paoloni <gabriele.paoloni@intel.com> * Tadeusz Struk (tadeusz.struk@intel.com) * Copyright (c) 2010, Intel Corporation. */ #include <crypto/aead.h>#include <crypto/hash.h>#include <crypto/skcipher.h>#include <linux/err.h>#include <linux/fips.h>#include <linux/module.h>#include <linux/once.h>#include <linux/prandom.h>#include <linux/scatterlist.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/uio.h>#include <crypto/akcipher.h>#include <crypto/kpp.h>#include <crypto/acompress.h>#include <crypto/sig.h>#include <crypto/internal/cipher.h>#include <crypto/internal/rng.h>#include <crypto/internal/simd.h> #include "internal.h" MODULE_IMPORT_NS("CRYPTO_INTERNAL"); static bool notests;module_param(notests, bool, 0644);MODULE_PARM_DESC(notests, "disable all crypto self-tests"); #ifdef CONFIG_CRYPTO_SELFTESTS_FULLstatic bool noslowtests;module_param(noslowtests, bool, 0644);MODULE_PARM_DESC(noslowtests, "disable slow crypto self-tests"); static unsigned int fuzz_iterations = 100;module_param(fuzz_iterations, uint, 0644);MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations");#else#define noslowtests 1#define fuzz_iterations 0#endif #ifndef CONFIG_CRYPTO_SELFTESTS /* a perfect nop */int alg_test(const char *driver, const char *alg, u32 type, u32 mask){ return 0;} #else #include "testmgr.h" /* * Need slab memory for testing (size in number of pages). */#define XBUFSIZE 8 /** Used by test_cipher()*/#define ENCRYPT 1#define DECRYPT 0 struct aead_test_suite { const struct aead_testvec *vecs; unsigned int count; /* * Set if trying to decrypt an inauthentic ciphertext with this * algorithm might result in EINVAL rather than EBADMSG, due to other * validation the algorithm does on the inputs such as length checks. */ unsigned int einval_allowed : 1; /* * Set if this algorithm requires that the IV be located at the end of * the AAD buffer, in addition to being given in the normal way. The * behavior when the two IV copies differ is implementation-defined. */ unsigned int aad_iv : 1;}; struct cipher_test_suite { const struct cipher_testvec *vecs; unsigned int count;}; struct comp_test_suite { struct { const struct comp_testvec *vecs; unsigned int count; } comp, decomp;}; struct hash_test_suite { const struct hash_testvec *vecs; unsigned int count;}; struct drbg_test_suite { const struct drbg_testvec *vecs; unsigned int count;}; struct akcipher_test_suite { const struct akcipher_testvec *vecs; unsigned int count;}; struct sig_test_suite { const struct sig_testvec *vecs; unsigned int count;}; struct kpp_test_suite { const struct kpp_testvec *vecs; unsigned int count;}; struct alg_test_desc { const char *alg; const char *generic_driver; int (*test)(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask); int fips_allowed; /* set if alg is allowed in fips mode */ union { struct aead_test_suite aead; struct cipher_test_suite cipher; struct comp_test_suite comp; struct hash_test_suite hash; struct drbg_test_suite drbg; struct akcipher_test_suite akcipher; struct sig_test_suite sig; struct kpp_test_suite kpp; } suite;}; static void hexdump(unsigned char *buf, unsigned int len){ print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, 16, 1, buf, len, false);} static int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order){ int i; for (i = 0; i < XBUFSIZE; i++) { buf[i] = (char *)__get_free_pages(GFP_KERNEL, order); if (!buf[i]) goto err_free_buf; } return 0; err_free_buf: while (i-- > 0) free_pages((unsigned long)buf[i], order); return -ENOMEM;} static int testmgr_alloc_buf(char *buf[XBUFSIZE]){ return __testmgr_alloc_buf(buf, 0);} static void __testmgr_free_buf(char *buf[XBUFSIZE], int order){ int i; for (i = 0; i < XBUFSIZE; i++) free_pages((unsigned long)buf[i], order);} static void testmgr_free_buf(char *buf[XBUFSIZE]){ __testmgr_free_buf(buf, 0);} #define TESTMGR_POISON_BYTE 0xfe#define TESTMGR_POISON_LEN 16 static inline void testmgr_poison(void *addr, size_t len){ memset(addr, TESTMGR_POISON_BYTE, len);} /* Is the memory region still fully poisoned? */static inline bool testmgr_is_poison(const void *addr, size_t len){ return memchr_inv(addr, TESTMGR_POISON_BYTE, len) == NULL;} /* flush type for hash algorithms */enum flush_type { /* merge with update of previous buffer(s) */ FLUSH_TYPE_NONE = 0, /* update with previous buffer(s) before doing this one */ FLUSH_TYPE_FLUSH, /* likewise, but also export and re-import the intermediate state */ FLUSH_TYPE_REIMPORT,}; /* finalization function for hash algorithms */enum finalization_type { FINALIZATION_TYPE_FINAL, /* use final() */ FINALIZATION_TYPE_FINUP, /* use finup() */ FINALIZATION_TYPE_DIGEST, /* use digest() */}; /* * Whether the crypto operation will occur in-place, and if so whether the * source and destination scatterlist pointers will coincide (req->src == * req->dst), or whether they'll merely point to two separate scatterlists * (req->src != req->dst) that reference the same underlying memory. * * This is only relevant for algorithm types that support in-place operation. */enum inplace_mode { OUT_OF_PLACE, INPLACE_ONE_SGLIST, INPLACE_TWO_SGLISTS,}; #define TEST_SG_TOTAL 10000 /** * struct test_sg_division - description of a scatterlist entry * * This struct describes one entry of a scatterlist being constructed to check a * crypto test vector. * * @proportion_of_total: length of this chunk relative to the total length, * given as a proportion out of TEST_SG_TOTAL so that it * scales to fit any test vector * @offset: byte offset into a 2-page buffer at which this chunk will start * @offset_relative_to_alignmask: if true, add the algorithm's alignmask to the * @offset * @flush_type: for hashes, whether an update() should be done now vs. * continuing to accumulate data * @nosimd: if doing the pending update(), do it with SIMD disabled? */struct test_sg_division { unsigned int proportion_of_total; unsigned int offset; bool offset_relative_to_alignmask; enum flush_type flush_type; bool nosimd;}; /** * struct testvec_config - configuration for testing a crypto test vector * * This struct describes the data layout and other parameters with which each * crypto test vector can be tested. * * @name: name of this config, logged for debugging purposes if a test fails * @inplace_mode: whether and how to operate on the data in-place, if applicable * @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP * @src_divs: description of how to arrange the source scatterlist * @dst_divs: description of how to arrange the dst scatterlist, if applicable * for the algorithm type. Defaults to @src_divs if unset. * @iv_offset: misalignment of the IV in the range [0..MAX_ALGAPI_ALIGNMASK+1], * where 0 is aligned to a 2*(MAX_ALGAPI_ALIGNMASK+1) byte boundary * @iv_offset_relative_to_alignmask: if true, add the algorithm's alignmask to * the @iv_offset * @key_offset: misalignment of the key, where 0 is default alignment * @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to * the @key_offset * @finalization_type: what finalization function to use for hashes * @nosimd: execute with SIMD disabled? Requires !CRYPTO_TFM_REQ_MAY_SLEEP. * This applies to the parts of the operation that aren't controlled * individually by @nosimd_setkey or @src_divs[].nosimd. * @nosimd_setkey: set the key (if applicable) with SIMD disabled? Requires * !CRYPTO_TFM_REQ_MAY_SLEEP. */struct testvec_config { const char *name; enum inplace_mode inplace_mode; u32 req_flags; struct test_sg_division src_divs[XBUFSIZE]; struct test_sg_division dst_divs[XBUFSIZE]; unsigned int iv_offset; unsigned int key_offset; bool iv_offset_relative_to_alignmask; bool key_offset_relative_to_alignmask; enum finalization_type finalization_type; bool nosimd; bool nosimd_setkey;}; #define TESTVEC_CONFIG_NAMELEN 192 /* * The following are the lists of testvec_configs to test for each algorithm * type when the "fast" crypto self-tests are enabled. They aim to provide good * test coverage, while keeping the test time much shorter than the "full" tests * so that the "fast" tests can be enabled in a wider range of circumstances. */ /* Configs for skciphers and aeads */static const struct testvec_config default_cipher_testvec_configs[] = { { .name = "in-place (one sglist)", .inplace_mode = INPLACE_ONE_SGLIST, .src_divs = { { .proportion_of_total = 10000 } }, }, { .name = "in-place (two sglists)", .inplace_mode = INPLACE_TWO_SGLISTS, .src_divs = { { .proportion_of_total = 10000 } }, }, { .name = "out-of-place", .inplace_mode = OUT_OF_PLACE, .src_divs = { { .proportion_of_total = 10000 } }, }, { .name = "unaligned buffer, offset=1", .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, .iv_offset = 1, .key_offset = 1, }, { .name = "buffer aligned only to alignmask", .src_divs = { { .proportion_of_total = 10000, .offset = 1, .offset_relative_to_alignmask = true, }, }, .iv_offset = 1, .iv_offset_relative_to_alignmask = true, .key_offset = 1, .key_offset_relative_to_alignmask = true, }, { .name = "two even aligned splits", .src_divs = { { .proportion_of_total = 5000 }, { .proportion_of_total = 5000 }, }, }, { .name = "one src, two even splits dst", .inplace_mode = OUT_OF_PLACE, .src_divs = { { .proportion_of_total = 10000 } }, .dst_divs = { { .proportion_of_total = 5000 }, { .proportion_of_total = 5000 }, }, }, { .name = "uneven misaligned splits, may sleep", .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, .src_divs = { { .proportion_of_total = 1900, .offset = 33 }, { .proportion_of_total = 3300, .offset = 7 }, { .proportion_of_total = 4800, .offset = 18 }, }, .iv_offset = 3, .key_offset = 3, }, { .name = "misaligned splits crossing pages, inplace", .inplace_mode = INPLACE_ONE_SGLIST, .src_divs = { { .proportion_of_total = 7500, .offset = PAGE_SIZE - 32 }, { .proportion_of_total = 2500, .offset = PAGE_SIZE - 7 }, }, }}; static const struct testvec_config default_hash_testvec_configs[] = { { .name = "init+update+final aligned buffer", .src_divs = { { .proportion_of_total = 10000 } }, .finalization_type = FINALIZATION_TYPE_FINAL, }, { .name = "init+finup aligned buffer", .src_divs = { { .proportion_of_total = 10000 } }, .finalization_type = FINALIZATION_TYPE_FINUP, }, { .name = "digest aligned buffer", .src_divs = { { .proportion_of_total = 10000 } }, .finalization_type = FINALIZATION_TYPE_DIGEST, }, { .name = "init+update+final misaligned buffer", .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, .finalization_type = FINALIZATION_TYPE_FINAL, .key_offset = 1, }, { .name = "digest misaligned buffer", .src_divs = { { .proportion_of_total = 10000, .offset = 1, }, }, .finalization_type = FINALIZATION_TYPE_DIGEST, .key_offset = 1, }, { .name = "init+update+update+final two even splits", .src_divs = { { .proportion_of_total = 5000 }, { .proportion_of_total = 5000, .flush_type = FLUSH_TYPE_FLUSH, }, }, .finalization_type = FINALIZATION_TYPE_FINAL, }, { .name = "digest uneven misaligned splits, may sleep", .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, .src_divs = { { .proportion_of_total = 1900, .offset = 33 }, { .proportion_of_total = 3300, .offset = 7 }, { .proportion_of_total = 4800, .offset = 18 }, }, .finalization_type = FINALIZATION_TYPE_DIGEST, }, { .name = "digest misaligned splits crossing pages", .src_divs = { { .proportion_of_total = 7500, .offset = PAGE_SIZE - 32, }, { .proportion_of_total = 2500, .offset = PAGE_SIZE - 7, }, }, .finalization_type = FINALIZATION_TYPE_DIGEST, }, { .name = "import/export", .src_divs = { { .proportion_of_total = 6500, .flush_type = FLUSH_TYPE_REIMPORT, }, { .proportion_of_total = 3500, .flush_type = FLUSH_TYPE_REIMPORT, }, }, .finalization_type = FINALIZATION_TYPE_FINAL, }}; static unsigned int count_test_sg_divisions(const struct test_sg_division *divs){ unsigned int remaining = TEST_SG_TOTAL; unsigned int ndivs = 0; do { remaining -= divs[ndivs++].proportion_of_total; } while (remaining); return ndivs;} #define SGDIVS_HAVE_FLUSHES BIT(0)#define SGDIVS_HAVE_NOSIMD BIT(1) static bool valid_sg_divisions(const struct test_sg_division *divs, unsigned int count, int *flags_ret){ unsigned int total = 0; unsigned int i; for (i = 0; i < count && total != TEST_SG_TOTAL; i++) { if (divs[i].proportion_of_total <= 0 || divs[i].proportion_of_total > TEST_SG_TOTAL - total) return false; total += divs[i].proportion_of_total; if (divs[i].flush_type != FLUSH_TYPE_NONE) *flags_ret |= SGDIVS_HAVE_FLUSHES; if (divs[i].nosimd) *flags_ret |= SGDIVS_HAVE_NOSIMD; }Lines 1–500 of 5722. Load more
// SPDX-License-Identifier: GPL-2.0-or-later /* * Algorithm testing framework and tests. * * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> * Copyright (c) 2007 Nokia Siemens Networks * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> * Copyright (c) 2019 Google LLC * * Updated RFC4106 AES-GCM testing. * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) * Adrian Hoban <adrian.hoban@intel.com> * Gabriele Paoloni <gabriele.paoloni@intel.com> * Tadeusz Struk (tadeusz.struk@intel.com) * Copyright (c) 2010, Intel Corporation. */ #include <crypto/aead.h> #include <crypto/hash.h> #include <crypto/skcipher.h> #include <linux/err.h> #include <linux/fips.h> #include <linux/module.h> #include <linux/once.h> #include <linux/prandom.h> #include <linux/scatterlist.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/uio.h> #include <crypto/akcipher.h> #include <crypto/kpp.h> #include <crypto/acompress.h> #include <crypto/sig.h> #include <crypto/internal/cipher.h> #include <crypto/internal/rng.h> #include <crypto/internal/simd.h> #include "internal.h" MODULE_IMPORT_NS("CRYPTO_INTERNAL"); static bool notests; module_param(notests, bool, 0644); MODULE_PARM_DESC(notests, "disable all crypto self-tests"); #ifdef CONFIG_CRYPTO_SELFTESTS_FULL static bool noslowtests; module_param(noslowtests, bool, 0644); MODULE_PARM_DESC(noslowtests, "disable slow crypto self-tests"); static unsigned int fuzz_iterations = 100; module_param(fuzz_iterations, uint, 0644); MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); #else #define noslowtests 1 #define fuzz_iterations 0 #endif #ifndef CONFIG_CRYPTO_SELFTESTS /* a perfect nop */ int alg_test(const char *driver, const char *alg, u32 type, u32 mask) { return 0; } #else #include "testmgr.h" /* * Need slab memory for testing (size in number of pages). */ #define XBUFSIZE 8 /* * Used by test_cipher() */ #define ENCRYPT 1 #define DECRYPT 0 struct aead_test_suite { const struct aead_testvec *vecs; unsigned int count; /* * Set if trying to decrypt an inauthentic ciphertext with this * algorithm might result in EINVAL rather than EBADMSG, due to other * validation the algorithm does on the inputs such as length checks. */ unsigned int einval_allowed : 1; /* * Set if this algorithm requires that the IV be located at the end of * the AAD buffer, in addition to being given in the normal way. The * behavior when the two IV copies differ is implementation-defined. */ unsigned int aad_iv : 1; }; struct cipher_test_suite { const struct cipher_testvec *vecs; unsigned int count; }; struct comp_test_suite { struct { const struct comp_testvec *vecs; unsigned int count; } comp, decomp; }; struct hash_test_suite { const struct hash_testvec *vecs; unsigned int count; }; struct drbg_test_suite { const struct drbg_testvec *vecs; unsigned int count; }; struct akcipher_test_suite { const struct akcipher_testvec *vecs; unsigned int count; }; struct sig_test_suite { const struct sig_testvec *vecs; unsigned int count; }; struct kpp_test_suite { const struct kpp_testvec *vecs; unsigned int count; }; struct alg_test_desc { const char *alg; const char *generic_driver; int (*test)(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask); int fips_allowed; /* set if alg is allowed in fips mode */ union { struct aead_test_suite aead; struct cipher_test_suite cipher; struct comp_test_suite comp; struct hash_test_suite hash; struct drbg_test_suite drbg; struct akcipher_test_suite akcipher; struct sig_test_suite sig; struct kpp_test_suite kpp; } suite; }; static void hexdump(unsigned char *buf, unsigned int len) { print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, 16, 1, buf, len, false); } static int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order) { int i; for (i = 0; i < XBUFSIZE; i++) { buf[i] = (char *)__get_free_pages(GFP_KERNEL, order); if (!buf[i]) goto err_free_buf; } return 0; err_free_buf: while (i-- > 0) free_pages((unsigned long)buf[i], order); return -ENOMEM; } static int testmgr_alloc_buf(char *buf[XBUFSIZE]) { return __testmgr_alloc_buf(buf, 0); } static void __testmgr_free_buf(char *buf[XBUFSIZE], int order) { int i; for (i = 0; i < XBUFSIZE; i++) free_pages((unsigned long)buf[i], order); } static void testmgr_free_buf(char *buf[XBUFSIZE]) { __testmgr_free_buf(buf, 0); } #define TESTMGR_POISON_BYTE 0xfe #define TESTMGR_POISON_LEN 16 static inline void testmgr_poison(void *addr, size_t len) { memset(addr, TESTMGR_POISON_BYTE, len); } /* Is the memory region still fully poisoned? */ static inline bool testmgr_is_poison(const void *addr, size_t len) { return memchr_inv(addr, TESTMGR_POISON_BYTE, len) == NULL; } /* flush type for hash algorithms */ enum flush_type { /* merge with update of previous buffer(s) */ FLUSH_TYPE_NONE = 0, /* update with previous buffer(s) before doing this one */ FLUSH_TYPE_FLUSH, /* likewise, but also export and re-import the intermediate state */ FLUSH_TYPE_REIMPORT, }; /* finalization function for hash algorithms */ enum finalization_type { FINALIZATION_TYPE_FINAL, /* use final() */ FINALIZATION_TYPE_FINUP, /* use finup() */ FINALIZATION_TYPE_DIGEST, /* use digest() */ }; /* * Whether the crypto operation will occur in-place, and if so whether the * source and destination scatterlist pointers will coincide (req->src == * req->dst), or whether they'll merely point to two separate scatterlists * (req->src != req->dst) that reference the same underlying memory. * * This is only relevant for algorithm types that support in-place operation. */ enum inplace_mode { OUT_OF_PLACE, INPLACE_ONE_SGLIST, INPLACE_TWO_SGLISTS, }; #define TEST_SG_TOTAL 10000 /** * struct test_sg_division - description of a scatterlist entry * * This struct describes one entry of a scatterlist being constructed to check a * crypto test vector. * * @proportion_of_total: length of this chunk relative to the total length, * given as a proportion out of TEST_SG_TOTAL so that it * scales to fit any test vector * @offset: byte offset into a 2-page buffer at which this chunk will start * @offset_relative_to_alignmask: if true, add the algorithm's alignmask to the * @offset * @flush_type: for hashes, whether an update() should be done now vs. * continuing to accumulate data * @nosimd: if doing the pending update(), do it with SIMD disabled? */ struct test_sg_division { unsigned int proportion_of_total; unsigned int offset; bool offset_relative_to_alignmask; enum flush_type flush_type; bool nosimd; }; /** * struct testvec_config - configuration for testing a crypto test vector * * This struct describes the data layout and other parameters with which each * crypto test vector can be tested. * * @name: name of this config, logged for debugging purposes if a test fails * @inplace_mode: whether and how to operate on the data in-place, if applicable * @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP * @src_divs: description of how to arrange the source scatterlist * @dst_divs: description of how to arrange the dst scatterlist, if applicable * for the algorithm type. Defaults to @src_divs if unset. * @iv_offset: misalignment of the IV in the range [0..MAX_ALGAPI_ALIGNMASK+1], * where 0 is aligned to a 2*(MAX_ALGAPI_ALIGNMASK+1) byte boundary * @iv_offset_relative_to_alignmask: if true, add the algorithm's alignmask to * the @iv_offset * @key_offset: misalignment of the key, where 0 is default alignment * @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to * the @key_offset * @finalization_type: what finalization function to use for hashes * @nosimd: execute with SIMD disabled? Requires !CRYPTO_TFM_REQ_MAY_SLEEP. * This applies to the parts of the operation that aren't controlled * individually by @nosimd_setkey or @src_divs[].nosimd. * @nosimd_setkey: set the key (if applicable) with SIMD disabled? Requires * !CRYPTO_TFM_REQ_MAY_SLEEP. */ struct testvec_config { const char *name; enum inplace_mode inplace_mode; u32 req_flags; struct test_sg_division src_divs[XBUFSIZE]; struct test_sg_division dst_divs[XBUFSIZE]; unsigned int iv_offset; unsigned int key_offset; bool iv_offset_relative_to_alignmask; bool key_offset_relative_to_alignmask; enum finalization_type finalization_type; bool nosimd; bool nosimd_setkey; }; #define TESTVEC_CONFIG_NAMELEN 192 /* * The following are the lists of testvec_configs to test for each algorithm * type when the "fast" crypto self-tests are enabled. They aim to provide good * test coverage, while keeping the test time much shorter than the "full" tests * so that the "fast" tests can be enabled in a wider range of circumstances. */ /* Configs for skciphers and aeads */ static const struct testvec_config default_cipher_testvec_configs[] = { { .name = "in-place (one sglist)", .inplace_mode = INPLACE_ONE_SGLIST, .src_divs = { { .proportion_of_total = 10000 } }, }, { .name = "in-place (two sglists)", .inplace_mode = INPLACE_TWO_SGLISTS, .src_divs = { { .proportion_of_total = 10000 } }, }, { .name = "out-of-place", .inplace_mode = OUT_OF_PLACE, .src_divs = { { .proportion_of_total = 10000 } }, }, { .name = "unaligned buffer, offset=1", .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, .iv_offset = 1, .key_offset = 1, }, { .name = "buffer aligned only to alignmask", .src_divs = { { .proportion_of_total = 10000, .offset = 1, .offset_relative_to_alignmask = true, }, }, .iv_offset = 1, .iv_offset_relative_to_alignmask = true, .key_offset = 1, .key_offset_relative_to_alignmask = true, }, { .name = "two even aligned splits", .src_divs = { { .proportion_of_total = 5000 }, { .proportion_of_total = 5000 }, }, }, { .name = "one src, two even splits dst", .inplace_mode = OUT_OF_PLACE, .src_divs = { { .proportion_of_total = 10000 } }, .dst_divs = { { .proportion_of_total = 5000 }, { .proportion_of_total = 5000 }, }, }, { .name = "uneven misaligned splits, may sleep", .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, .src_divs = { { .proportion_of_total = 1900, .offset = 33 }, { .proportion_of_total = 3300, .offset = 7 }, { .proportion_of_total = 4800, .offset = 18 }, }, .iv_offset = 3, .key_offset = 3, }, { .name = "misaligned splits crossing pages, inplace", .inplace_mode = INPLACE_ONE_SGLIST, .src_divs = { { .proportion_of_total = 7500, .offset = PAGE_SIZE - 32 }, { .proportion_of_total = 2500, .offset = PAGE_SIZE - 7 }, }, } }; static const struct testvec_config default_hash_testvec_configs[] = { { .name = "init+update+final aligned buffer", .src_divs = { { .proportion_of_total = 10000 } }, .finalization_type = FINALIZATION_TYPE_FINAL, }, { .name = "init+finup aligned buffer", .src_divs = { { .proportion_of_total = 10000 } }, .finalization_type = FINALIZATION_TYPE_FINUP, }, { .name = "digest aligned buffer", .src_divs = { { .proportion_of_total = 10000 } }, .finalization_type = FINALIZATION_TYPE_DIGEST, }, { .name = "init+update+final misaligned buffer", .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, .finalization_type = FINALIZATION_TYPE_FINAL, .key_offset = 1, }, { .name = "digest misaligned buffer", .src_divs = { { .proportion_of_total = 10000, .offset = 1, }, }, .finalization_type = FINALIZATION_TYPE_DIGEST, .key_offset = 1, }, { .name = "init+update+update+final two even splits", .src_divs = { { .proportion_of_total = 5000 }, { .proportion_of_total = 5000, .flush_type = FLUSH_TYPE_FLUSH, }, }, .finalization_type = FINALIZATION_TYPE_FINAL, }, { .name = "digest uneven misaligned splits, may sleep", .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, .src_divs = { { .proportion_of_total = 1900, .offset = 33 }, { .proportion_of_total = 3300, .offset = 7 }, { .proportion_of_total = 4800, .offset = 18 }, }, .finalization_type = FINALIZATION_TYPE_DIGEST, }, { .name = "digest misaligned splits crossing pages", .src_divs = { { .proportion_of_total = 7500, .offset = PAGE_SIZE - 32, }, { .proportion_of_total = 2500, .offset = PAGE_SIZE - 7, }, }, .finalization_type = FINALIZATION_TYPE_DIGEST, }, { .name = "import/export", .src_divs = { { .proportion_of_total = 6500, .flush_type = FLUSH_TYPE_REIMPORT, }, { .proportion_of_total = 3500, .flush_type = FLUSH_TYPE_REIMPORT, }, }, .finalization_type = FINALIZATION_TYPE_FINAL, } }; static unsigned int count_test_sg_divisions(const struct test_sg_division *divs) { unsigned int remaining = TEST_SG_TOTAL; unsigned int ndivs = 0; do { remaining -= divs[ndivs++].proportion_of_total; } while (remaining); return ndivs; } #define SGDIVS_HAVE_FLUSHES BIT(0) #define SGDIVS_HAVE_NOSIMD BIT(1) static bool valid_sg_divisions(const struct test_sg_division *divs, unsigned int count, int *flags_ret) { unsigned int total = 0; unsigned int i; for (i = 0; i < count && total != TEST_SG_TOTAL; i++) { if (divs[i].proportion_of_total <= 0 || divs[i].proportion_of_total > TEST_SG_TOTAL - total) return false; total += divs[i].proportion_of_total; if (divs[i].flush_type != FLUSH_TYPE_NONE) *flags_ret |= SGDIVS_HAVE_FLUSHES; if (divs[i].nosimd) *flags_ret |= SGDIVS_HAVE_NOSIMD; }