162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Algorithm testing framework and tests. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 662306a36Sopenharmony_ci * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> 762306a36Sopenharmony_ci * Copyright (c) 2007 Nokia Siemens Networks 862306a36Sopenharmony_ci * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> 962306a36Sopenharmony_ci * Copyright (c) 2019 Google LLC 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Updated RFC4106 AES-GCM testing. 1262306a36Sopenharmony_ci * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) 1362306a36Sopenharmony_ci * Adrian Hoban <adrian.hoban@intel.com> 1462306a36Sopenharmony_ci * Gabriele Paoloni <gabriele.paoloni@intel.com> 1562306a36Sopenharmony_ci * Tadeusz Struk (tadeusz.struk@intel.com) 1662306a36Sopenharmony_ci * Copyright (c) 2010, Intel Corporation. 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <crypto/aead.h> 2062306a36Sopenharmony_ci#include <crypto/hash.h> 2162306a36Sopenharmony_ci#include <crypto/skcipher.h> 2262306a36Sopenharmony_ci#include <linux/err.h> 2362306a36Sopenharmony_ci#include <linux/fips.h> 2462306a36Sopenharmony_ci#include <linux/module.h> 2562306a36Sopenharmony_ci#include <linux/once.h> 2662306a36Sopenharmony_ci#include <linux/random.h> 2762306a36Sopenharmony_ci#include <linux/scatterlist.h> 2862306a36Sopenharmony_ci#include <linux/slab.h> 2962306a36Sopenharmony_ci#include <linux/string.h> 3062306a36Sopenharmony_ci#include <linux/uio.h> 3162306a36Sopenharmony_ci#include <crypto/rng.h> 3262306a36Sopenharmony_ci#include <crypto/drbg.h> 3362306a36Sopenharmony_ci#include <crypto/akcipher.h> 3462306a36Sopenharmony_ci#include <crypto/kpp.h> 3562306a36Sopenharmony_ci#include <crypto/acompress.h> 3662306a36Sopenharmony_ci#include <crypto/internal/cipher.h> 3762306a36Sopenharmony_ci#include <crypto/internal/simd.h> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#include "internal.h" 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciMODULE_IMPORT_NS(CRYPTO_INTERNAL); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic bool notests; 4462306a36Sopenharmony_cimodule_param(notests, bool, 0644); 4562306a36Sopenharmony_ciMODULE_PARM_DESC(notests, "disable crypto self-tests"); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic bool panic_on_fail; 4862306a36Sopenharmony_cimodule_param(panic_on_fail, bool, 0444); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 5162306a36Sopenharmony_cistatic bool noextratests; 5262306a36Sopenharmony_cimodule_param(noextratests, bool, 0644); 5362306a36Sopenharmony_ciMODULE_PARM_DESC(noextratests, "disable expensive crypto self-tests"); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic unsigned int fuzz_iterations = 100; 5662306a36Sopenharmony_cimodule_param(fuzz_iterations, uint, 0644); 5762306a36Sopenharmony_ciMODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); 5862306a36Sopenharmony_ci#endif 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* a perfect nop */ 6362306a36Sopenharmony_ciint alg_test(const char *driver, const char *alg, u32 type, u32 mask) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci return 0; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#else 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#include "testmgr.h" 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/* 7362306a36Sopenharmony_ci * Need slab memory for testing (size in number of pages). 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_ci#define XBUFSIZE 8 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* 7862306a36Sopenharmony_ci* Used by test_cipher() 7962306a36Sopenharmony_ci*/ 8062306a36Sopenharmony_ci#define ENCRYPT 1 8162306a36Sopenharmony_ci#define DECRYPT 0 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistruct aead_test_suite { 8462306a36Sopenharmony_ci const struct aead_testvec *vecs; 8562306a36Sopenharmony_ci unsigned int count; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci /* 8862306a36Sopenharmony_ci * Set if trying to decrypt an inauthentic ciphertext with this 8962306a36Sopenharmony_ci * algorithm might result in EINVAL rather than EBADMSG, due to other 9062306a36Sopenharmony_ci * validation the algorithm does on the inputs such as length checks. 9162306a36Sopenharmony_ci */ 9262306a36Sopenharmony_ci unsigned int einval_allowed : 1; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /* 9562306a36Sopenharmony_ci * Set if this algorithm requires that the IV be located at the end of 9662306a36Sopenharmony_ci * the AAD buffer, in addition to being given in the normal way. The 9762306a36Sopenharmony_ci * behavior when the two IV copies differ is implementation-defined. 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_ci unsigned int aad_iv : 1; 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistruct cipher_test_suite { 10362306a36Sopenharmony_ci const struct cipher_testvec *vecs; 10462306a36Sopenharmony_ci unsigned int count; 10562306a36Sopenharmony_ci}; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistruct comp_test_suite { 10862306a36Sopenharmony_ci struct { 10962306a36Sopenharmony_ci const struct comp_testvec *vecs; 11062306a36Sopenharmony_ci unsigned int count; 11162306a36Sopenharmony_ci } comp, decomp; 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistruct hash_test_suite { 11562306a36Sopenharmony_ci const struct hash_testvec *vecs; 11662306a36Sopenharmony_ci unsigned int count; 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistruct cprng_test_suite { 12062306a36Sopenharmony_ci const struct cprng_testvec *vecs; 12162306a36Sopenharmony_ci unsigned int count; 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistruct drbg_test_suite { 12562306a36Sopenharmony_ci const struct drbg_testvec *vecs; 12662306a36Sopenharmony_ci unsigned int count; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistruct akcipher_test_suite { 13062306a36Sopenharmony_ci const struct akcipher_testvec *vecs; 13162306a36Sopenharmony_ci unsigned int count; 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistruct kpp_test_suite { 13562306a36Sopenharmony_ci const struct kpp_testvec *vecs; 13662306a36Sopenharmony_ci unsigned int count; 13762306a36Sopenharmony_ci}; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistruct alg_test_desc { 14062306a36Sopenharmony_ci const char *alg; 14162306a36Sopenharmony_ci const char *generic_driver; 14262306a36Sopenharmony_ci int (*test)(const struct alg_test_desc *desc, const char *driver, 14362306a36Sopenharmony_ci u32 type, u32 mask); 14462306a36Sopenharmony_ci int fips_allowed; /* set if alg is allowed in fips mode */ 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci union { 14762306a36Sopenharmony_ci struct aead_test_suite aead; 14862306a36Sopenharmony_ci struct cipher_test_suite cipher; 14962306a36Sopenharmony_ci struct comp_test_suite comp; 15062306a36Sopenharmony_ci struct hash_test_suite hash; 15162306a36Sopenharmony_ci struct cprng_test_suite cprng; 15262306a36Sopenharmony_ci struct drbg_test_suite drbg; 15362306a36Sopenharmony_ci struct akcipher_test_suite akcipher; 15462306a36Sopenharmony_ci struct kpp_test_suite kpp; 15562306a36Sopenharmony_ci } suite; 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic void hexdump(unsigned char *buf, unsigned int len) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, 16162306a36Sopenharmony_ci 16, 1, 16262306a36Sopenharmony_ci buf, len, false); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci int i; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci for (i = 0; i < XBUFSIZE; i++) { 17062306a36Sopenharmony_ci buf[i] = (char *)__get_free_pages(GFP_KERNEL, order); 17162306a36Sopenharmony_ci if (!buf[i]) 17262306a36Sopenharmony_ci goto err_free_buf; 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci return 0; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cierr_free_buf: 17862306a36Sopenharmony_ci while (i-- > 0) 17962306a36Sopenharmony_ci free_pages((unsigned long)buf[i], order); 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci return -ENOMEM; 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistatic int testmgr_alloc_buf(char *buf[XBUFSIZE]) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci return __testmgr_alloc_buf(buf, 0); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistatic void __testmgr_free_buf(char *buf[XBUFSIZE], int order) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci int i; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci for (i = 0; i < XBUFSIZE; i++) 19462306a36Sopenharmony_ci free_pages((unsigned long)buf[i], order); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic void testmgr_free_buf(char *buf[XBUFSIZE]) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci __testmgr_free_buf(buf, 0); 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci#define TESTMGR_POISON_BYTE 0xfe 20362306a36Sopenharmony_ci#define TESTMGR_POISON_LEN 16 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistatic inline void testmgr_poison(void *addr, size_t len) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci memset(addr, TESTMGR_POISON_BYTE, len); 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci/* Is the memory region still fully poisoned? */ 21162306a36Sopenharmony_cistatic inline bool testmgr_is_poison(const void *addr, size_t len) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci return memchr_inv(addr, TESTMGR_POISON_BYTE, len) == NULL; 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci/* flush type for hash algorithms */ 21762306a36Sopenharmony_cienum flush_type { 21862306a36Sopenharmony_ci /* merge with update of previous buffer(s) */ 21962306a36Sopenharmony_ci FLUSH_TYPE_NONE = 0, 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* update with previous buffer(s) before doing this one */ 22262306a36Sopenharmony_ci FLUSH_TYPE_FLUSH, 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci /* likewise, but also export and re-import the intermediate state */ 22562306a36Sopenharmony_ci FLUSH_TYPE_REIMPORT, 22662306a36Sopenharmony_ci}; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci/* finalization function for hash algorithms */ 22962306a36Sopenharmony_cienum finalization_type { 23062306a36Sopenharmony_ci FINALIZATION_TYPE_FINAL, /* use final() */ 23162306a36Sopenharmony_ci FINALIZATION_TYPE_FINUP, /* use finup() */ 23262306a36Sopenharmony_ci FINALIZATION_TYPE_DIGEST, /* use digest() */ 23362306a36Sopenharmony_ci}; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci/* 23662306a36Sopenharmony_ci * Whether the crypto operation will occur in-place, and if so whether the 23762306a36Sopenharmony_ci * source and destination scatterlist pointers will coincide (req->src == 23862306a36Sopenharmony_ci * req->dst), or whether they'll merely point to two separate scatterlists 23962306a36Sopenharmony_ci * (req->src != req->dst) that reference the same underlying memory. 24062306a36Sopenharmony_ci * 24162306a36Sopenharmony_ci * This is only relevant for algorithm types that support in-place operation. 24262306a36Sopenharmony_ci */ 24362306a36Sopenharmony_cienum inplace_mode { 24462306a36Sopenharmony_ci OUT_OF_PLACE, 24562306a36Sopenharmony_ci INPLACE_ONE_SGLIST, 24662306a36Sopenharmony_ci INPLACE_TWO_SGLISTS, 24762306a36Sopenharmony_ci}; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci#define TEST_SG_TOTAL 10000 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/** 25262306a36Sopenharmony_ci * struct test_sg_division - description of a scatterlist entry 25362306a36Sopenharmony_ci * 25462306a36Sopenharmony_ci * This struct describes one entry of a scatterlist being constructed to check a 25562306a36Sopenharmony_ci * crypto test vector. 25662306a36Sopenharmony_ci * 25762306a36Sopenharmony_ci * @proportion_of_total: length of this chunk relative to the total length, 25862306a36Sopenharmony_ci * given as a proportion out of TEST_SG_TOTAL so that it 25962306a36Sopenharmony_ci * scales to fit any test vector 26062306a36Sopenharmony_ci * @offset: byte offset into a 2-page buffer at which this chunk will start 26162306a36Sopenharmony_ci * @offset_relative_to_alignmask: if true, add the algorithm's alignmask to the 26262306a36Sopenharmony_ci * @offset 26362306a36Sopenharmony_ci * @flush_type: for hashes, whether an update() should be done now vs. 26462306a36Sopenharmony_ci * continuing to accumulate data 26562306a36Sopenharmony_ci * @nosimd: if doing the pending update(), do it with SIMD disabled? 26662306a36Sopenharmony_ci */ 26762306a36Sopenharmony_cistruct test_sg_division { 26862306a36Sopenharmony_ci unsigned int proportion_of_total; 26962306a36Sopenharmony_ci unsigned int offset; 27062306a36Sopenharmony_ci bool offset_relative_to_alignmask; 27162306a36Sopenharmony_ci enum flush_type flush_type; 27262306a36Sopenharmony_ci bool nosimd; 27362306a36Sopenharmony_ci}; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci/** 27662306a36Sopenharmony_ci * struct testvec_config - configuration for testing a crypto test vector 27762306a36Sopenharmony_ci * 27862306a36Sopenharmony_ci * This struct describes the data layout and other parameters with which each 27962306a36Sopenharmony_ci * crypto test vector can be tested. 28062306a36Sopenharmony_ci * 28162306a36Sopenharmony_ci * @name: name of this config, logged for debugging purposes if a test fails 28262306a36Sopenharmony_ci * @inplace_mode: whether and how to operate on the data in-place, if applicable 28362306a36Sopenharmony_ci * @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP 28462306a36Sopenharmony_ci * @src_divs: description of how to arrange the source scatterlist 28562306a36Sopenharmony_ci * @dst_divs: description of how to arrange the dst scatterlist, if applicable 28662306a36Sopenharmony_ci * for the algorithm type. Defaults to @src_divs if unset. 28762306a36Sopenharmony_ci * @iv_offset: misalignment of the IV in the range [0..MAX_ALGAPI_ALIGNMASK+1], 28862306a36Sopenharmony_ci * where 0 is aligned to a 2*(MAX_ALGAPI_ALIGNMASK+1) byte boundary 28962306a36Sopenharmony_ci * @iv_offset_relative_to_alignmask: if true, add the algorithm's alignmask to 29062306a36Sopenharmony_ci * the @iv_offset 29162306a36Sopenharmony_ci * @key_offset: misalignment of the key, where 0 is default alignment 29262306a36Sopenharmony_ci * @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to 29362306a36Sopenharmony_ci * the @key_offset 29462306a36Sopenharmony_ci * @finalization_type: what finalization function to use for hashes 29562306a36Sopenharmony_ci * @nosimd: execute with SIMD disabled? Requires !CRYPTO_TFM_REQ_MAY_SLEEP. 29662306a36Sopenharmony_ci */ 29762306a36Sopenharmony_cistruct testvec_config { 29862306a36Sopenharmony_ci const char *name; 29962306a36Sopenharmony_ci enum inplace_mode inplace_mode; 30062306a36Sopenharmony_ci u32 req_flags; 30162306a36Sopenharmony_ci struct test_sg_division src_divs[XBUFSIZE]; 30262306a36Sopenharmony_ci struct test_sg_division dst_divs[XBUFSIZE]; 30362306a36Sopenharmony_ci unsigned int iv_offset; 30462306a36Sopenharmony_ci unsigned int key_offset; 30562306a36Sopenharmony_ci bool iv_offset_relative_to_alignmask; 30662306a36Sopenharmony_ci bool key_offset_relative_to_alignmask; 30762306a36Sopenharmony_ci enum finalization_type finalization_type; 30862306a36Sopenharmony_ci bool nosimd; 30962306a36Sopenharmony_ci}; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci#define TESTVEC_CONFIG_NAMELEN 192 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci/* 31462306a36Sopenharmony_ci * The following are the lists of testvec_configs to test for each algorithm 31562306a36Sopenharmony_ci * type when the basic crypto self-tests are enabled, i.e. when 31662306a36Sopenharmony_ci * CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is unset. They aim to provide good test 31762306a36Sopenharmony_ci * coverage, while keeping the test time much shorter than the full fuzz tests 31862306a36Sopenharmony_ci * so that the basic tests can be enabled in a wider range of circumstances. 31962306a36Sopenharmony_ci */ 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci/* Configs for skciphers and aeads */ 32262306a36Sopenharmony_cistatic const struct testvec_config default_cipher_testvec_configs[] = { 32362306a36Sopenharmony_ci { 32462306a36Sopenharmony_ci .name = "in-place (one sglist)", 32562306a36Sopenharmony_ci .inplace_mode = INPLACE_ONE_SGLIST, 32662306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000 } }, 32762306a36Sopenharmony_ci }, { 32862306a36Sopenharmony_ci .name = "in-place (two sglists)", 32962306a36Sopenharmony_ci .inplace_mode = INPLACE_TWO_SGLISTS, 33062306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000 } }, 33162306a36Sopenharmony_ci }, { 33262306a36Sopenharmony_ci .name = "out-of-place", 33362306a36Sopenharmony_ci .inplace_mode = OUT_OF_PLACE, 33462306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000 } }, 33562306a36Sopenharmony_ci }, { 33662306a36Sopenharmony_ci .name = "unaligned buffer, offset=1", 33762306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, 33862306a36Sopenharmony_ci .iv_offset = 1, 33962306a36Sopenharmony_ci .key_offset = 1, 34062306a36Sopenharmony_ci }, { 34162306a36Sopenharmony_ci .name = "buffer aligned only to alignmask", 34262306a36Sopenharmony_ci .src_divs = { 34362306a36Sopenharmony_ci { 34462306a36Sopenharmony_ci .proportion_of_total = 10000, 34562306a36Sopenharmony_ci .offset = 1, 34662306a36Sopenharmony_ci .offset_relative_to_alignmask = true, 34762306a36Sopenharmony_ci }, 34862306a36Sopenharmony_ci }, 34962306a36Sopenharmony_ci .iv_offset = 1, 35062306a36Sopenharmony_ci .iv_offset_relative_to_alignmask = true, 35162306a36Sopenharmony_ci .key_offset = 1, 35262306a36Sopenharmony_ci .key_offset_relative_to_alignmask = true, 35362306a36Sopenharmony_ci }, { 35462306a36Sopenharmony_ci .name = "two even aligned splits", 35562306a36Sopenharmony_ci .src_divs = { 35662306a36Sopenharmony_ci { .proportion_of_total = 5000 }, 35762306a36Sopenharmony_ci { .proportion_of_total = 5000 }, 35862306a36Sopenharmony_ci }, 35962306a36Sopenharmony_ci }, { 36062306a36Sopenharmony_ci .name = "one src, two even splits dst", 36162306a36Sopenharmony_ci .inplace_mode = OUT_OF_PLACE, 36262306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000 } }, 36362306a36Sopenharmony_ci .dst_divs = { 36462306a36Sopenharmony_ci { .proportion_of_total = 5000 }, 36562306a36Sopenharmony_ci { .proportion_of_total = 5000 }, 36662306a36Sopenharmony_ci }, 36762306a36Sopenharmony_ci }, { 36862306a36Sopenharmony_ci .name = "uneven misaligned splits, may sleep", 36962306a36Sopenharmony_ci .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, 37062306a36Sopenharmony_ci .src_divs = { 37162306a36Sopenharmony_ci { .proportion_of_total = 1900, .offset = 33 }, 37262306a36Sopenharmony_ci { .proportion_of_total = 3300, .offset = 7 }, 37362306a36Sopenharmony_ci { .proportion_of_total = 4800, .offset = 18 }, 37462306a36Sopenharmony_ci }, 37562306a36Sopenharmony_ci .iv_offset = 3, 37662306a36Sopenharmony_ci .key_offset = 3, 37762306a36Sopenharmony_ci }, { 37862306a36Sopenharmony_ci .name = "misaligned splits crossing pages, inplace", 37962306a36Sopenharmony_ci .inplace_mode = INPLACE_ONE_SGLIST, 38062306a36Sopenharmony_ci .src_divs = { 38162306a36Sopenharmony_ci { 38262306a36Sopenharmony_ci .proportion_of_total = 7500, 38362306a36Sopenharmony_ci .offset = PAGE_SIZE - 32 38462306a36Sopenharmony_ci }, { 38562306a36Sopenharmony_ci .proportion_of_total = 2500, 38662306a36Sopenharmony_ci .offset = PAGE_SIZE - 7 38762306a36Sopenharmony_ci }, 38862306a36Sopenharmony_ci }, 38962306a36Sopenharmony_ci } 39062306a36Sopenharmony_ci}; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_cistatic const struct testvec_config default_hash_testvec_configs[] = { 39362306a36Sopenharmony_ci { 39462306a36Sopenharmony_ci .name = "init+update+final aligned buffer", 39562306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000 } }, 39662306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_FINAL, 39762306a36Sopenharmony_ci }, { 39862306a36Sopenharmony_ci .name = "init+finup aligned buffer", 39962306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000 } }, 40062306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_FINUP, 40162306a36Sopenharmony_ci }, { 40262306a36Sopenharmony_ci .name = "digest aligned buffer", 40362306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000 } }, 40462306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_DIGEST, 40562306a36Sopenharmony_ci }, { 40662306a36Sopenharmony_ci .name = "init+update+final misaligned buffer", 40762306a36Sopenharmony_ci .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, 40862306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_FINAL, 40962306a36Sopenharmony_ci .key_offset = 1, 41062306a36Sopenharmony_ci }, { 41162306a36Sopenharmony_ci .name = "digest buffer aligned only to alignmask", 41262306a36Sopenharmony_ci .src_divs = { 41362306a36Sopenharmony_ci { 41462306a36Sopenharmony_ci .proportion_of_total = 10000, 41562306a36Sopenharmony_ci .offset = 1, 41662306a36Sopenharmony_ci .offset_relative_to_alignmask = true, 41762306a36Sopenharmony_ci }, 41862306a36Sopenharmony_ci }, 41962306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_DIGEST, 42062306a36Sopenharmony_ci .key_offset = 1, 42162306a36Sopenharmony_ci .key_offset_relative_to_alignmask = true, 42262306a36Sopenharmony_ci }, { 42362306a36Sopenharmony_ci .name = "init+update+update+final two even splits", 42462306a36Sopenharmony_ci .src_divs = { 42562306a36Sopenharmony_ci { .proportion_of_total = 5000 }, 42662306a36Sopenharmony_ci { 42762306a36Sopenharmony_ci .proportion_of_total = 5000, 42862306a36Sopenharmony_ci .flush_type = FLUSH_TYPE_FLUSH, 42962306a36Sopenharmony_ci }, 43062306a36Sopenharmony_ci }, 43162306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_FINAL, 43262306a36Sopenharmony_ci }, { 43362306a36Sopenharmony_ci .name = "digest uneven misaligned splits, may sleep", 43462306a36Sopenharmony_ci .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, 43562306a36Sopenharmony_ci .src_divs = { 43662306a36Sopenharmony_ci { .proportion_of_total = 1900, .offset = 33 }, 43762306a36Sopenharmony_ci { .proportion_of_total = 3300, .offset = 7 }, 43862306a36Sopenharmony_ci { .proportion_of_total = 4800, .offset = 18 }, 43962306a36Sopenharmony_ci }, 44062306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_DIGEST, 44162306a36Sopenharmony_ci }, { 44262306a36Sopenharmony_ci .name = "digest misaligned splits crossing pages", 44362306a36Sopenharmony_ci .src_divs = { 44462306a36Sopenharmony_ci { 44562306a36Sopenharmony_ci .proportion_of_total = 7500, 44662306a36Sopenharmony_ci .offset = PAGE_SIZE - 32, 44762306a36Sopenharmony_ci }, { 44862306a36Sopenharmony_ci .proportion_of_total = 2500, 44962306a36Sopenharmony_ci .offset = PAGE_SIZE - 7, 45062306a36Sopenharmony_ci }, 45162306a36Sopenharmony_ci }, 45262306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_DIGEST, 45362306a36Sopenharmony_ci }, { 45462306a36Sopenharmony_ci .name = "import/export", 45562306a36Sopenharmony_ci .src_divs = { 45662306a36Sopenharmony_ci { 45762306a36Sopenharmony_ci .proportion_of_total = 6500, 45862306a36Sopenharmony_ci .flush_type = FLUSH_TYPE_REIMPORT, 45962306a36Sopenharmony_ci }, { 46062306a36Sopenharmony_ci .proportion_of_total = 3500, 46162306a36Sopenharmony_ci .flush_type = FLUSH_TYPE_REIMPORT, 46262306a36Sopenharmony_ci }, 46362306a36Sopenharmony_ci }, 46462306a36Sopenharmony_ci .finalization_type = FINALIZATION_TYPE_FINAL, 46562306a36Sopenharmony_ci } 46662306a36Sopenharmony_ci}; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_cistatic unsigned int count_test_sg_divisions(const struct test_sg_division *divs) 46962306a36Sopenharmony_ci{ 47062306a36Sopenharmony_ci unsigned int remaining = TEST_SG_TOTAL; 47162306a36Sopenharmony_ci unsigned int ndivs = 0; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci do { 47462306a36Sopenharmony_ci remaining -= divs[ndivs++].proportion_of_total; 47562306a36Sopenharmony_ci } while (remaining); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci return ndivs; 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci#define SGDIVS_HAVE_FLUSHES BIT(0) 48162306a36Sopenharmony_ci#define SGDIVS_HAVE_NOSIMD BIT(1) 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_cistatic bool valid_sg_divisions(const struct test_sg_division *divs, 48462306a36Sopenharmony_ci unsigned int count, int *flags_ret) 48562306a36Sopenharmony_ci{ 48662306a36Sopenharmony_ci unsigned int total = 0; 48762306a36Sopenharmony_ci unsigned int i; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci for (i = 0; i < count && total != TEST_SG_TOTAL; i++) { 49062306a36Sopenharmony_ci if (divs[i].proportion_of_total <= 0 || 49162306a36Sopenharmony_ci divs[i].proportion_of_total > TEST_SG_TOTAL - total) 49262306a36Sopenharmony_ci return false; 49362306a36Sopenharmony_ci total += divs[i].proportion_of_total; 49462306a36Sopenharmony_ci if (divs[i].flush_type != FLUSH_TYPE_NONE) 49562306a36Sopenharmony_ci *flags_ret |= SGDIVS_HAVE_FLUSHES; 49662306a36Sopenharmony_ci if (divs[i].nosimd) 49762306a36Sopenharmony_ci *flags_ret |= SGDIVS_HAVE_NOSIMD; 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci return total == TEST_SG_TOTAL && 50062306a36Sopenharmony_ci memchr_inv(&divs[i], 0, (count - i) * sizeof(divs[0])) == NULL; 50162306a36Sopenharmony_ci} 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci/* 50462306a36Sopenharmony_ci * Check whether the given testvec_config is valid. This isn't strictly needed 50562306a36Sopenharmony_ci * since every testvec_config should be valid, but check anyway so that people 50662306a36Sopenharmony_ci * don't unknowingly add broken configs that don't do what they wanted. 50762306a36Sopenharmony_ci */ 50862306a36Sopenharmony_cistatic bool valid_testvec_config(const struct testvec_config *cfg) 50962306a36Sopenharmony_ci{ 51062306a36Sopenharmony_ci int flags = 0; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci if (cfg->name == NULL) 51362306a36Sopenharmony_ci return false; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci if (!valid_sg_divisions(cfg->src_divs, ARRAY_SIZE(cfg->src_divs), 51662306a36Sopenharmony_ci &flags)) 51762306a36Sopenharmony_ci return false; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci if (cfg->dst_divs[0].proportion_of_total) { 52062306a36Sopenharmony_ci if (!valid_sg_divisions(cfg->dst_divs, 52162306a36Sopenharmony_ci ARRAY_SIZE(cfg->dst_divs), &flags)) 52262306a36Sopenharmony_ci return false; 52362306a36Sopenharmony_ci } else { 52462306a36Sopenharmony_ci if (memchr_inv(cfg->dst_divs, 0, sizeof(cfg->dst_divs))) 52562306a36Sopenharmony_ci return false; 52662306a36Sopenharmony_ci /* defaults to dst_divs=src_divs */ 52762306a36Sopenharmony_ci } 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci if (cfg->iv_offset + 53062306a36Sopenharmony_ci (cfg->iv_offset_relative_to_alignmask ? MAX_ALGAPI_ALIGNMASK : 0) > 53162306a36Sopenharmony_ci MAX_ALGAPI_ALIGNMASK + 1) 53262306a36Sopenharmony_ci return false; 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci if ((flags & (SGDIVS_HAVE_FLUSHES | SGDIVS_HAVE_NOSIMD)) && 53562306a36Sopenharmony_ci cfg->finalization_type == FINALIZATION_TYPE_DIGEST) 53662306a36Sopenharmony_ci return false; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci if ((cfg->nosimd || (flags & SGDIVS_HAVE_NOSIMD)) && 53962306a36Sopenharmony_ci (cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP)) 54062306a36Sopenharmony_ci return false; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci return true; 54362306a36Sopenharmony_ci} 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_cistruct test_sglist { 54662306a36Sopenharmony_ci char *bufs[XBUFSIZE]; 54762306a36Sopenharmony_ci struct scatterlist sgl[XBUFSIZE]; 54862306a36Sopenharmony_ci struct scatterlist sgl_saved[XBUFSIZE]; 54962306a36Sopenharmony_ci struct scatterlist *sgl_ptr; 55062306a36Sopenharmony_ci unsigned int nents; 55162306a36Sopenharmony_ci}; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cistatic int init_test_sglist(struct test_sglist *tsgl) 55462306a36Sopenharmony_ci{ 55562306a36Sopenharmony_ci return __testmgr_alloc_buf(tsgl->bufs, 1 /* two pages per buffer */); 55662306a36Sopenharmony_ci} 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_cistatic void destroy_test_sglist(struct test_sglist *tsgl) 55962306a36Sopenharmony_ci{ 56062306a36Sopenharmony_ci return __testmgr_free_buf(tsgl->bufs, 1 /* two pages per buffer */); 56162306a36Sopenharmony_ci} 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci/** 56462306a36Sopenharmony_ci * build_test_sglist() - build a scatterlist for a crypto test 56562306a36Sopenharmony_ci * 56662306a36Sopenharmony_ci * @tsgl: the scatterlist to build. @tsgl->bufs[] contains an array of 2-page 56762306a36Sopenharmony_ci * buffers which the scatterlist @tsgl->sgl[] will be made to point into. 56862306a36Sopenharmony_ci * @divs: the layout specification on which the scatterlist will be based 56962306a36Sopenharmony_ci * @alignmask: the algorithm's alignmask 57062306a36Sopenharmony_ci * @total_len: the total length of the scatterlist to build in bytes 57162306a36Sopenharmony_ci * @data: if non-NULL, the buffers will be filled with this data until it ends. 57262306a36Sopenharmony_ci * Otherwise the buffers will be poisoned. In both cases, some bytes 57362306a36Sopenharmony_ci * past the end of each buffer will be poisoned to help detect overruns. 57462306a36Sopenharmony_ci * @out_divs: if non-NULL, the test_sg_division to which each scatterlist entry 57562306a36Sopenharmony_ci * corresponds will be returned here. This will match @divs except 57662306a36Sopenharmony_ci * that divisions resolving to a length of 0 are omitted as they are 57762306a36Sopenharmony_ci * not included in the scatterlist. 57862306a36Sopenharmony_ci * 57962306a36Sopenharmony_ci * Return: 0 or a -errno value 58062306a36Sopenharmony_ci */ 58162306a36Sopenharmony_cistatic int build_test_sglist(struct test_sglist *tsgl, 58262306a36Sopenharmony_ci const struct test_sg_division *divs, 58362306a36Sopenharmony_ci const unsigned int alignmask, 58462306a36Sopenharmony_ci const unsigned int total_len, 58562306a36Sopenharmony_ci struct iov_iter *data, 58662306a36Sopenharmony_ci const struct test_sg_division *out_divs[XBUFSIZE]) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci struct { 58962306a36Sopenharmony_ci const struct test_sg_division *div; 59062306a36Sopenharmony_ci size_t length; 59162306a36Sopenharmony_ci } partitions[XBUFSIZE]; 59262306a36Sopenharmony_ci const unsigned int ndivs = count_test_sg_divisions(divs); 59362306a36Sopenharmony_ci unsigned int len_remaining = total_len; 59462306a36Sopenharmony_ci unsigned int i; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci BUILD_BUG_ON(ARRAY_SIZE(partitions) != ARRAY_SIZE(tsgl->sgl)); 59762306a36Sopenharmony_ci if (WARN_ON(ndivs > ARRAY_SIZE(partitions))) 59862306a36Sopenharmony_ci return -EINVAL; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci /* Calculate the (div, length) pairs */ 60162306a36Sopenharmony_ci tsgl->nents = 0; 60262306a36Sopenharmony_ci for (i = 0; i < ndivs; i++) { 60362306a36Sopenharmony_ci unsigned int len_this_sg = 60462306a36Sopenharmony_ci min(len_remaining, 60562306a36Sopenharmony_ci (total_len * divs[i].proportion_of_total + 60662306a36Sopenharmony_ci TEST_SG_TOTAL / 2) / TEST_SG_TOTAL); 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci if (len_this_sg != 0) { 60962306a36Sopenharmony_ci partitions[tsgl->nents].div = &divs[i]; 61062306a36Sopenharmony_ci partitions[tsgl->nents].length = len_this_sg; 61162306a36Sopenharmony_ci tsgl->nents++; 61262306a36Sopenharmony_ci len_remaining -= len_this_sg; 61362306a36Sopenharmony_ci } 61462306a36Sopenharmony_ci } 61562306a36Sopenharmony_ci if (tsgl->nents == 0) { 61662306a36Sopenharmony_ci partitions[tsgl->nents].div = &divs[0]; 61762306a36Sopenharmony_ci partitions[tsgl->nents].length = 0; 61862306a36Sopenharmony_ci tsgl->nents++; 61962306a36Sopenharmony_ci } 62062306a36Sopenharmony_ci partitions[tsgl->nents - 1].length += len_remaining; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci /* Set up the sgl entries and fill the data or poison */ 62362306a36Sopenharmony_ci sg_init_table(tsgl->sgl, tsgl->nents); 62462306a36Sopenharmony_ci for (i = 0; i < tsgl->nents; i++) { 62562306a36Sopenharmony_ci unsigned int offset = partitions[i].div->offset; 62662306a36Sopenharmony_ci void *addr; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci if (partitions[i].div->offset_relative_to_alignmask) 62962306a36Sopenharmony_ci offset += alignmask; 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci while (offset + partitions[i].length + TESTMGR_POISON_LEN > 63262306a36Sopenharmony_ci 2 * PAGE_SIZE) { 63362306a36Sopenharmony_ci if (WARN_ON(offset <= 0)) 63462306a36Sopenharmony_ci return -EINVAL; 63562306a36Sopenharmony_ci offset /= 2; 63662306a36Sopenharmony_ci } 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci addr = &tsgl->bufs[i][offset]; 63962306a36Sopenharmony_ci sg_set_buf(&tsgl->sgl[i], addr, partitions[i].length); 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci if (out_divs) 64262306a36Sopenharmony_ci out_divs[i] = partitions[i].div; 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci if (data) { 64562306a36Sopenharmony_ci size_t copy_len, copied; 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci copy_len = min(partitions[i].length, data->count); 64862306a36Sopenharmony_ci copied = copy_from_iter(addr, copy_len, data); 64962306a36Sopenharmony_ci if (WARN_ON(copied != copy_len)) 65062306a36Sopenharmony_ci return -EINVAL; 65162306a36Sopenharmony_ci testmgr_poison(addr + copy_len, partitions[i].length + 65262306a36Sopenharmony_ci TESTMGR_POISON_LEN - copy_len); 65362306a36Sopenharmony_ci } else { 65462306a36Sopenharmony_ci testmgr_poison(addr, partitions[i].length + 65562306a36Sopenharmony_ci TESTMGR_POISON_LEN); 65662306a36Sopenharmony_ci } 65762306a36Sopenharmony_ci } 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci sg_mark_end(&tsgl->sgl[tsgl->nents - 1]); 66062306a36Sopenharmony_ci tsgl->sgl_ptr = tsgl->sgl; 66162306a36Sopenharmony_ci memcpy(tsgl->sgl_saved, tsgl->sgl, tsgl->nents * sizeof(tsgl->sgl[0])); 66262306a36Sopenharmony_ci return 0; 66362306a36Sopenharmony_ci} 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci/* 66662306a36Sopenharmony_ci * Verify that a scatterlist crypto operation produced the correct output. 66762306a36Sopenharmony_ci * 66862306a36Sopenharmony_ci * @tsgl: scatterlist containing the actual output 66962306a36Sopenharmony_ci * @expected_output: buffer containing the expected output 67062306a36Sopenharmony_ci * @len_to_check: length of @expected_output in bytes 67162306a36Sopenharmony_ci * @unchecked_prefix_len: number of ignored bytes in @tsgl prior to real result 67262306a36Sopenharmony_ci * @check_poison: verify that the poison bytes after each chunk are intact? 67362306a36Sopenharmony_ci * 67462306a36Sopenharmony_ci * Return: 0 if correct, -EINVAL if incorrect, -EOVERFLOW if buffer overrun. 67562306a36Sopenharmony_ci */ 67662306a36Sopenharmony_cistatic int verify_correct_output(const struct test_sglist *tsgl, 67762306a36Sopenharmony_ci const char *expected_output, 67862306a36Sopenharmony_ci unsigned int len_to_check, 67962306a36Sopenharmony_ci unsigned int unchecked_prefix_len, 68062306a36Sopenharmony_ci bool check_poison) 68162306a36Sopenharmony_ci{ 68262306a36Sopenharmony_ci unsigned int i; 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci for (i = 0; i < tsgl->nents; i++) { 68562306a36Sopenharmony_ci struct scatterlist *sg = &tsgl->sgl_ptr[i]; 68662306a36Sopenharmony_ci unsigned int len = sg->length; 68762306a36Sopenharmony_ci unsigned int offset = sg->offset; 68862306a36Sopenharmony_ci const char *actual_output; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci if (unchecked_prefix_len) { 69162306a36Sopenharmony_ci if (unchecked_prefix_len >= len) { 69262306a36Sopenharmony_ci unchecked_prefix_len -= len; 69362306a36Sopenharmony_ci continue; 69462306a36Sopenharmony_ci } 69562306a36Sopenharmony_ci offset += unchecked_prefix_len; 69662306a36Sopenharmony_ci len -= unchecked_prefix_len; 69762306a36Sopenharmony_ci unchecked_prefix_len = 0; 69862306a36Sopenharmony_ci } 69962306a36Sopenharmony_ci len = min(len, len_to_check); 70062306a36Sopenharmony_ci actual_output = page_address(sg_page(sg)) + offset; 70162306a36Sopenharmony_ci if (memcmp(expected_output, actual_output, len) != 0) 70262306a36Sopenharmony_ci return -EINVAL; 70362306a36Sopenharmony_ci if (check_poison && 70462306a36Sopenharmony_ci !testmgr_is_poison(actual_output + len, TESTMGR_POISON_LEN)) 70562306a36Sopenharmony_ci return -EOVERFLOW; 70662306a36Sopenharmony_ci len_to_check -= len; 70762306a36Sopenharmony_ci expected_output += len; 70862306a36Sopenharmony_ci } 70962306a36Sopenharmony_ci if (WARN_ON(len_to_check != 0)) 71062306a36Sopenharmony_ci return -EINVAL; 71162306a36Sopenharmony_ci return 0; 71262306a36Sopenharmony_ci} 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_cistatic bool is_test_sglist_corrupted(const struct test_sglist *tsgl) 71562306a36Sopenharmony_ci{ 71662306a36Sopenharmony_ci unsigned int i; 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci for (i = 0; i < tsgl->nents; i++) { 71962306a36Sopenharmony_ci if (tsgl->sgl[i].page_link != tsgl->sgl_saved[i].page_link) 72062306a36Sopenharmony_ci return true; 72162306a36Sopenharmony_ci if (tsgl->sgl[i].offset != tsgl->sgl_saved[i].offset) 72262306a36Sopenharmony_ci return true; 72362306a36Sopenharmony_ci if (tsgl->sgl[i].length != tsgl->sgl_saved[i].length) 72462306a36Sopenharmony_ci return true; 72562306a36Sopenharmony_ci } 72662306a36Sopenharmony_ci return false; 72762306a36Sopenharmony_ci} 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_cistruct cipher_test_sglists { 73062306a36Sopenharmony_ci struct test_sglist src; 73162306a36Sopenharmony_ci struct test_sglist dst; 73262306a36Sopenharmony_ci}; 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_cistatic struct cipher_test_sglists *alloc_cipher_test_sglists(void) 73562306a36Sopenharmony_ci{ 73662306a36Sopenharmony_ci struct cipher_test_sglists *tsgls; 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci tsgls = kmalloc(sizeof(*tsgls), GFP_KERNEL); 73962306a36Sopenharmony_ci if (!tsgls) 74062306a36Sopenharmony_ci return NULL; 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci if (init_test_sglist(&tsgls->src) != 0) 74362306a36Sopenharmony_ci goto fail_kfree; 74462306a36Sopenharmony_ci if (init_test_sglist(&tsgls->dst) != 0) 74562306a36Sopenharmony_ci goto fail_destroy_src; 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci return tsgls; 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_cifail_destroy_src: 75062306a36Sopenharmony_ci destroy_test_sglist(&tsgls->src); 75162306a36Sopenharmony_cifail_kfree: 75262306a36Sopenharmony_ci kfree(tsgls); 75362306a36Sopenharmony_ci return NULL; 75462306a36Sopenharmony_ci} 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_cistatic void free_cipher_test_sglists(struct cipher_test_sglists *tsgls) 75762306a36Sopenharmony_ci{ 75862306a36Sopenharmony_ci if (tsgls) { 75962306a36Sopenharmony_ci destroy_test_sglist(&tsgls->src); 76062306a36Sopenharmony_ci destroy_test_sglist(&tsgls->dst); 76162306a36Sopenharmony_ci kfree(tsgls); 76262306a36Sopenharmony_ci } 76362306a36Sopenharmony_ci} 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci/* Build the src and dst scatterlists for an skcipher or AEAD test */ 76662306a36Sopenharmony_cistatic int build_cipher_test_sglists(struct cipher_test_sglists *tsgls, 76762306a36Sopenharmony_ci const struct testvec_config *cfg, 76862306a36Sopenharmony_ci unsigned int alignmask, 76962306a36Sopenharmony_ci unsigned int src_total_len, 77062306a36Sopenharmony_ci unsigned int dst_total_len, 77162306a36Sopenharmony_ci const struct kvec *inputs, 77262306a36Sopenharmony_ci unsigned int nr_inputs) 77362306a36Sopenharmony_ci{ 77462306a36Sopenharmony_ci struct iov_iter input; 77562306a36Sopenharmony_ci int err; 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci iov_iter_kvec(&input, ITER_SOURCE, inputs, nr_inputs, src_total_len); 77862306a36Sopenharmony_ci err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask, 77962306a36Sopenharmony_ci cfg->inplace_mode != OUT_OF_PLACE ? 78062306a36Sopenharmony_ci max(dst_total_len, src_total_len) : 78162306a36Sopenharmony_ci src_total_len, 78262306a36Sopenharmony_ci &input, NULL); 78362306a36Sopenharmony_ci if (err) 78462306a36Sopenharmony_ci return err; 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci /* 78762306a36Sopenharmony_ci * In-place crypto operations can use the same scatterlist for both the 78862306a36Sopenharmony_ci * source and destination (req->src == req->dst), or can use separate 78962306a36Sopenharmony_ci * scatterlists (req->src != req->dst) which point to the same 79062306a36Sopenharmony_ci * underlying memory. Make sure to test both cases. 79162306a36Sopenharmony_ci */ 79262306a36Sopenharmony_ci if (cfg->inplace_mode == INPLACE_ONE_SGLIST) { 79362306a36Sopenharmony_ci tsgls->dst.sgl_ptr = tsgls->src.sgl; 79462306a36Sopenharmony_ci tsgls->dst.nents = tsgls->src.nents; 79562306a36Sopenharmony_ci return 0; 79662306a36Sopenharmony_ci } 79762306a36Sopenharmony_ci if (cfg->inplace_mode == INPLACE_TWO_SGLISTS) { 79862306a36Sopenharmony_ci /* 79962306a36Sopenharmony_ci * For now we keep it simple and only test the case where the 80062306a36Sopenharmony_ci * two scatterlists have identical entries, rather than 80162306a36Sopenharmony_ci * different entries that split up the same memory differently. 80262306a36Sopenharmony_ci */ 80362306a36Sopenharmony_ci memcpy(tsgls->dst.sgl, tsgls->src.sgl, 80462306a36Sopenharmony_ci tsgls->src.nents * sizeof(tsgls->src.sgl[0])); 80562306a36Sopenharmony_ci memcpy(tsgls->dst.sgl_saved, tsgls->src.sgl, 80662306a36Sopenharmony_ci tsgls->src.nents * sizeof(tsgls->src.sgl[0])); 80762306a36Sopenharmony_ci tsgls->dst.sgl_ptr = tsgls->dst.sgl; 80862306a36Sopenharmony_ci tsgls->dst.nents = tsgls->src.nents; 80962306a36Sopenharmony_ci return 0; 81062306a36Sopenharmony_ci } 81162306a36Sopenharmony_ci /* Out of place */ 81262306a36Sopenharmony_ci return build_test_sglist(&tsgls->dst, 81362306a36Sopenharmony_ci cfg->dst_divs[0].proportion_of_total ? 81462306a36Sopenharmony_ci cfg->dst_divs : cfg->src_divs, 81562306a36Sopenharmony_ci alignmask, dst_total_len, NULL, NULL); 81662306a36Sopenharmony_ci} 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci/* 81962306a36Sopenharmony_ci * Support for testing passing a misaligned key to setkey(): 82062306a36Sopenharmony_ci * 82162306a36Sopenharmony_ci * If cfg->key_offset is set, copy the key into a new buffer at that offset, 82262306a36Sopenharmony_ci * optionally adding alignmask. Else, just use the key directly. 82362306a36Sopenharmony_ci */ 82462306a36Sopenharmony_cistatic int prepare_keybuf(const u8 *key, unsigned int ksize, 82562306a36Sopenharmony_ci const struct testvec_config *cfg, 82662306a36Sopenharmony_ci unsigned int alignmask, 82762306a36Sopenharmony_ci const u8 **keybuf_ret, const u8 **keyptr_ret) 82862306a36Sopenharmony_ci{ 82962306a36Sopenharmony_ci unsigned int key_offset = cfg->key_offset; 83062306a36Sopenharmony_ci u8 *keybuf = NULL, *keyptr = (u8 *)key; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci if (key_offset != 0) { 83362306a36Sopenharmony_ci if (cfg->key_offset_relative_to_alignmask) 83462306a36Sopenharmony_ci key_offset += alignmask; 83562306a36Sopenharmony_ci keybuf = kmalloc(key_offset + ksize, GFP_KERNEL); 83662306a36Sopenharmony_ci if (!keybuf) 83762306a36Sopenharmony_ci return -ENOMEM; 83862306a36Sopenharmony_ci keyptr = keybuf + key_offset; 83962306a36Sopenharmony_ci memcpy(keyptr, key, ksize); 84062306a36Sopenharmony_ci } 84162306a36Sopenharmony_ci *keybuf_ret = keybuf; 84262306a36Sopenharmony_ci *keyptr_ret = keyptr; 84362306a36Sopenharmony_ci return 0; 84462306a36Sopenharmony_ci} 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci/* Like setkey_f(tfm, key, ksize), but sometimes misalign the key */ 84762306a36Sopenharmony_ci#define do_setkey(setkey_f, tfm, key, ksize, cfg, alignmask) \ 84862306a36Sopenharmony_ci({ \ 84962306a36Sopenharmony_ci const u8 *keybuf, *keyptr; \ 85062306a36Sopenharmony_ci int err; \ 85162306a36Sopenharmony_ci \ 85262306a36Sopenharmony_ci err = prepare_keybuf((key), (ksize), (cfg), (alignmask), \ 85362306a36Sopenharmony_ci &keybuf, &keyptr); \ 85462306a36Sopenharmony_ci if (err == 0) { \ 85562306a36Sopenharmony_ci err = setkey_f((tfm), keyptr, (ksize)); \ 85662306a36Sopenharmony_ci kfree(keybuf); \ 85762306a36Sopenharmony_ci } \ 85862306a36Sopenharmony_ci err; \ 85962306a36Sopenharmony_ci}) 86062306a36Sopenharmony_ci 86162306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci/* 86462306a36Sopenharmony_ci * The fuzz tests use prandom instead of the normal Linux RNG since they don't 86562306a36Sopenharmony_ci * need cryptographically secure random numbers. This greatly improves the 86662306a36Sopenharmony_ci * performance of these tests, especially if they are run before the Linux RNG 86762306a36Sopenharmony_ci * has been initialized or if they are run on a lockdep-enabled kernel. 86862306a36Sopenharmony_ci */ 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_cistatic inline void init_rnd_state(struct rnd_state *rng) 87162306a36Sopenharmony_ci{ 87262306a36Sopenharmony_ci prandom_seed_state(rng, get_random_u64()); 87362306a36Sopenharmony_ci} 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic inline u8 prandom_u8(struct rnd_state *rng) 87662306a36Sopenharmony_ci{ 87762306a36Sopenharmony_ci return prandom_u32_state(rng); 87862306a36Sopenharmony_ci} 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_cistatic inline u32 prandom_u32_below(struct rnd_state *rng, u32 ceil) 88162306a36Sopenharmony_ci{ 88262306a36Sopenharmony_ci /* 88362306a36Sopenharmony_ci * This is slightly biased for non-power-of-2 values of 'ceil', but this 88462306a36Sopenharmony_ci * isn't important here. 88562306a36Sopenharmony_ci */ 88662306a36Sopenharmony_ci return prandom_u32_state(rng) % ceil; 88762306a36Sopenharmony_ci} 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_cistatic inline bool prandom_bool(struct rnd_state *rng) 89062306a36Sopenharmony_ci{ 89162306a36Sopenharmony_ci return prandom_u32_below(rng, 2); 89262306a36Sopenharmony_ci} 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_cistatic inline u32 prandom_u32_inclusive(struct rnd_state *rng, 89562306a36Sopenharmony_ci u32 floor, u32 ceil) 89662306a36Sopenharmony_ci{ 89762306a36Sopenharmony_ci return floor + prandom_u32_below(rng, ceil - floor + 1); 89862306a36Sopenharmony_ci} 89962306a36Sopenharmony_ci 90062306a36Sopenharmony_ci/* Generate a random length in range [0, max_len], but prefer smaller values */ 90162306a36Sopenharmony_cistatic unsigned int generate_random_length(struct rnd_state *rng, 90262306a36Sopenharmony_ci unsigned int max_len) 90362306a36Sopenharmony_ci{ 90462306a36Sopenharmony_ci unsigned int len = prandom_u32_below(rng, max_len + 1); 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci switch (prandom_u32_below(rng, 4)) { 90762306a36Sopenharmony_ci case 0: 90862306a36Sopenharmony_ci return len % 64; 90962306a36Sopenharmony_ci case 1: 91062306a36Sopenharmony_ci return len % 256; 91162306a36Sopenharmony_ci case 2: 91262306a36Sopenharmony_ci return len % 1024; 91362306a36Sopenharmony_ci default: 91462306a36Sopenharmony_ci return len; 91562306a36Sopenharmony_ci } 91662306a36Sopenharmony_ci} 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci/* Flip a random bit in the given nonempty data buffer */ 91962306a36Sopenharmony_cistatic void flip_random_bit(struct rnd_state *rng, u8 *buf, size_t size) 92062306a36Sopenharmony_ci{ 92162306a36Sopenharmony_ci size_t bitpos; 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci bitpos = prandom_u32_below(rng, size * 8); 92462306a36Sopenharmony_ci buf[bitpos / 8] ^= 1 << (bitpos % 8); 92562306a36Sopenharmony_ci} 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci/* Flip a random byte in the given nonempty data buffer */ 92862306a36Sopenharmony_cistatic void flip_random_byte(struct rnd_state *rng, u8 *buf, size_t size) 92962306a36Sopenharmony_ci{ 93062306a36Sopenharmony_ci buf[prandom_u32_below(rng, size)] ^= 0xff; 93162306a36Sopenharmony_ci} 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci/* Sometimes make some random changes to the given nonempty data buffer */ 93462306a36Sopenharmony_cistatic void mutate_buffer(struct rnd_state *rng, u8 *buf, size_t size) 93562306a36Sopenharmony_ci{ 93662306a36Sopenharmony_ci size_t num_flips; 93762306a36Sopenharmony_ci size_t i; 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci /* Sometimes flip some bits */ 94062306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) { 94162306a36Sopenharmony_ci num_flips = min_t(size_t, 1 << prandom_u32_below(rng, 8), 94262306a36Sopenharmony_ci size * 8); 94362306a36Sopenharmony_ci for (i = 0; i < num_flips; i++) 94462306a36Sopenharmony_ci flip_random_bit(rng, buf, size); 94562306a36Sopenharmony_ci } 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci /* Sometimes flip some bytes */ 94862306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) { 94962306a36Sopenharmony_ci num_flips = min_t(size_t, 1 << prandom_u32_below(rng, 8), size); 95062306a36Sopenharmony_ci for (i = 0; i < num_flips; i++) 95162306a36Sopenharmony_ci flip_random_byte(rng, buf, size); 95262306a36Sopenharmony_ci } 95362306a36Sopenharmony_ci} 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci/* Randomly generate 'count' bytes, but sometimes make them "interesting" */ 95662306a36Sopenharmony_cistatic void generate_random_bytes(struct rnd_state *rng, u8 *buf, size_t count) 95762306a36Sopenharmony_ci{ 95862306a36Sopenharmony_ci u8 b; 95962306a36Sopenharmony_ci u8 increment; 96062306a36Sopenharmony_ci size_t i; 96162306a36Sopenharmony_ci 96262306a36Sopenharmony_ci if (count == 0) 96362306a36Sopenharmony_ci return; 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci switch (prandom_u32_below(rng, 8)) { /* Choose a generation strategy */ 96662306a36Sopenharmony_ci case 0: 96762306a36Sopenharmony_ci case 1: 96862306a36Sopenharmony_ci /* All the same byte, plus optional mutations */ 96962306a36Sopenharmony_ci switch (prandom_u32_below(rng, 4)) { 97062306a36Sopenharmony_ci case 0: 97162306a36Sopenharmony_ci b = 0x00; 97262306a36Sopenharmony_ci break; 97362306a36Sopenharmony_ci case 1: 97462306a36Sopenharmony_ci b = 0xff; 97562306a36Sopenharmony_ci break; 97662306a36Sopenharmony_ci default: 97762306a36Sopenharmony_ci b = prandom_u8(rng); 97862306a36Sopenharmony_ci break; 97962306a36Sopenharmony_ci } 98062306a36Sopenharmony_ci memset(buf, b, count); 98162306a36Sopenharmony_ci mutate_buffer(rng, buf, count); 98262306a36Sopenharmony_ci break; 98362306a36Sopenharmony_ci case 2: 98462306a36Sopenharmony_ci /* Ascending or descending bytes, plus optional mutations */ 98562306a36Sopenharmony_ci increment = prandom_u8(rng); 98662306a36Sopenharmony_ci b = prandom_u8(rng); 98762306a36Sopenharmony_ci for (i = 0; i < count; i++, b += increment) 98862306a36Sopenharmony_ci buf[i] = b; 98962306a36Sopenharmony_ci mutate_buffer(rng, buf, count); 99062306a36Sopenharmony_ci break; 99162306a36Sopenharmony_ci default: 99262306a36Sopenharmony_ci /* Fully random bytes */ 99362306a36Sopenharmony_ci prandom_bytes_state(rng, buf, count); 99462306a36Sopenharmony_ci } 99562306a36Sopenharmony_ci} 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_cistatic char *generate_random_sgl_divisions(struct rnd_state *rng, 99862306a36Sopenharmony_ci struct test_sg_division *divs, 99962306a36Sopenharmony_ci size_t max_divs, char *p, char *end, 100062306a36Sopenharmony_ci bool gen_flushes, u32 req_flags) 100162306a36Sopenharmony_ci{ 100262306a36Sopenharmony_ci struct test_sg_division *div = divs; 100362306a36Sopenharmony_ci unsigned int remaining = TEST_SG_TOTAL; 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_ci do { 100662306a36Sopenharmony_ci unsigned int this_len; 100762306a36Sopenharmony_ci const char *flushtype_str; 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci if (div == &divs[max_divs - 1] || prandom_bool(rng)) 101062306a36Sopenharmony_ci this_len = remaining; 101162306a36Sopenharmony_ci else 101262306a36Sopenharmony_ci this_len = prandom_u32_inclusive(rng, 1, remaining); 101362306a36Sopenharmony_ci div->proportion_of_total = this_len; 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) 101662306a36Sopenharmony_ci div->offset = prandom_u32_inclusive(rng, 101762306a36Sopenharmony_ci PAGE_SIZE - 128, 101862306a36Sopenharmony_ci PAGE_SIZE - 1); 101962306a36Sopenharmony_ci else if (prandom_bool(rng)) 102062306a36Sopenharmony_ci div->offset = prandom_u32_below(rng, 32); 102162306a36Sopenharmony_ci else 102262306a36Sopenharmony_ci div->offset = prandom_u32_below(rng, PAGE_SIZE); 102362306a36Sopenharmony_ci if (prandom_u32_below(rng, 8) == 0) 102462306a36Sopenharmony_ci div->offset_relative_to_alignmask = true; 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci div->flush_type = FLUSH_TYPE_NONE; 102762306a36Sopenharmony_ci if (gen_flushes) { 102862306a36Sopenharmony_ci switch (prandom_u32_below(rng, 4)) { 102962306a36Sopenharmony_ci case 0: 103062306a36Sopenharmony_ci div->flush_type = FLUSH_TYPE_REIMPORT; 103162306a36Sopenharmony_ci break; 103262306a36Sopenharmony_ci case 1: 103362306a36Sopenharmony_ci div->flush_type = FLUSH_TYPE_FLUSH; 103462306a36Sopenharmony_ci break; 103562306a36Sopenharmony_ci } 103662306a36Sopenharmony_ci } 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci if (div->flush_type != FLUSH_TYPE_NONE && 103962306a36Sopenharmony_ci !(req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) && 104062306a36Sopenharmony_ci prandom_bool(rng)) 104162306a36Sopenharmony_ci div->nosimd = true; 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci switch (div->flush_type) { 104462306a36Sopenharmony_ci case FLUSH_TYPE_FLUSH: 104562306a36Sopenharmony_ci if (div->nosimd) 104662306a36Sopenharmony_ci flushtype_str = "<flush,nosimd>"; 104762306a36Sopenharmony_ci else 104862306a36Sopenharmony_ci flushtype_str = "<flush>"; 104962306a36Sopenharmony_ci break; 105062306a36Sopenharmony_ci case FLUSH_TYPE_REIMPORT: 105162306a36Sopenharmony_ci if (div->nosimd) 105262306a36Sopenharmony_ci flushtype_str = "<reimport,nosimd>"; 105362306a36Sopenharmony_ci else 105462306a36Sopenharmony_ci flushtype_str = "<reimport>"; 105562306a36Sopenharmony_ci break; 105662306a36Sopenharmony_ci default: 105762306a36Sopenharmony_ci flushtype_str = ""; 105862306a36Sopenharmony_ci break; 105962306a36Sopenharmony_ci } 106062306a36Sopenharmony_ci 106162306a36Sopenharmony_ci BUILD_BUG_ON(TEST_SG_TOTAL != 10000); /* for "%u.%u%%" */ 106262306a36Sopenharmony_ci p += scnprintf(p, end - p, "%s%u.%u%%@%s+%u%s", flushtype_str, 106362306a36Sopenharmony_ci this_len / 100, this_len % 100, 106462306a36Sopenharmony_ci div->offset_relative_to_alignmask ? 106562306a36Sopenharmony_ci "alignmask" : "", 106662306a36Sopenharmony_ci div->offset, this_len == remaining ? "" : ", "); 106762306a36Sopenharmony_ci remaining -= this_len; 106862306a36Sopenharmony_ci div++; 106962306a36Sopenharmony_ci } while (remaining); 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci return p; 107262306a36Sopenharmony_ci} 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_ci/* Generate a random testvec_config for fuzz testing */ 107562306a36Sopenharmony_cistatic void generate_random_testvec_config(struct rnd_state *rng, 107662306a36Sopenharmony_ci struct testvec_config *cfg, 107762306a36Sopenharmony_ci char *name, size_t max_namelen) 107862306a36Sopenharmony_ci{ 107962306a36Sopenharmony_ci char *p = name; 108062306a36Sopenharmony_ci char * const end = name + max_namelen; 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci memset(cfg, 0, sizeof(*cfg)); 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci cfg->name = name; 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_ci p += scnprintf(p, end - p, "random:"); 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci switch (prandom_u32_below(rng, 4)) { 108962306a36Sopenharmony_ci case 0: 109062306a36Sopenharmony_ci case 1: 109162306a36Sopenharmony_ci cfg->inplace_mode = OUT_OF_PLACE; 109262306a36Sopenharmony_ci break; 109362306a36Sopenharmony_ci case 2: 109462306a36Sopenharmony_ci cfg->inplace_mode = INPLACE_ONE_SGLIST; 109562306a36Sopenharmony_ci p += scnprintf(p, end - p, " inplace_one_sglist"); 109662306a36Sopenharmony_ci break; 109762306a36Sopenharmony_ci default: 109862306a36Sopenharmony_ci cfg->inplace_mode = INPLACE_TWO_SGLISTS; 109962306a36Sopenharmony_ci p += scnprintf(p, end - p, " inplace_two_sglists"); 110062306a36Sopenharmony_ci break; 110162306a36Sopenharmony_ci } 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci if (prandom_bool(rng)) { 110462306a36Sopenharmony_ci cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP; 110562306a36Sopenharmony_ci p += scnprintf(p, end - p, " may_sleep"); 110662306a36Sopenharmony_ci } 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ci switch (prandom_u32_below(rng, 4)) { 110962306a36Sopenharmony_ci case 0: 111062306a36Sopenharmony_ci cfg->finalization_type = FINALIZATION_TYPE_FINAL; 111162306a36Sopenharmony_ci p += scnprintf(p, end - p, " use_final"); 111262306a36Sopenharmony_ci break; 111362306a36Sopenharmony_ci case 1: 111462306a36Sopenharmony_ci cfg->finalization_type = FINALIZATION_TYPE_FINUP; 111562306a36Sopenharmony_ci p += scnprintf(p, end - p, " use_finup"); 111662306a36Sopenharmony_ci break; 111762306a36Sopenharmony_ci default: 111862306a36Sopenharmony_ci cfg->finalization_type = FINALIZATION_TYPE_DIGEST; 111962306a36Sopenharmony_ci p += scnprintf(p, end - p, " use_digest"); 112062306a36Sopenharmony_ci break; 112162306a36Sopenharmony_ci } 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci if (!(cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) && prandom_bool(rng)) { 112462306a36Sopenharmony_ci cfg->nosimd = true; 112562306a36Sopenharmony_ci p += scnprintf(p, end - p, " nosimd"); 112662306a36Sopenharmony_ci } 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci p += scnprintf(p, end - p, " src_divs=["); 112962306a36Sopenharmony_ci p = generate_random_sgl_divisions(rng, cfg->src_divs, 113062306a36Sopenharmony_ci ARRAY_SIZE(cfg->src_divs), p, end, 113162306a36Sopenharmony_ci (cfg->finalization_type != 113262306a36Sopenharmony_ci FINALIZATION_TYPE_DIGEST), 113362306a36Sopenharmony_ci cfg->req_flags); 113462306a36Sopenharmony_ci p += scnprintf(p, end - p, "]"); 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_ci if (cfg->inplace_mode == OUT_OF_PLACE && prandom_bool(rng)) { 113762306a36Sopenharmony_ci p += scnprintf(p, end - p, " dst_divs=["); 113862306a36Sopenharmony_ci p = generate_random_sgl_divisions(rng, cfg->dst_divs, 113962306a36Sopenharmony_ci ARRAY_SIZE(cfg->dst_divs), 114062306a36Sopenharmony_ci p, end, false, 114162306a36Sopenharmony_ci cfg->req_flags); 114262306a36Sopenharmony_ci p += scnprintf(p, end - p, "]"); 114362306a36Sopenharmony_ci } 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci if (prandom_bool(rng)) { 114662306a36Sopenharmony_ci cfg->iv_offset = prandom_u32_inclusive(rng, 1, 114762306a36Sopenharmony_ci MAX_ALGAPI_ALIGNMASK); 114862306a36Sopenharmony_ci p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset); 114962306a36Sopenharmony_ci } 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_ci if (prandom_bool(rng)) { 115262306a36Sopenharmony_ci cfg->key_offset = prandom_u32_inclusive(rng, 1, 115362306a36Sopenharmony_ci MAX_ALGAPI_ALIGNMASK); 115462306a36Sopenharmony_ci p += scnprintf(p, end - p, " key_offset=%u", cfg->key_offset); 115562306a36Sopenharmony_ci } 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci WARN_ON_ONCE(!valid_testvec_config(cfg)); 115862306a36Sopenharmony_ci} 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_cistatic void crypto_disable_simd_for_test(void) 116162306a36Sopenharmony_ci{ 116262306a36Sopenharmony_ci migrate_disable(); 116362306a36Sopenharmony_ci __this_cpu_write(crypto_simd_disabled_for_test, true); 116462306a36Sopenharmony_ci} 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_cistatic void crypto_reenable_simd_for_test(void) 116762306a36Sopenharmony_ci{ 116862306a36Sopenharmony_ci __this_cpu_write(crypto_simd_disabled_for_test, false); 116962306a36Sopenharmony_ci migrate_enable(); 117062306a36Sopenharmony_ci} 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci/* 117362306a36Sopenharmony_ci * Given an algorithm name, build the name of the generic implementation of that 117462306a36Sopenharmony_ci * algorithm, assuming the usual naming convention. Specifically, this appends 117562306a36Sopenharmony_ci * "-generic" to every part of the name that is not a template name. Examples: 117662306a36Sopenharmony_ci * 117762306a36Sopenharmony_ci * aes => aes-generic 117862306a36Sopenharmony_ci * cbc(aes) => cbc(aes-generic) 117962306a36Sopenharmony_ci * cts(cbc(aes)) => cts(cbc(aes-generic)) 118062306a36Sopenharmony_ci * rfc7539(chacha20,poly1305) => rfc7539(chacha20-generic,poly1305-generic) 118162306a36Sopenharmony_ci * 118262306a36Sopenharmony_ci * Return: 0 on success, or -ENAMETOOLONG if the generic name would be too long 118362306a36Sopenharmony_ci */ 118462306a36Sopenharmony_cistatic int build_generic_driver_name(const char *algname, 118562306a36Sopenharmony_ci char driver_name[CRYPTO_MAX_ALG_NAME]) 118662306a36Sopenharmony_ci{ 118762306a36Sopenharmony_ci const char *in = algname; 118862306a36Sopenharmony_ci char *out = driver_name; 118962306a36Sopenharmony_ci size_t len = strlen(algname); 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci if (len >= CRYPTO_MAX_ALG_NAME) 119262306a36Sopenharmony_ci goto too_long; 119362306a36Sopenharmony_ci do { 119462306a36Sopenharmony_ci const char *in_saved = in; 119562306a36Sopenharmony_ci 119662306a36Sopenharmony_ci while (*in && *in != '(' && *in != ')' && *in != ',') 119762306a36Sopenharmony_ci *out++ = *in++; 119862306a36Sopenharmony_ci if (*in != '(' && in > in_saved) { 119962306a36Sopenharmony_ci len += 8; 120062306a36Sopenharmony_ci if (len >= CRYPTO_MAX_ALG_NAME) 120162306a36Sopenharmony_ci goto too_long; 120262306a36Sopenharmony_ci memcpy(out, "-generic", 8); 120362306a36Sopenharmony_ci out += 8; 120462306a36Sopenharmony_ci } 120562306a36Sopenharmony_ci } while ((*out++ = *in++) != '\0'); 120662306a36Sopenharmony_ci return 0; 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_citoo_long: 120962306a36Sopenharmony_ci pr_err("alg: generic driver name for \"%s\" would be too long\n", 121062306a36Sopenharmony_ci algname); 121162306a36Sopenharmony_ci return -ENAMETOOLONG; 121262306a36Sopenharmony_ci} 121362306a36Sopenharmony_ci#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 121462306a36Sopenharmony_cistatic void crypto_disable_simd_for_test(void) 121562306a36Sopenharmony_ci{ 121662306a36Sopenharmony_ci} 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_cistatic void crypto_reenable_simd_for_test(void) 121962306a36Sopenharmony_ci{ 122062306a36Sopenharmony_ci} 122162306a36Sopenharmony_ci#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_cistatic int build_hash_sglist(struct test_sglist *tsgl, 122462306a36Sopenharmony_ci const struct hash_testvec *vec, 122562306a36Sopenharmony_ci const struct testvec_config *cfg, 122662306a36Sopenharmony_ci unsigned int alignmask, 122762306a36Sopenharmony_ci const struct test_sg_division *divs[XBUFSIZE]) 122862306a36Sopenharmony_ci{ 122962306a36Sopenharmony_ci struct kvec kv; 123062306a36Sopenharmony_ci struct iov_iter input; 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_ci kv.iov_base = (void *)vec->plaintext; 123362306a36Sopenharmony_ci kv.iov_len = vec->psize; 123462306a36Sopenharmony_ci iov_iter_kvec(&input, ITER_SOURCE, &kv, 1, vec->psize); 123562306a36Sopenharmony_ci return build_test_sglist(tsgl, cfg->src_divs, alignmask, vec->psize, 123662306a36Sopenharmony_ci &input, divs); 123762306a36Sopenharmony_ci} 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_cistatic int check_hash_result(const char *type, 124062306a36Sopenharmony_ci const u8 *result, unsigned int digestsize, 124162306a36Sopenharmony_ci const struct hash_testvec *vec, 124262306a36Sopenharmony_ci const char *vec_name, 124362306a36Sopenharmony_ci const char *driver, 124462306a36Sopenharmony_ci const struct testvec_config *cfg) 124562306a36Sopenharmony_ci{ 124662306a36Sopenharmony_ci if (memcmp(result, vec->digest, digestsize) != 0) { 124762306a36Sopenharmony_ci pr_err("alg: %s: %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n", 124862306a36Sopenharmony_ci type, driver, vec_name, cfg->name); 124962306a36Sopenharmony_ci return -EINVAL; 125062306a36Sopenharmony_ci } 125162306a36Sopenharmony_ci if (!testmgr_is_poison(&result[digestsize], TESTMGR_POISON_LEN)) { 125262306a36Sopenharmony_ci pr_err("alg: %s: %s overran result buffer on test vector %s, cfg=\"%s\"\n", 125362306a36Sopenharmony_ci type, driver, vec_name, cfg->name); 125462306a36Sopenharmony_ci return -EOVERFLOW; 125562306a36Sopenharmony_ci } 125662306a36Sopenharmony_ci return 0; 125762306a36Sopenharmony_ci} 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_cistatic inline int check_shash_op(const char *op, int err, 126062306a36Sopenharmony_ci const char *driver, const char *vec_name, 126162306a36Sopenharmony_ci const struct testvec_config *cfg) 126262306a36Sopenharmony_ci{ 126362306a36Sopenharmony_ci if (err) 126462306a36Sopenharmony_ci pr_err("alg: shash: %s %s() failed with err %d on test vector %s, cfg=\"%s\"\n", 126562306a36Sopenharmony_ci driver, op, err, vec_name, cfg->name); 126662306a36Sopenharmony_ci return err; 126762306a36Sopenharmony_ci} 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci/* Test one hash test vector in one configuration, using the shash API */ 127062306a36Sopenharmony_cistatic int test_shash_vec_cfg(const struct hash_testvec *vec, 127162306a36Sopenharmony_ci const char *vec_name, 127262306a36Sopenharmony_ci const struct testvec_config *cfg, 127362306a36Sopenharmony_ci struct shash_desc *desc, 127462306a36Sopenharmony_ci struct test_sglist *tsgl, 127562306a36Sopenharmony_ci u8 *hashstate) 127662306a36Sopenharmony_ci{ 127762306a36Sopenharmony_ci struct crypto_shash *tfm = desc->tfm; 127862306a36Sopenharmony_ci const unsigned int alignmask = crypto_shash_alignmask(tfm); 127962306a36Sopenharmony_ci const unsigned int digestsize = crypto_shash_digestsize(tfm); 128062306a36Sopenharmony_ci const unsigned int statesize = crypto_shash_statesize(tfm); 128162306a36Sopenharmony_ci const char *driver = crypto_shash_driver_name(tfm); 128262306a36Sopenharmony_ci const struct test_sg_division *divs[XBUFSIZE]; 128362306a36Sopenharmony_ci unsigned int i; 128462306a36Sopenharmony_ci u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN]; 128562306a36Sopenharmony_ci int err; 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_ci /* Set the key, if specified */ 128862306a36Sopenharmony_ci if (vec->ksize) { 128962306a36Sopenharmony_ci err = do_setkey(crypto_shash_setkey, tfm, vec->key, vec->ksize, 129062306a36Sopenharmony_ci cfg, alignmask); 129162306a36Sopenharmony_ci if (err) { 129262306a36Sopenharmony_ci if (err == vec->setkey_error) 129362306a36Sopenharmony_ci return 0; 129462306a36Sopenharmony_ci pr_err("alg: shash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n", 129562306a36Sopenharmony_ci driver, vec_name, vec->setkey_error, err, 129662306a36Sopenharmony_ci crypto_shash_get_flags(tfm)); 129762306a36Sopenharmony_ci return err; 129862306a36Sopenharmony_ci } 129962306a36Sopenharmony_ci if (vec->setkey_error) { 130062306a36Sopenharmony_ci pr_err("alg: shash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n", 130162306a36Sopenharmony_ci driver, vec_name, vec->setkey_error); 130262306a36Sopenharmony_ci return -EINVAL; 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci } 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci /* Build the scatterlist for the source data */ 130762306a36Sopenharmony_ci err = build_hash_sglist(tsgl, vec, cfg, alignmask, divs); 130862306a36Sopenharmony_ci if (err) { 130962306a36Sopenharmony_ci pr_err("alg: shash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n", 131062306a36Sopenharmony_ci driver, vec_name, cfg->name); 131162306a36Sopenharmony_ci return err; 131262306a36Sopenharmony_ci } 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ci /* Do the actual hashing */ 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci testmgr_poison(desc->__ctx, crypto_shash_descsize(tfm)); 131762306a36Sopenharmony_ci testmgr_poison(result, digestsize + TESTMGR_POISON_LEN); 131862306a36Sopenharmony_ci 131962306a36Sopenharmony_ci if (cfg->finalization_type == FINALIZATION_TYPE_DIGEST || 132062306a36Sopenharmony_ci vec->digest_error) { 132162306a36Sopenharmony_ci /* Just using digest() */ 132262306a36Sopenharmony_ci if (tsgl->nents != 1) 132362306a36Sopenharmony_ci return 0; 132462306a36Sopenharmony_ci if (cfg->nosimd) 132562306a36Sopenharmony_ci crypto_disable_simd_for_test(); 132662306a36Sopenharmony_ci err = crypto_shash_digest(desc, sg_virt(&tsgl->sgl[0]), 132762306a36Sopenharmony_ci tsgl->sgl[0].length, result); 132862306a36Sopenharmony_ci if (cfg->nosimd) 132962306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 133062306a36Sopenharmony_ci if (err) { 133162306a36Sopenharmony_ci if (err == vec->digest_error) 133262306a36Sopenharmony_ci return 0; 133362306a36Sopenharmony_ci pr_err("alg: shash: %s digest() failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n", 133462306a36Sopenharmony_ci driver, vec_name, vec->digest_error, err, 133562306a36Sopenharmony_ci cfg->name); 133662306a36Sopenharmony_ci return err; 133762306a36Sopenharmony_ci } 133862306a36Sopenharmony_ci if (vec->digest_error) { 133962306a36Sopenharmony_ci pr_err("alg: shash: %s digest() unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n", 134062306a36Sopenharmony_ci driver, vec_name, vec->digest_error, cfg->name); 134162306a36Sopenharmony_ci return -EINVAL; 134262306a36Sopenharmony_ci } 134362306a36Sopenharmony_ci goto result_ready; 134462306a36Sopenharmony_ci } 134562306a36Sopenharmony_ci 134662306a36Sopenharmony_ci /* Using init(), zero or more update(), then final() or finup() */ 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci if (cfg->nosimd) 134962306a36Sopenharmony_ci crypto_disable_simd_for_test(); 135062306a36Sopenharmony_ci err = crypto_shash_init(desc); 135162306a36Sopenharmony_ci if (cfg->nosimd) 135262306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 135362306a36Sopenharmony_ci err = check_shash_op("init", err, driver, vec_name, cfg); 135462306a36Sopenharmony_ci if (err) 135562306a36Sopenharmony_ci return err; 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci for (i = 0; i < tsgl->nents; i++) { 135862306a36Sopenharmony_ci if (i + 1 == tsgl->nents && 135962306a36Sopenharmony_ci cfg->finalization_type == FINALIZATION_TYPE_FINUP) { 136062306a36Sopenharmony_ci if (divs[i]->nosimd) 136162306a36Sopenharmony_ci crypto_disable_simd_for_test(); 136262306a36Sopenharmony_ci err = crypto_shash_finup(desc, sg_virt(&tsgl->sgl[i]), 136362306a36Sopenharmony_ci tsgl->sgl[i].length, result); 136462306a36Sopenharmony_ci if (divs[i]->nosimd) 136562306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 136662306a36Sopenharmony_ci err = check_shash_op("finup", err, driver, vec_name, 136762306a36Sopenharmony_ci cfg); 136862306a36Sopenharmony_ci if (err) 136962306a36Sopenharmony_ci return err; 137062306a36Sopenharmony_ci goto result_ready; 137162306a36Sopenharmony_ci } 137262306a36Sopenharmony_ci if (divs[i]->nosimd) 137362306a36Sopenharmony_ci crypto_disable_simd_for_test(); 137462306a36Sopenharmony_ci err = crypto_shash_update(desc, sg_virt(&tsgl->sgl[i]), 137562306a36Sopenharmony_ci tsgl->sgl[i].length); 137662306a36Sopenharmony_ci if (divs[i]->nosimd) 137762306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 137862306a36Sopenharmony_ci err = check_shash_op("update", err, driver, vec_name, cfg); 137962306a36Sopenharmony_ci if (err) 138062306a36Sopenharmony_ci return err; 138162306a36Sopenharmony_ci if (divs[i]->flush_type == FLUSH_TYPE_REIMPORT) { 138262306a36Sopenharmony_ci /* Test ->export() and ->import() */ 138362306a36Sopenharmony_ci testmgr_poison(hashstate + statesize, 138462306a36Sopenharmony_ci TESTMGR_POISON_LEN); 138562306a36Sopenharmony_ci err = crypto_shash_export(desc, hashstate); 138662306a36Sopenharmony_ci err = check_shash_op("export", err, driver, vec_name, 138762306a36Sopenharmony_ci cfg); 138862306a36Sopenharmony_ci if (err) 138962306a36Sopenharmony_ci return err; 139062306a36Sopenharmony_ci if (!testmgr_is_poison(hashstate + statesize, 139162306a36Sopenharmony_ci TESTMGR_POISON_LEN)) { 139262306a36Sopenharmony_ci pr_err("alg: shash: %s export() overran state buffer on test vector %s, cfg=\"%s\"\n", 139362306a36Sopenharmony_ci driver, vec_name, cfg->name); 139462306a36Sopenharmony_ci return -EOVERFLOW; 139562306a36Sopenharmony_ci } 139662306a36Sopenharmony_ci testmgr_poison(desc->__ctx, crypto_shash_descsize(tfm)); 139762306a36Sopenharmony_ci err = crypto_shash_import(desc, hashstate); 139862306a36Sopenharmony_ci err = check_shash_op("import", err, driver, vec_name, 139962306a36Sopenharmony_ci cfg); 140062306a36Sopenharmony_ci if (err) 140162306a36Sopenharmony_ci return err; 140262306a36Sopenharmony_ci } 140362306a36Sopenharmony_ci } 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci if (cfg->nosimd) 140662306a36Sopenharmony_ci crypto_disable_simd_for_test(); 140762306a36Sopenharmony_ci err = crypto_shash_final(desc, result); 140862306a36Sopenharmony_ci if (cfg->nosimd) 140962306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 141062306a36Sopenharmony_ci err = check_shash_op("final", err, driver, vec_name, cfg); 141162306a36Sopenharmony_ci if (err) 141262306a36Sopenharmony_ci return err; 141362306a36Sopenharmony_ciresult_ready: 141462306a36Sopenharmony_ci return check_hash_result("shash", result, digestsize, vec, vec_name, 141562306a36Sopenharmony_ci driver, cfg); 141662306a36Sopenharmony_ci} 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_cistatic int do_ahash_op(int (*op)(struct ahash_request *req), 141962306a36Sopenharmony_ci struct ahash_request *req, 142062306a36Sopenharmony_ci struct crypto_wait *wait, bool nosimd) 142162306a36Sopenharmony_ci{ 142262306a36Sopenharmony_ci int err; 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci if (nosimd) 142562306a36Sopenharmony_ci crypto_disable_simd_for_test(); 142662306a36Sopenharmony_ci 142762306a36Sopenharmony_ci err = op(req); 142862306a36Sopenharmony_ci 142962306a36Sopenharmony_ci if (nosimd) 143062306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci return crypto_wait_req(err, wait); 143362306a36Sopenharmony_ci} 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_cistatic int check_nonfinal_ahash_op(const char *op, int err, 143662306a36Sopenharmony_ci u8 *result, unsigned int digestsize, 143762306a36Sopenharmony_ci const char *driver, const char *vec_name, 143862306a36Sopenharmony_ci const struct testvec_config *cfg) 143962306a36Sopenharmony_ci{ 144062306a36Sopenharmony_ci if (err) { 144162306a36Sopenharmony_ci pr_err("alg: ahash: %s %s() failed with err %d on test vector %s, cfg=\"%s\"\n", 144262306a36Sopenharmony_ci driver, op, err, vec_name, cfg->name); 144362306a36Sopenharmony_ci return err; 144462306a36Sopenharmony_ci } 144562306a36Sopenharmony_ci if (!testmgr_is_poison(result, digestsize)) { 144662306a36Sopenharmony_ci pr_err("alg: ahash: %s %s() used result buffer on test vector %s, cfg=\"%s\"\n", 144762306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 144862306a36Sopenharmony_ci return -EINVAL; 144962306a36Sopenharmony_ci } 145062306a36Sopenharmony_ci return 0; 145162306a36Sopenharmony_ci} 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci/* Test one hash test vector in one configuration, using the ahash API */ 145462306a36Sopenharmony_cistatic int test_ahash_vec_cfg(const struct hash_testvec *vec, 145562306a36Sopenharmony_ci const char *vec_name, 145662306a36Sopenharmony_ci const struct testvec_config *cfg, 145762306a36Sopenharmony_ci struct ahash_request *req, 145862306a36Sopenharmony_ci struct test_sglist *tsgl, 145962306a36Sopenharmony_ci u8 *hashstate) 146062306a36Sopenharmony_ci{ 146162306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 146262306a36Sopenharmony_ci const unsigned int alignmask = crypto_ahash_alignmask(tfm); 146362306a36Sopenharmony_ci const unsigned int digestsize = crypto_ahash_digestsize(tfm); 146462306a36Sopenharmony_ci const unsigned int statesize = crypto_ahash_statesize(tfm); 146562306a36Sopenharmony_ci const char *driver = crypto_ahash_driver_name(tfm); 146662306a36Sopenharmony_ci const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 146762306a36Sopenharmony_ci const struct test_sg_division *divs[XBUFSIZE]; 146862306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 146962306a36Sopenharmony_ci unsigned int i; 147062306a36Sopenharmony_ci struct scatterlist *pending_sgl; 147162306a36Sopenharmony_ci unsigned int pending_len; 147262306a36Sopenharmony_ci u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN]; 147362306a36Sopenharmony_ci int err; 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci /* Set the key, if specified */ 147662306a36Sopenharmony_ci if (vec->ksize) { 147762306a36Sopenharmony_ci err = do_setkey(crypto_ahash_setkey, tfm, vec->key, vec->ksize, 147862306a36Sopenharmony_ci cfg, alignmask); 147962306a36Sopenharmony_ci if (err) { 148062306a36Sopenharmony_ci if (err == vec->setkey_error) 148162306a36Sopenharmony_ci return 0; 148262306a36Sopenharmony_ci pr_err("alg: ahash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n", 148362306a36Sopenharmony_ci driver, vec_name, vec->setkey_error, err, 148462306a36Sopenharmony_ci crypto_ahash_get_flags(tfm)); 148562306a36Sopenharmony_ci return err; 148662306a36Sopenharmony_ci } 148762306a36Sopenharmony_ci if (vec->setkey_error) { 148862306a36Sopenharmony_ci pr_err("alg: ahash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n", 148962306a36Sopenharmony_ci driver, vec_name, vec->setkey_error); 149062306a36Sopenharmony_ci return -EINVAL; 149162306a36Sopenharmony_ci } 149262306a36Sopenharmony_ci } 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci /* Build the scatterlist for the source data */ 149562306a36Sopenharmony_ci err = build_hash_sglist(tsgl, vec, cfg, alignmask, divs); 149662306a36Sopenharmony_ci if (err) { 149762306a36Sopenharmony_ci pr_err("alg: ahash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n", 149862306a36Sopenharmony_ci driver, vec_name, cfg->name); 149962306a36Sopenharmony_ci return err; 150062306a36Sopenharmony_ci } 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci /* Do the actual hashing */ 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm)); 150562306a36Sopenharmony_ci testmgr_poison(result, digestsize + TESTMGR_POISON_LEN); 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci if (cfg->finalization_type == FINALIZATION_TYPE_DIGEST || 150862306a36Sopenharmony_ci vec->digest_error) { 150962306a36Sopenharmony_ci /* Just using digest() */ 151062306a36Sopenharmony_ci ahash_request_set_callback(req, req_flags, crypto_req_done, 151162306a36Sopenharmony_ci &wait); 151262306a36Sopenharmony_ci ahash_request_set_crypt(req, tsgl->sgl, result, vec->psize); 151362306a36Sopenharmony_ci err = do_ahash_op(crypto_ahash_digest, req, &wait, cfg->nosimd); 151462306a36Sopenharmony_ci if (err) { 151562306a36Sopenharmony_ci if (err == vec->digest_error) 151662306a36Sopenharmony_ci return 0; 151762306a36Sopenharmony_ci pr_err("alg: ahash: %s digest() failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n", 151862306a36Sopenharmony_ci driver, vec_name, vec->digest_error, err, 151962306a36Sopenharmony_ci cfg->name); 152062306a36Sopenharmony_ci return err; 152162306a36Sopenharmony_ci } 152262306a36Sopenharmony_ci if (vec->digest_error) { 152362306a36Sopenharmony_ci pr_err("alg: ahash: %s digest() unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n", 152462306a36Sopenharmony_ci driver, vec_name, vec->digest_error, cfg->name); 152562306a36Sopenharmony_ci return -EINVAL; 152662306a36Sopenharmony_ci } 152762306a36Sopenharmony_ci goto result_ready; 152862306a36Sopenharmony_ci } 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci /* Using init(), zero or more update(), then final() or finup() */ 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci ahash_request_set_callback(req, req_flags, crypto_req_done, &wait); 153362306a36Sopenharmony_ci ahash_request_set_crypt(req, NULL, result, 0); 153462306a36Sopenharmony_ci err = do_ahash_op(crypto_ahash_init, req, &wait, cfg->nosimd); 153562306a36Sopenharmony_ci err = check_nonfinal_ahash_op("init", err, result, digestsize, 153662306a36Sopenharmony_ci driver, vec_name, cfg); 153762306a36Sopenharmony_ci if (err) 153862306a36Sopenharmony_ci return err; 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_ci pending_sgl = NULL; 154162306a36Sopenharmony_ci pending_len = 0; 154262306a36Sopenharmony_ci for (i = 0; i < tsgl->nents; i++) { 154362306a36Sopenharmony_ci if (divs[i]->flush_type != FLUSH_TYPE_NONE && 154462306a36Sopenharmony_ci pending_sgl != NULL) { 154562306a36Sopenharmony_ci /* update() with the pending data */ 154662306a36Sopenharmony_ci ahash_request_set_callback(req, req_flags, 154762306a36Sopenharmony_ci crypto_req_done, &wait); 154862306a36Sopenharmony_ci ahash_request_set_crypt(req, pending_sgl, result, 154962306a36Sopenharmony_ci pending_len); 155062306a36Sopenharmony_ci err = do_ahash_op(crypto_ahash_update, req, &wait, 155162306a36Sopenharmony_ci divs[i]->nosimd); 155262306a36Sopenharmony_ci err = check_nonfinal_ahash_op("update", err, 155362306a36Sopenharmony_ci result, digestsize, 155462306a36Sopenharmony_ci driver, vec_name, cfg); 155562306a36Sopenharmony_ci if (err) 155662306a36Sopenharmony_ci return err; 155762306a36Sopenharmony_ci pending_sgl = NULL; 155862306a36Sopenharmony_ci pending_len = 0; 155962306a36Sopenharmony_ci } 156062306a36Sopenharmony_ci if (divs[i]->flush_type == FLUSH_TYPE_REIMPORT) { 156162306a36Sopenharmony_ci /* Test ->export() and ->import() */ 156262306a36Sopenharmony_ci testmgr_poison(hashstate + statesize, 156362306a36Sopenharmony_ci TESTMGR_POISON_LEN); 156462306a36Sopenharmony_ci err = crypto_ahash_export(req, hashstate); 156562306a36Sopenharmony_ci err = check_nonfinal_ahash_op("export", err, 156662306a36Sopenharmony_ci result, digestsize, 156762306a36Sopenharmony_ci driver, vec_name, cfg); 156862306a36Sopenharmony_ci if (err) 156962306a36Sopenharmony_ci return err; 157062306a36Sopenharmony_ci if (!testmgr_is_poison(hashstate + statesize, 157162306a36Sopenharmony_ci TESTMGR_POISON_LEN)) { 157262306a36Sopenharmony_ci pr_err("alg: ahash: %s export() overran state buffer on test vector %s, cfg=\"%s\"\n", 157362306a36Sopenharmony_ci driver, vec_name, cfg->name); 157462306a36Sopenharmony_ci return -EOVERFLOW; 157562306a36Sopenharmony_ci } 157662306a36Sopenharmony_ci 157762306a36Sopenharmony_ci testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm)); 157862306a36Sopenharmony_ci err = crypto_ahash_import(req, hashstate); 157962306a36Sopenharmony_ci err = check_nonfinal_ahash_op("import", err, 158062306a36Sopenharmony_ci result, digestsize, 158162306a36Sopenharmony_ci driver, vec_name, cfg); 158262306a36Sopenharmony_ci if (err) 158362306a36Sopenharmony_ci return err; 158462306a36Sopenharmony_ci } 158562306a36Sopenharmony_ci if (pending_sgl == NULL) 158662306a36Sopenharmony_ci pending_sgl = &tsgl->sgl[i]; 158762306a36Sopenharmony_ci pending_len += tsgl->sgl[i].length; 158862306a36Sopenharmony_ci } 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci ahash_request_set_callback(req, req_flags, crypto_req_done, &wait); 159162306a36Sopenharmony_ci ahash_request_set_crypt(req, pending_sgl, result, pending_len); 159262306a36Sopenharmony_ci if (cfg->finalization_type == FINALIZATION_TYPE_FINAL) { 159362306a36Sopenharmony_ci /* finish with update() and final() */ 159462306a36Sopenharmony_ci err = do_ahash_op(crypto_ahash_update, req, &wait, cfg->nosimd); 159562306a36Sopenharmony_ci err = check_nonfinal_ahash_op("update", err, result, digestsize, 159662306a36Sopenharmony_ci driver, vec_name, cfg); 159762306a36Sopenharmony_ci if (err) 159862306a36Sopenharmony_ci return err; 159962306a36Sopenharmony_ci err = do_ahash_op(crypto_ahash_final, req, &wait, cfg->nosimd); 160062306a36Sopenharmony_ci if (err) { 160162306a36Sopenharmony_ci pr_err("alg: ahash: %s final() failed with err %d on test vector %s, cfg=\"%s\"\n", 160262306a36Sopenharmony_ci driver, err, vec_name, cfg->name); 160362306a36Sopenharmony_ci return err; 160462306a36Sopenharmony_ci } 160562306a36Sopenharmony_ci } else { 160662306a36Sopenharmony_ci /* finish with finup() */ 160762306a36Sopenharmony_ci err = do_ahash_op(crypto_ahash_finup, req, &wait, cfg->nosimd); 160862306a36Sopenharmony_ci if (err) { 160962306a36Sopenharmony_ci pr_err("alg: ahash: %s finup() failed with err %d on test vector %s, cfg=\"%s\"\n", 161062306a36Sopenharmony_ci driver, err, vec_name, cfg->name); 161162306a36Sopenharmony_ci return err; 161262306a36Sopenharmony_ci } 161362306a36Sopenharmony_ci } 161462306a36Sopenharmony_ci 161562306a36Sopenharmony_ciresult_ready: 161662306a36Sopenharmony_ci return check_hash_result("ahash", result, digestsize, vec, vec_name, 161762306a36Sopenharmony_ci driver, cfg); 161862306a36Sopenharmony_ci} 161962306a36Sopenharmony_ci 162062306a36Sopenharmony_cistatic int test_hash_vec_cfg(const struct hash_testvec *vec, 162162306a36Sopenharmony_ci const char *vec_name, 162262306a36Sopenharmony_ci const struct testvec_config *cfg, 162362306a36Sopenharmony_ci struct ahash_request *req, 162462306a36Sopenharmony_ci struct shash_desc *desc, 162562306a36Sopenharmony_ci struct test_sglist *tsgl, 162662306a36Sopenharmony_ci u8 *hashstate) 162762306a36Sopenharmony_ci{ 162862306a36Sopenharmony_ci int err; 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci /* 163162306a36Sopenharmony_ci * For algorithms implemented as "shash", most bugs will be detected by 163262306a36Sopenharmony_ci * both the shash and ahash tests. Test the shash API first so that the 163362306a36Sopenharmony_ci * failures involve less indirection, so are easier to debug. 163462306a36Sopenharmony_ci */ 163562306a36Sopenharmony_ci 163662306a36Sopenharmony_ci if (desc) { 163762306a36Sopenharmony_ci err = test_shash_vec_cfg(vec, vec_name, cfg, desc, tsgl, 163862306a36Sopenharmony_ci hashstate); 163962306a36Sopenharmony_ci if (err) 164062306a36Sopenharmony_ci return err; 164162306a36Sopenharmony_ci } 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci return test_ahash_vec_cfg(vec, vec_name, cfg, req, tsgl, hashstate); 164462306a36Sopenharmony_ci} 164562306a36Sopenharmony_ci 164662306a36Sopenharmony_cistatic int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num, 164762306a36Sopenharmony_ci struct ahash_request *req, struct shash_desc *desc, 164862306a36Sopenharmony_ci struct test_sglist *tsgl, u8 *hashstate) 164962306a36Sopenharmony_ci{ 165062306a36Sopenharmony_ci char vec_name[16]; 165162306a36Sopenharmony_ci unsigned int i; 165262306a36Sopenharmony_ci int err; 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci sprintf(vec_name, "%u", vec_num); 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) { 165762306a36Sopenharmony_ci err = test_hash_vec_cfg(vec, vec_name, 165862306a36Sopenharmony_ci &default_hash_testvec_configs[i], 165962306a36Sopenharmony_ci req, desc, tsgl, hashstate); 166062306a36Sopenharmony_ci if (err) 166162306a36Sopenharmony_ci return err; 166262306a36Sopenharmony_ci } 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 166562306a36Sopenharmony_ci if (!noextratests) { 166662306a36Sopenharmony_ci struct rnd_state rng; 166762306a36Sopenharmony_ci struct testvec_config cfg; 166862306a36Sopenharmony_ci char cfgname[TESTVEC_CONFIG_NAMELEN]; 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci init_rnd_state(&rng); 167162306a36Sopenharmony_ci 167262306a36Sopenharmony_ci for (i = 0; i < fuzz_iterations; i++) { 167362306a36Sopenharmony_ci generate_random_testvec_config(&rng, &cfg, cfgname, 167462306a36Sopenharmony_ci sizeof(cfgname)); 167562306a36Sopenharmony_ci err = test_hash_vec_cfg(vec, vec_name, &cfg, 167662306a36Sopenharmony_ci req, desc, tsgl, hashstate); 167762306a36Sopenharmony_ci if (err) 167862306a36Sopenharmony_ci return err; 167962306a36Sopenharmony_ci cond_resched(); 168062306a36Sopenharmony_ci } 168162306a36Sopenharmony_ci } 168262306a36Sopenharmony_ci#endif 168362306a36Sopenharmony_ci return 0; 168462306a36Sopenharmony_ci} 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 168762306a36Sopenharmony_ci/* 168862306a36Sopenharmony_ci * Generate a hash test vector from the given implementation. 168962306a36Sopenharmony_ci * Assumes the buffers in 'vec' were already allocated. 169062306a36Sopenharmony_ci */ 169162306a36Sopenharmony_cistatic void generate_random_hash_testvec(struct rnd_state *rng, 169262306a36Sopenharmony_ci struct shash_desc *desc, 169362306a36Sopenharmony_ci struct hash_testvec *vec, 169462306a36Sopenharmony_ci unsigned int maxkeysize, 169562306a36Sopenharmony_ci unsigned int maxdatasize, 169662306a36Sopenharmony_ci char *name, size_t max_namelen) 169762306a36Sopenharmony_ci{ 169862306a36Sopenharmony_ci /* Data */ 169962306a36Sopenharmony_ci vec->psize = generate_random_length(rng, maxdatasize); 170062306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->plaintext, vec->psize); 170162306a36Sopenharmony_ci 170262306a36Sopenharmony_ci /* 170362306a36Sopenharmony_ci * Key: length in range [1, maxkeysize], but usually choose maxkeysize. 170462306a36Sopenharmony_ci * If algorithm is unkeyed, then maxkeysize == 0 and set ksize = 0. 170562306a36Sopenharmony_ci */ 170662306a36Sopenharmony_ci vec->setkey_error = 0; 170762306a36Sopenharmony_ci vec->ksize = 0; 170862306a36Sopenharmony_ci if (maxkeysize) { 170962306a36Sopenharmony_ci vec->ksize = maxkeysize; 171062306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) 171162306a36Sopenharmony_ci vec->ksize = prandom_u32_inclusive(rng, 1, maxkeysize); 171262306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->key, vec->ksize); 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ci vec->setkey_error = crypto_shash_setkey(desc->tfm, vec->key, 171562306a36Sopenharmony_ci vec->ksize); 171662306a36Sopenharmony_ci /* If the key couldn't be set, no need to continue to digest. */ 171762306a36Sopenharmony_ci if (vec->setkey_error) 171862306a36Sopenharmony_ci goto done; 171962306a36Sopenharmony_ci } 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ci /* Digest */ 172262306a36Sopenharmony_ci vec->digest_error = crypto_shash_digest(desc, vec->plaintext, 172362306a36Sopenharmony_ci vec->psize, (u8 *)vec->digest); 172462306a36Sopenharmony_cidone: 172562306a36Sopenharmony_ci snprintf(name, max_namelen, "\"random: psize=%u ksize=%u\"", 172662306a36Sopenharmony_ci vec->psize, vec->ksize); 172762306a36Sopenharmony_ci} 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_ci/* 173062306a36Sopenharmony_ci * Test the hash algorithm represented by @req against the corresponding generic 173162306a36Sopenharmony_ci * implementation, if one is available. 173262306a36Sopenharmony_ci */ 173362306a36Sopenharmony_cistatic int test_hash_vs_generic_impl(const char *generic_driver, 173462306a36Sopenharmony_ci unsigned int maxkeysize, 173562306a36Sopenharmony_ci struct ahash_request *req, 173662306a36Sopenharmony_ci struct shash_desc *desc, 173762306a36Sopenharmony_ci struct test_sglist *tsgl, 173862306a36Sopenharmony_ci u8 *hashstate) 173962306a36Sopenharmony_ci{ 174062306a36Sopenharmony_ci struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 174162306a36Sopenharmony_ci const unsigned int digestsize = crypto_ahash_digestsize(tfm); 174262306a36Sopenharmony_ci const unsigned int blocksize = crypto_ahash_blocksize(tfm); 174362306a36Sopenharmony_ci const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN; 174462306a36Sopenharmony_ci const char *algname = crypto_hash_alg_common(tfm)->base.cra_name; 174562306a36Sopenharmony_ci const char *driver = crypto_ahash_driver_name(tfm); 174662306a36Sopenharmony_ci struct rnd_state rng; 174762306a36Sopenharmony_ci char _generic_driver[CRYPTO_MAX_ALG_NAME]; 174862306a36Sopenharmony_ci struct crypto_shash *generic_tfm = NULL; 174962306a36Sopenharmony_ci struct shash_desc *generic_desc = NULL; 175062306a36Sopenharmony_ci unsigned int i; 175162306a36Sopenharmony_ci struct hash_testvec vec = { 0 }; 175262306a36Sopenharmony_ci char vec_name[64]; 175362306a36Sopenharmony_ci struct testvec_config *cfg; 175462306a36Sopenharmony_ci char cfgname[TESTVEC_CONFIG_NAMELEN]; 175562306a36Sopenharmony_ci int err; 175662306a36Sopenharmony_ci 175762306a36Sopenharmony_ci if (noextratests) 175862306a36Sopenharmony_ci return 0; 175962306a36Sopenharmony_ci 176062306a36Sopenharmony_ci init_rnd_state(&rng); 176162306a36Sopenharmony_ci 176262306a36Sopenharmony_ci if (!generic_driver) { /* Use default naming convention? */ 176362306a36Sopenharmony_ci err = build_generic_driver_name(algname, _generic_driver); 176462306a36Sopenharmony_ci if (err) 176562306a36Sopenharmony_ci return err; 176662306a36Sopenharmony_ci generic_driver = _generic_driver; 176762306a36Sopenharmony_ci } 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci if (strcmp(generic_driver, driver) == 0) /* Already the generic impl? */ 177062306a36Sopenharmony_ci return 0; 177162306a36Sopenharmony_ci 177262306a36Sopenharmony_ci generic_tfm = crypto_alloc_shash(generic_driver, 0, 0); 177362306a36Sopenharmony_ci if (IS_ERR(generic_tfm)) { 177462306a36Sopenharmony_ci err = PTR_ERR(generic_tfm); 177562306a36Sopenharmony_ci if (err == -ENOENT) { 177662306a36Sopenharmony_ci pr_warn("alg: hash: skipping comparison tests for %s because %s is unavailable\n", 177762306a36Sopenharmony_ci driver, generic_driver); 177862306a36Sopenharmony_ci return 0; 177962306a36Sopenharmony_ci } 178062306a36Sopenharmony_ci pr_err("alg: hash: error allocating %s (generic impl of %s): %d\n", 178162306a36Sopenharmony_ci generic_driver, algname, err); 178262306a36Sopenharmony_ci return err; 178362306a36Sopenharmony_ci } 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 178662306a36Sopenharmony_ci if (!cfg) { 178762306a36Sopenharmony_ci err = -ENOMEM; 178862306a36Sopenharmony_ci goto out; 178962306a36Sopenharmony_ci } 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci generic_desc = kzalloc(sizeof(*desc) + 179262306a36Sopenharmony_ci crypto_shash_descsize(generic_tfm), GFP_KERNEL); 179362306a36Sopenharmony_ci if (!generic_desc) { 179462306a36Sopenharmony_ci err = -ENOMEM; 179562306a36Sopenharmony_ci goto out; 179662306a36Sopenharmony_ci } 179762306a36Sopenharmony_ci generic_desc->tfm = generic_tfm; 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci /* Check the algorithm properties for consistency. */ 180062306a36Sopenharmony_ci 180162306a36Sopenharmony_ci if (digestsize != crypto_shash_digestsize(generic_tfm)) { 180262306a36Sopenharmony_ci pr_err("alg: hash: digestsize for %s (%u) doesn't match generic impl (%u)\n", 180362306a36Sopenharmony_ci driver, digestsize, 180462306a36Sopenharmony_ci crypto_shash_digestsize(generic_tfm)); 180562306a36Sopenharmony_ci err = -EINVAL; 180662306a36Sopenharmony_ci goto out; 180762306a36Sopenharmony_ci } 180862306a36Sopenharmony_ci 180962306a36Sopenharmony_ci if (blocksize != crypto_shash_blocksize(generic_tfm)) { 181062306a36Sopenharmony_ci pr_err("alg: hash: blocksize for %s (%u) doesn't match generic impl (%u)\n", 181162306a36Sopenharmony_ci driver, blocksize, crypto_shash_blocksize(generic_tfm)); 181262306a36Sopenharmony_ci err = -EINVAL; 181362306a36Sopenharmony_ci goto out; 181462306a36Sopenharmony_ci } 181562306a36Sopenharmony_ci 181662306a36Sopenharmony_ci /* 181762306a36Sopenharmony_ci * Now generate test vectors using the generic implementation, and test 181862306a36Sopenharmony_ci * the other implementation against them. 181962306a36Sopenharmony_ci */ 182062306a36Sopenharmony_ci 182162306a36Sopenharmony_ci vec.key = kmalloc(maxkeysize, GFP_KERNEL); 182262306a36Sopenharmony_ci vec.plaintext = kmalloc(maxdatasize, GFP_KERNEL); 182362306a36Sopenharmony_ci vec.digest = kmalloc(digestsize, GFP_KERNEL); 182462306a36Sopenharmony_ci if (!vec.key || !vec.plaintext || !vec.digest) { 182562306a36Sopenharmony_ci err = -ENOMEM; 182662306a36Sopenharmony_ci goto out; 182762306a36Sopenharmony_ci } 182862306a36Sopenharmony_ci 182962306a36Sopenharmony_ci for (i = 0; i < fuzz_iterations * 8; i++) { 183062306a36Sopenharmony_ci generate_random_hash_testvec(&rng, generic_desc, &vec, 183162306a36Sopenharmony_ci maxkeysize, maxdatasize, 183262306a36Sopenharmony_ci vec_name, sizeof(vec_name)); 183362306a36Sopenharmony_ci generate_random_testvec_config(&rng, cfg, cfgname, 183462306a36Sopenharmony_ci sizeof(cfgname)); 183562306a36Sopenharmony_ci 183662306a36Sopenharmony_ci err = test_hash_vec_cfg(&vec, vec_name, cfg, 183762306a36Sopenharmony_ci req, desc, tsgl, hashstate); 183862306a36Sopenharmony_ci if (err) 183962306a36Sopenharmony_ci goto out; 184062306a36Sopenharmony_ci cond_resched(); 184162306a36Sopenharmony_ci } 184262306a36Sopenharmony_ci err = 0; 184362306a36Sopenharmony_ciout: 184462306a36Sopenharmony_ci kfree(cfg); 184562306a36Sopenharmony_ci kfree(vec.key); 184662306a36Sopenharmony_ci kfree(vec.plaintext); 184762306a36Sopenharmony_ci kfree(vec.digest); 184862306a36Sopenharmony_ci crypto_free_shash(generic_tfm); 184962306a36Sopenharmony_ci kfree_sensitive(generic_desc); 185062306a36Sopenharmony_ci return err; 185162306a36Sopenharmony_ci} 185262306a36Sopenharmony_ci#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 185362306a36Sopenharmony_cistatic int test_hash_vs_generic_impl(const char *generic_driver, 185462306a36Sopenharmony_ci unsigned int maxkeysize, 185562306a36Sopenharmony_ci struct ahash_request *req, 185662306a36Sopenharmony_ci struct shash_desc *desc, 185762306a36Sopenharmony_ci struct test_sglist *tsgl, 185862306a36Sopenharmony_ci u8 *hashstate) 185962306a36Sopenharmony_ci{ 186062306a36Sopenharmony_ci return 0; 186162306a36Sopenharmony_ci} 186262306a36Sopenharmony_ci#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 186362306a36Sopenharmony_ci 186462306a36Sopenharmony_cistatic int alloc_shash(const char *driver, u32 type, u32 mask, 186562306a36Sopenharmony_ci struct crypto_shash **tfm_ret, 186662306a36Sopenharmony_ci struct shash_desc **desc_ret) 186762306a36Sopenharmony_ci{ 186862306a36Sopenharmony_ci struct crypto_shash *tfm; 186962306a36Sopenharmony_ci struct shash_desc *desc; 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci tfm = crypto_alloc_shash(driver, type, mask); 187262306a36Sopenharmony_ci if (IS_ERR(tfm)) { 187362306a36Sopenharmony_ci if (PTR_ERR(tfm) == -ENOENT) { 187462306a36Sopenharmony_ci /* 187562306a36Sopenharmony_ci * This algorithm is only available through the ahash 187662306a36Sopenharmony_ci * API, not the shash API, so skip the shash tests. 187762306a36Sopenharmony_ci */ 187862306a36Sopenharmony_ci return 0; 187962306a36Sopenharmony_ci } 188062306a36Sopenharmony_ci pr_err("alg: hash: failed to allocate shash transform for %s: %ld\n", 188162306a36Sopenharmony_ci driver, PTR_ERR(tfm)); 188262306a36Sopenharmony_ci return PTR_ERR(tfm); 188362306a36Sopenharmony_ci } 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ci desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL); 188662306a36Sopenharmony_ci if (!desc) { 188762306a36Sopenharmony_ci crypto_free_shash(tfm); 188862306a36Sopenharmony_ci return -ENOMEM; 188962306a36Sopenharmony_ci } 189062306a36Sopenharmony_ci desc->tfm = tfm; 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ci *tfm_ret = tfm; 189362306a36Sopenharmony_ci *desc_ret = desc; 189462306a36Sopenharmony_ci return 0; 189562306a36Sopenharmony_ci} 189662306a36Sopenharmony_ci 189762306a36Sopenharmony_cistatic int __alg_test_hash(const struct hash_testvec *vecs, 189862306a36Sopenharmony_ci unsigned int num_vecs, const char *driver, 189962306a36Sopenharmony_ci u32 type, u32 mask, 190062306a36Sopenharmony_ci const char *generic_driver, unsigned int maxkeysize) 190162306a36Sopenharmony_ci{ 190262306a36Sopenharmony_ci struct crypto_ahash *atfm = NULL; 190362306a36Sopenharmony_ci struct ahash_request *req = NULL; 190462306a36Sopenharmony_ci struct crypto_shash *stfm = NULL; 190562306a36Sopenharmony_ci struct shash_desc *desc = NULL; 190662306a36Sopenharmony_ci struct test_sglist *tsgl = NULL; 190762306a36Sopenharmony_ci u8 *hashstate = NULL; 190862306a36Sopenharmony_ci unsigned int statesize; 190962306a36Sopenharmony_ci unsigned int i; 191062306a36Sopenharmony_ci int err; 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_ci /* 191362306a36Sopenharmony_ci * Always test the ahash API. This works regardless of whether the 191462306a36Sopenharmony_ci * algorithm is implemented as ahash or shash. 191562306a36Sopenharmony_ci */ 191662306a36Sopenharmony_ci 191762306a36Sopenharmony_ci atfm = crypto_alloc_ahash(driver, type, mask); 191862306a36Sopenharmony_ci if (IS_ERR(atfm)) { 191962306a36Sopenharmony_ci pr_err("alg: hash: failed to allocate transform for %s: %ld\n", 192062306a36Sopenharmony_ci driver, PTR_ERR(atfm)); 192162306a36Sopenharmony_ci return PTR_ERR(atfm); 192262306a36Sopenharmony_ci } 192362306a36Sopenharmony_ci driver = crypto_ahash_driver_name(atfm); 192462306a36Sopenharmony_ci 192562306a36Sopenharmony_ci req = ahash_request_alloc(atfm, GFP_KERNEL); 192662306a36Sopenharmony_ci if (!req) { 192762306a36Sopenharmony_ci pr_err("alg: hash: failed to allocate request for %s\n", 192862306a36Sopenharmony_ci driver); 192962306a36Sopenharmony_ci err = -ENOMEM; 193062306a36Sopenharmony_ci goto out; 193162306a36Sopenharmony_ci } 193262306a36Sopenharmony_ci 193362306a36Sopenharmony_ci /* 193462306a36Sopenharmony_ci * If available also test the shash API, to cover corner cases that may 193562306a36Sopenharmony_ci * be missed by testing the ahash API only. 193662306a36Sopenharmony_ci */ 193762306a36Sopenharmony_ci err = alloc_shash(driver, type, mask, &stfm, &desc); 193862306a36Sopenharmony_ci if (err) 193962306a36Sopenharmony_ci goto out; 194062306a36Sopenharmony_ci 194162306a36Sopenharmony_ci tsgl = kmalloc(sizeof(*tsgl), GFP_KERNEL); 194262306a36Sopenharmony_ci if (!tsgl || init_test_sglist(tsgl) != 0) { 194362306a36Sopenharmony_ci pr_err("alg: hash: failed to allocate test buffers for %s\n", 194462306a36Sopenharmony_ci driver); 194562306a36Sopenharmony_ci kfree(tsgl); 194662306a36Sopenharmony_ci tsgl = NULL; 194762306a36Sopenharmony_ci err = -ENOMEM; 194862306a36Sopenharmony_ci goto out; 194962306a36Sopenharmony_ci } 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_ci statesize = crypto_ahash_statesize(atfm); 195262306a36Sopenharmony_ci if (stfm) 195362306a36Sopenharmony_ci statesize = max(statesize, crypto_shash_statesize(stfm)); 195462306a36Sopenharmony_ci hashstate = kmalloc(statesize + TESTMGR_POISON_LEN, GFP_KERNEL); 195562306a36Sopenharmony_ci if (!hashstate) { 195662306a36Sopenharmony_ci pr_err("alg: hash: failed to allocate hash state buffer for %s\n", 195762306a36Sopenharmony_ci driver); 195862306a36Sopenharmony_ci err = -ENOMEM; 195962306a36Sopenharmony_ci goto out; 196062306a36Sopenharmony_ci } 196162306a36Sopenharmony_ci 196262306a36Sopenharmony_ci for (i = 0; i < num_vecs; i++) { 196362306a36Sopenharmony_ci if (fips_enabled && vecs[i].fips_skip) 196462306a36Sopenharmony_ci continue; 196562306a36Sopenharmony_ci 196662306a36Sopenharmony_ci err = test_hash_vec(&vecs[i], i, req, desc, tsgl, hashstate); 196762306a36Sopenharmony_ci if (err) 196862306a36Sopenharmony_ci goto out; 196962306a36Sopenharmony_ci cond_resched(); 197062306a36Sopenharmony_ci } 197162306a36Sopenharmony_ci err = test_hash_vs_generic_impl(generic_driver, maxkeysize, req, 197262306a36Sopenharmony_ci desc, tsgl, hashstate); 197362306a36Sopenharmony_ciout: 197462306a36Sopenharmony_ci kfree(hashstate); 197562306a36Sopenharmony_ci if (tsgl) { 197662306a36Sopenharmony_ci destroy_test_sglist(tsgl); 197762306a36Sopenharmony_ci kfree(tsgl); 197862306a36Sopenharmony_ci } 197962306a36Sopenharmony_ci kfree(desc); 198062306a36Sopenharmony_ci crypto_free_shash(stfm); 198162306a36Sopenharmony_ci ahash_request_free(req); 198262306a36Sopenharmony_ci crypto_free_ahash(atfm); 198362306a36Sopenharmony_ci return err; 198462306a36Sopenharmony_ci} 198562306a36Sopenharmony_ci 198662306a36Sopenharmony_cistatic int alg_test_hash(const struct alg_test_desc *desc, const char *driver, 198762306a36Sopenharmony_ci u32 type, u32 mask) 198862306a36Sopenharmony_ci{ 198962306a36Sopenharmony_ci const struct hash_testvec *template = desc->suite.hash.vecs; 199062306a36Sopenharmony_ci unsigned int tcount = desc->suite.hash.count; 199162306a36Sopenharmony_ci unsigned int nr_unkeyed, nr_keyed; 199262306a36Sopenharmony_ci unsigned int maxkeysize = 0; 199362306a36Sopenharmony_ci int err; 199462306a36Sopenharmony_ci 199562306a36Sopenharmony_ci /* 199662306a36Sopenharmony_ci * For OPTIONAL_KEY algorithms, we have to do all the unkeyed tests 199762306a36Sopenharmony_ci * first, before setting a key on the tfm. To make this easier, we 199862306a36Sopenharmony_ci * require that the unkeyed test vectors (if any) are listed first. 199962306a36Sopenharmony_ci */ 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_ci for (nr_unkeyed = 0; nr_unkeyed < tcount; nr_unkeyed++) { 200262306a36Sopenharmony_ci if (template[nr_unkeyed].ksize) 200362306a36Sopenharmony_ci break; 200462306a36Sopenharmony_ci } 200562306a36Sopenharmony_ci for (nr_keyed = 0; nr_unkeyed + nr_keyed < tcount; nr_keyed++) { 200662306a36Sopenharmony_ci if (!template[nr_unkeyed + nr_keyed].ksize) { 200762306a36Sopenharmony_ci pr_err("alg: hash: test vectors for %s out of order, " 200862306a36Sopenharmony_ci "unkeyed ones must come first\n", desc->alg); 200962306a36Sopenharmony_ci return -EINVAL; 201062306a36Sopenharmony_ci } 201162306a36Sopenharmony_ci maxkeysize = max_t(unsigned int, maxkeysize, 201262306a36Sopenharmony_ci template[nr_unkeyed + nr_keyed].ksize); 201362306a36Sopenharmony_ci } 201462306a36Sopenharmony_ci 201562306a36Sopenharmony_ci err = 0; 201662306a36Sopenharmony_ci if (nr_unkeyed) { 201762306a36Sopenharmony_ci err = __alg_test_hash(template, nr_unkeyed, driver, type, mask, 201862306a36Sopenharmony_ci desc->generic_driver, maxkeysize); 201962306a36Sopenharmony_ci template += nr_unkeyed; 202062306a36Sopenharmony_ci } 202162306a36Sopenharmony_ci 202262306a36Sopenharmony_ci if (!err && nr_keyed) 202362306a36Sopenharmony_ci err = __alg_test_hash(template, nr_keyed, driver, type, mask, 202462306a36Sopenharmony_ci desc->generic_driver, maxkeysize); 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci return err; 202762306a36Sopenharmony_ci} 202862306a36Sopenharmony_ci 202962306a36Sopenharmony_cistatic int test_aead_vec_cfg(int enc, const struct aead_testvec *vec, 203062306a36Sopenharmony_ci const char *vec_name, 203162306a36Sopenharmony_ci const struct testvec_config *cfg, 203262306a36Sopenharmony_ci struct aead_request *req, 203362306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 203462306a36Sopenharmony_ci{ 203562306a36Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 203662306a36Sopenharmony_ci const unsigned int alignmask = crypto_aead_alignmask(tfm); 203762306a36Sopenharmony_ci const unsigned int ivsize = crypto_aead_ivsize(tfm); 203862306a36Sopenharmony_ci const unsigned int authsize = vec->clen - vec->plen; 203962306a36Sopenharmony_ci const char *driver = crypto_aead_driver_name(tfm); 204062306a36Sopenharmony_ci const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 204162306a36Sopenharmony_ci const char *op = enc ? "encryption" : "decryption"; 204262306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 204362306a36Sopenharmony_ci u8 _iv[3 * (MAX_ALGAPI_ALIGNMASK + 1) + MAX_IVLEN]; 204462306a36Sopenharmony_ci u8 *iv = PTR_ALIGN(&_iv[0], 2 * (MAX_ALGAPI_ALIGNMASK + 1)) + 204562306a36Sopenharmony_ci cfg->iv_offset + 204662306a36Sopenharmony_ci (cfg->iv_offset_relative_to_alignmask ? alignmask : 0); 204762306a36Sopenharmony_ci struct kvec input[2]; 204862306a36Sopenharmony_ci int err; 204962306a36Sopenharmony_ci 205062306a36Sopenharmony_ci /* Set the key */ 205162306a36Sopenharmony_ci if (vec->wk) 205262306a36Sopenharmony_ci crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 205362306a36Sopenharmony_ci else 205462306a36Sopenharmony_ci crypto_aead_clear_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 205562306a36Sopenharmony_ci 205662306a36Sopenharmony_ci err = do_setkey(crypto_aead_setkey, tfm, vec->key, vec->klen, 205762306a36Sopenharmony_ci cfg, alignmask); 205862306a36Sopenharmony_ci if (err && err != vec->setkey_error) { 205962306a36Sopenharmony_ci pr_err("alg: aead: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n", 206062306a36Sopenharmony_ci driver, vec_name, vec->setkey_error, err, 206162306a36Sopenharmony_ci crypto_aead_get_flags(tfm)); 206262306a36Sopenharmony_ci return err; 206362306a36Sopenharmony_ci } 206462306a36Sopenharmony_ci if (!err && vec->setkey_error) { 206562306a36Sopenharmony_ci pr_err("alg: aead: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n", 206662306a36Sopenharmony_ci driver, vec_name, vec->setkey_error); 206762306a36Sopenharmony_ci return -EINVAL; 206862306a36Sopenharmony_ci } 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_ci /* Set the authentication tag size */ 207162306a36Sopenharmony_ci err = crypto_aead_setauthsize(tfm, authsize); 207262306a36Sopenharmony_ci if (err && err != vec->setauthsize_error) { 207362306a36Sopenharmony_ci pr_err("alg: aead: %s setauthsize failed on test vector %s; expected_error=%d, actual_error=%d\n", 207462306a36Sopenharmony_ci driver, vec_name, vec->setauthsize_error, err); 207562306a36Sopenharmony_ci return err; 207662306a36Sopenharmony_ci } 207762306a36Sopenharmony_ci if (!err && vec->setauthsize_error) { 207862306a36Sopenharmony_ci pr_err("alg: aead: %s setauthsize unexpectedly succeeded on test vector %s; expected_error=%d\n", 207962306a36Sopenharmony_ci driver, vec_name, vec->setauthsize_error); 208062306a36Sopenharmony_ci return -EINVAL; 208162306a36Sopenharmony_ci } 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci if (vec->setkey_error || vec->setauthsize_error) 208462306a36Sopenharmony_ci return 0; 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci /* The IV must be copied to a buffer, as the algorithm may modify it */ 208762306a36Sopenharmony_ci if (WARN_ON(ivsize > MAX_IVLEN)) 208862306a36Sopenharmony_ci return -EINVAL; 208962306a36Sopenharmony_ci if (vec->iv) 209062306a36Sopenharmony_ci memcpy(iv, vec->iv, ivsize); 209162306a36Sopenharmony_ci else 209262306a36Sopenharmony_ci memset(iv, 0, ivsize); 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci /* Build the src/dst scatterlists */ 209562306a36Sopenharmony_ci input[0].iov_base = (void *)vec->assoc; 209662306a36Sopenharmony_ci input[0].iov_len = vec->alen; 209762306a36Sopenharmony_ci input[1].iov_base = enc ? (void *)vec->ptext : (void *)vec->ctext; 209862306a36Sopenharmony_ci input[1].iov_len = enc ? vec->plen : vec->clen; 209962306a36Sopenharmony_ci err = build_cipher_test_sglists(tsgls, cfg, alignmask, 210062306a36Sopenharmony_ci vec->alen + (enc ? vec->plen : 210162306a36Sopenharmony_ci vec->clen), 210262306a36Sopenharmony_ci vec->alen + (enc ? vec->clen : 210362306a36Sopenharmony_ci vec->plen), 210462306a36Sopenharmony_ci input, 2); 210562306a36Sopenharmony_ci if (err) { 210662306a36Sopenharmony_ci pr_err("alg: aead: %s %s: error preparing scatterlists for test vector %s, cfg=\"%s\"\n", 210762306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 210862306a36Sopenharmony_ci return err; 210962306a36Sopenharmony_ci } 211062306a36Sopenharmony_ci 211162306a36Sopenharmony_ci /* Do the actual encryption or decryption */ 211262306a36Sopenharmony_ci testmgr_poison(req->__ctx, crypto_aead_reqsize(tfm)); 211362306a36Sopenharmony_ci aead_request_set_callback(req, req_flags, crypto_req_done, &wait); 211462306a36Sopenharmony_ci aead_request_set_crypt(req, tsgls->src.sgl_ptr, tsgls->dst.sgl_ptr, 211562306a36Sopenharmony_ci enc ? vec->plen : vec->clen, iv); 211662306a36Sopenharmony_ci aead_request_set_ad(req, vec->alen); 211762306a36Sopenharmony_ci if (cfg->nosimd) 211862306a36Sopenharmony_ci crypto_disable_simd_for_test(); 211962306a36Sopenharmony_ci err = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req); 212062306a36Sopenharmony_ci if (cfg->nosimd) 212162306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 212262306a36Sopenharmony_ci err = crypto_wait_req(err, &wait); 212362306a36Sopenharmony_ci 212462306a36Sopenharmony_ci /* Check that the algorithm didn't overwrite things it shouldn't have */ 212562306a36Sopenharmony_ci if (req->cryptlen != (enc ? vec->plen : vec->clen) || 212662306a36Sopenharmony_ci req->assoclen != vec->alen || 212762306a36Sopenharmony_ci req->iv != iv || 212862306a36Sopenharmony_ci req->src != tsgls->src.sgl_ptr || 212962306a36Sopenharmony_ci req->dst != tsgls->dst.sgl_ptr || 213062306a36Sopenharmony_ci crypto_aead_reqtfm(req) != tfm || 213162306a36Sopenharmony_ci req->base.complete != crypto_req_done || 213262306a36Sopenharmony_ci req->base.flags != req_flags || 213362306a36Sopenharmony_ci req->base.data != &wait) { 213462306a36Sopenharmony_ci pr_err("alg: aead: %s %s corrupted request struct on test vector %s, cfg=\"%s\"\n", 213562306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 213662306a36Sopenharmony_ci if (req->cryptlen != (enc ? vec->plen : vec->clen)) 213762306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->cryptlen'\n"); 213862306a36Sopenharmony_ci if (req->assoclen != vec->alen) 213962306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->assoclen'\n"); 214062306a36Sopenharmony_ci if (req->iv != iv) 214162306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->iv'\n"); 214262306a36Sopenharmony_ci if (req->src != tsgls->src.sgl_ptr) 214362306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->src'\n"); 214462306a36Sopenharmony_ci if (req->dst != tsgls->dst.sgl_ptr) 214562306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->dst'\n"); 214662306a36Sopenharmony_ci if (crypto_aead_reqtfm(req) != tfm) 214762306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->base.tfm'\n"); 214862306a36Sopenharmony_ci if (req->base.complete != crypto_req_done) 214962306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->base.complete'\n"); 215062306a36Sopenharmony_ci if (req->base.flags != req_flags) 215162306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->base.flags'\n"); 215262306a36Sopenharmony_ci if (req->base.data != &wait) 215362306a36Sopenharmony_ci pr_err("alg: aead: changed 'req->base.data'\n"); 215462306a36Sopenharmony_ci return -EINVAL; 215562306a36Sopenharmony_ci } 215662306a36Sopenharmony_ci if (is_test_sglist_corrupted(&tsgls->src)) { 215762306a36Sopenharmony_ci pr_err("alg: aead: %s %s corrupted src sgl on test vector %s, cfg=\"%s\"\n", 215862306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 215962306a36Sopenharmony_ci return -EINVAL; 216062306a36Sopenharmony_ci } 216162306a36Sopenharmony_ci if (tsgls->dst.sgl_ptr != tsgls->src.sgl && 216262306a36Sopenharmony_ci is_test_sglist_corrupted(&tsgls->dst)) { 216362306a36Sopenharmony_ci pr_err("alg: aead: %s %s corrupted dst sgl on test vector %s, cfg=\"%s\"\n", 216462306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 216562306a36Sopenharmony_ci return -EINVAL; 216662306a36Sopenharmony_ci } 216762306a36Sopenharmony_ci 216862306a36Sopenharmony_ci /* Check for unexpected success or failure, or wrong error code */ 216962306a36Sopenharmony_ci if ((err == 0 && vec->novrfy) || 217062306a36Sopenharmony_ci (err != vec->crypt_error && !(err == -EBADMSG && vec->novrfy))) { 217162306a36Sopenharmony_ci char expected_error[32]; 217262306a36Sopenharmony_ci 217362306a36Sopenharmony_ci if (vec->novrfy && 217462306a36Sopenharmony_ci vec->crypt_error != 0 && vec->crypt_error != -EBADMSG) 217562306a36Sopenharmony_ci sprintf(expected_error, "-EBADMSG or %d", 217662306a36Sopenharmony_ci vec->crypt_error); 217762306a36Sopenharmony_ci else if (vec->novrfy) 217862306a36Sopenharmony_ci sprintf(expected_error, "-EBADMSG"); 217962306a36Sopenharmony_ci else 218062306a36Sopenharmony_ci sprintf(expected_error, "%d", vec->crypt_error); 218162306a36Sopenharmony_ci if (err) { 218262306a36Sopenharmony_ci pr_err("alg: aead: %s %s failed on test vector %s; expected_error=%s, actual_error=%d, cfg=\"%s\"\n", 218362306a36Sopenharmony_ci driver, op, vec_name, expected_error, err, 218462306a36Sopenharmony_ci cfg->name); 218562306a36Sopenharmony_ci return err; 218662306a36Sopenharmony_ci } 218762306a36Sopenharmony_ci pr_err("alg: aead: %s %s unexpectedly succeeded on test vector %s; expected_error=%s, cfg=\"%s\"\n", 218862306a36Sopenharmony_ci driver, op, vec_name, expected_error, cfg->name); 218962306a36Sopenharmony_ci return -EINVAL; 219062306a36Sopenharmony_ci } 219162306a36Sopenharmony_ci if (err) /* Expectedly failed. */ 219262306a36Sopenharmony_ci return 0; 219362306a36Sopenharmony_ci 219462306a36Sopenharmony_ci /* Check for the correct output (ciphertext or plaintext) */ 219562306a36Sopenharmony_ci err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext, 219662306a36Sopenharmony_ci enc ? vec->clen : vec->plen, 219762306a36Sopenharmony_ci vec->alen, 219862306a36Sopenharmony_ci enc || cfg->inplace_mode == OUT_OF_PLACE); 219962306a36Sopenharmony_ci if (err == -EOVERFLOW) { 220062306a36Sopenharmony_ci pr_err("alg: aead: %s %s overran dst buffer on test vector %s, cfg=\"%s\"\n", 220162306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 220262306a36Sopenharmony_ci return err; 220362306a36Sopenharmony_ci } 220462306a36Sopenharmony_ci if (err) { 220562306a36Sopenharmony_ci pr_err("alg: aead: %s %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n", 220662306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 220762306a36Sopenharmony_ci return err; 220862306a36Sopenharmony_ci } 220962306a36Sopenharmony_ci 221062306a36Sopenharmony_ci return 0; 221162306a36Sopenharmony_ci} 221262306a36Sopenharmony_ci 221362306a36Sopenharmony_cistatic int test_aead_vec(int enc, const struct aead_testvec *vec, 221462306a36Sopenharmony_ci unsigned int vec_num, struct aead_request *req, 221562306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 221662306a36Sopenharmony_ci{ 221762306a36Sopenharmony_ci char vec_name[16]; 221862306a36Sopenharmony_ci unsigned int i; 221962306a36Sopenharmony_ci int err; 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_ci if (enc && vec->novrfy) 222262306a36Sopenharmony_ci return 0; 222362306a36Sopenharmony_ci 222462306a36Sopenharmony_ci sprintf(vec_name, "%u", vec_num); 222562306a36Sopenharmony_ci 222662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) { 222762306a36Sopenharmony_ci err = test_aead_vec_cfg(enc, vec, vec_name, 222862306a36Sopenharmony_ci &default_cipher_testvec_configs[i], 222962306a36Sopenharmony_ci req, tsgls); 223062306a36Sopenharmony_ci if (err) 223162306a36Sopenharmony_ci return err; 223262306a36Sopenharmony_ci } 223362306a36Sopenharmony_ci 223462306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 223562306a36Sopenharmony_ci if (!noextratests) { 223662306a36Sopenharmony_ci struct rnd_state rng; 223762306a36Sopenharmony_ci struct testvec_config cfg; 223862306a36Sopenharmony_ci char cfgname[TESTVEC_CONFIG_NAMELEN]; 223962306a36Sopenharmony_ci 224062306a36Sopenharmony_ci init_rnd_state(&rng); 224162306a36Sopenharmony_ci 224262306a36Sopenharmony_ci for (i = 0; i < fuzz_iterations; i++) { 224362306a36Sopenharmony_ci generate_random_testvec_config(&rng, &cfg, cfgname, 224462306a36Sopenharmony_ci sizeof(cfgname)); 224562306a36Sopenharmony_ci err = test_aead_vec_cfg(enc, vec, vec_name, 224662306a36Sopenharmony_ci &cfg, req, tsgls); 224762306a36Sopenharmony_ci if (err) 224862306a36Sopenharmony_ci return err; 224962306a36Sopenharmony_ci cond_resched(); 225062306a36Sopenharmony_ci } 225162306a36Sopenharmony_ci } 225262306a36Sopenharmony_ci#endif 225362306a36Sopenharmony_ci return 0; 225462306a36Sopenharmony_ci} 225562306a36Sopenharmony_ci 225662306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 225762306a36Sopenharmony_ci 225862306a36Sopenharmony_cistruct aead_extra_tests_ctx { 225962306a36Sopenharmony_ci struct rnd_state rng; 226062306a36Sopenharmony_ci struct aead_request *req; 226162306a36Sopenharmony_ci struct crypto_aead *tfm; 226262306a36Sopenharmony_ci const struct alg_test_desc *test_desc; 226362306a36Sopenharmony_ci struct cipher_test_sglists *tsgls; 226462306a36Sopenharmony_ci unsigned int maxdatasize; 226562306a36Sopenharmony_ci unsigned int maxkeysize; 226662306a36Sopenharmony_ci 226762306a36Sopenharmony_ci struct aead_testvec vec; 226862306a36Sopenharmony_ci char vec_name[64]; 226962306a36Sopenharmony_ci char cfgname[TESTVEC_CONFIG_NAMELEN]; 227062306a36Sopenharmony_ci struct testvec_config cfg; 227162306a36Sopenharmony_ci}; 227262306a36Sopenharmony_ci 227362306a36Sopenharmony_ci/* 227462306a36Sopenharmony_ci * Make at least one random change to a (ciphertext, AAD) pair. "Ciphertext" 227562306a36Sopenharmony_ci * here means the full ciphertext including the authentication tag. The 227662306a36Sopenharmony_ci * authentication tag (and hence also the ciphertext) is assumed to be nonempty. 227762306a36Sopenharmony_ci */ 227862306a36Sopenharmony_cistatic void mutate_aead_message(struct rnd_state *rng, 227962306a36Sopenharmony_ci struct aead_testvec *vec, bool aad_iv, 228062306a36Sopenharmony_ci unsigned int ivsize) 228162306a36Sopenharmony_ci{ 228262306a36Sopenharmony_ci const unsigned int aad_tail_size = aad_iv ? ivsize : 0; 228362306a36Sopenharmony_ci const unsigned int authsize = vec->clen - vec->plen; 228462306a36Sopenharmony_ci 228562306a36Sopenharmony_ci if (prandom_bool(rng) && vec->alen > aad_tail_size) { 228662306a36Sopenharmony_ci /* Mutate the AAD */ 228762306a36Sopenharmony_ci flip_random_bit(rng, (u8 *)vec->assoc, 228862306a36Sopenharmony_ci vec->alen - aad_tail_size); 228962306a36Sopenharmony_ci if (prandom_bool(rng)) 229062306a36Sopenharmony_ci return; 229162306a36Sopenharmony_ci } 229262306a36Sopenharmony_ci if (prandom_bool(rng)) { 229362306a36Sopenharmony_ci /* Mutate auth tag (assuming it's at the end of ciphertext) */ 229462306a36Sopenharmony_ci flip_random_bit(rng, (u8 *)vec->ctext + vec->plen, authsize); 229562306a36Sopenharmony_ci } else { 229662306a36Sopenharmony_ci /* Mutate any part of the ciphertext */ 229762306a36Sopenharmony_ci flip_random_bit(rng, (u8 *)vec->ctext, vec->clen); 229862306a36Sopenharmony_ci } 229962306a36Sopenharmony_ci} 230062306a36Sopenharmony_ci 230162306a36Sopenharmony_ci/* 230262306a36Sopenharmony_ci * Minimum authentication tag size in bytes at which we assume that we can 230362306a36Sopenharmony_ci * reliably generate inauthentic messages, i.e. not generate an authentic 230462306a36Sopenharmony_ci * message by chance. 230562306a36Sopenharmony_ci */ 230662306a36Sopenharmony_ci#define MIN_COLLISION_FREE_AUTHSIZE 8 230762306a36Sopenharmony_ci 230862306a36Sopenharmony_cistatic void generate_aead_message(struct rnd_state *rng, 230962306a36Sopenharmony_ci struct aead_request *req, 231062306a36Sopenharmony_ci const struct aead_test_suite *suite, 231162306a36Sopenharmony_ci struct aead_testvec *vec, 231262306a36Sopenharmony_ci bool prefer_inauthentic) 231362306a36Sopenharmony_ci{ 231462306a36Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 231562306a36Sopenharmony_ci const unsigned int ivsize = crypto_aead_ivsize(tfm); 231662306a36Sopenharmony_ci const unsigned int authsize = vec->clen - vec->plen; 231762306a36Sopenharmony_ci const bool inauthentic = (authsize >= MIN_COLLISION_FREE_AUTHSIZE) && 231862306a36Sopenharmony_ci (prefer_inauthentic || 231962306a36Sopenharmony_ci prandom_u32_below(rng, 4) == 0); 232062306a36Sopenharmony_ci 232162306a36Sopenharmony_ci /* Generate the AAD. */ 232262306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->assoc, vec->alen); 232362306a36Sopenharmony_ci if (suite->aad_iv && vec->alen >= ivsize) 232462306a36Sopenharmony_ci /* Avoid implementation-defined behavior. */ 232562306a36Sopenharmony_ci memcpy((u8 *)vec->assoc + vec->alen - ivsize, vec->iv, ivsize); 232662306a36Sopenharmony_ci 232762306a36Sopenharmony_ci if (inauthentic && prandom_bool(rng)) { 232862306a36Sopenharmony_ci /* Generate a random ciphertext. */ 232962306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->ctext, vec->clen); 233062306a36Sopenharmony_ci } else { 233162306a36Sopenharmony_ci int i = 0; 233262306a36Sopenharmony_ci struct scatterlist src[2], dst; 233362306a36Sopenharmony_ci u8 iv[MAX_IVLEN]; 233462306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 233562306a36Sopenharmony_ci 233662306a36Sopenharmony_ci /* Generate a random plaintext and encrypt it. */ 233762306a36Sopenharmony_ci sg_init_table(src, 2); 233862306a36Sopenharmony_ci if (vec->alen) 233962306a36Sopenharmony_ci sg_set_buf(&src[i++], vec->assoc, vec->alen); 234062306a36Sopenharmony_ci if (vec->plen) { 234162306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->ptext, vec->plen); 234262306a36Sopenharmony_ci sg_set_buf(&src[i++], vec->ptext, vec->plen); 234362306a36Sopenharmony_ci } 234462306a36Sopenharmony_ci sg_init_one(&dst, vec->ctext, vec->alen + vec->clen); 234562306a36Sopenharmony_ci memcpy(iv, vec->iv, ivsize); 234662306a36Sopenharmony_ci aead_request_set_callback(req, 0, crypto_req_done, &wait); 234762306a36Sopenharmony_ci aead_request_set_crypt(req, src, &dst, vec->plen, iv); 234862306a36Sopenharmony_ci aead_request_set_ad(req, vec->alen); 234962306a36Sopenharmony_ci vec->crypt_error = crypto_wait_req(crypto_aead_encrypt(req), 235062306a36Sopenharmony_ci &wait); 235162306a36Sopenharmony_ci /* If encryption failed, we're done. */ 235262306a36Sopenharmony_ci if (vec->crypt_error != 0) 235362306a36Sopenharmony_ci return; 235462306a36Sopenharmony_ci memmove((u8 *)vec->ctext, vec->ctext + vec->alen, vec->clen); 235562306a36Sopenharmony_ci if (!inauthentic) 235662306a36Sopenharmony_ci return; 235762306a36Sopenharmony_ci /* 235862306a36Sopenharmony_ci * Mutate the authentic (ciphertext, AAD) pair to get an 235962306a36Sopenharmony_ci * inauthentic one. 236062306a36Sopenharmony_ci */ 236162306a36Sopenharmony_ci mutate_aead_message(rng, vec, suite->aad_iv, ivsize); 236262306a36Sopenharmony_ci } 236362306a36Sopenharmony_ci vec->novrfy = 1; 236462306a36Sopenharmony_ci if (suite->einval_allowed) 236562306a36Sopenharmony_ci vec->crypt_error = -EINVAL; 236662306a36Sopenharmony_ci} 236762306a36Sopenharmony_ci 236862306a36Sopenharmony_ci/* 236962306a36Sopenharmony_ci * Generate an AEAD test vector 'vec' using the implementation specified by 237062306a36Sopenharmony_ci * 'req'. The buffers in 'vec' must already be allocated. 237162306a36Sopenharmony_ci * 237262306a36Sopenharmony_ci * If 'prefer_inauthentic' is true, then this function will generate inauthentic 237362306a36Sopenharmony_ci * test vectors (i.e. vectors with 'vec->novrfy=1') more often. 237462306a36Sopenharmony_ci */ 237562306a36Sopenharmony_cistatic void generate_random_aead_testvec(struct rnd_state *rng, 237662306a36Sopenharmony_ci struct aead_request *req, 237762306a36Sopenharmony_ci struct aead_testvec *vec, 237862306a36Sopenharmony_ci const struct aead_test_suite *suite, 237962306a36Sopenharmony_ci unsigned int maxkeysize, 238062306a36Sopenharmony_ci unsigned int maxdatasize, 238162306a36Sopenharmony_ci char *name, size_t max_namelen, 238262306a36Sopenharmony_ci bool prefer_inauthentic) 238362306a36Sopenharmony_ci{ 238462306a36Sopenharmony_ci struct crypto_aead *tfm = crypto_aead_reqtfm(req); 238562306a36Sopenharmony_ci const unsigned int ivsize = crypto_aead_ivsize(tfm); 238662306a36Sopenharmony_ci const unsigned int maxauthsize = crypto_aead_maxauthsize(tfm); 238762306a36Sopenharmony_ci unsigned int authsize; 238862306a36Sopenharmony_ci unsigned int total_len; 238962306a36Sopenharmony_ci 239062306a36Sopenharmony_ci /* Key: length in [0, maxkeysize], but usually choose maxkeysize */ 239162306a36Sopenharmony_ci vec->klen = maxkeysize; 239262306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) 239362306a36Sopenharmony_ci vec->klen = prandom_u32_below(rng, maxkeysize + 1); 239462306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->key, vec->klen); 239562306a36Sopenharmony_ci vec->setkey_error = crypto_aead_setkey(tfm, vec->key, vec->klen); 239662306a36Sopenharmony_ci 239762306a36Sopenharmony_ci /* IV */ 239862306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->iv, ivsize); 239962306a36Sopenharmony_ci 240062306a36Sopenharmony_ci /* Tag length: in [0, maxauthsize], but usually choose maxauthsize */ 240162306a36Sopenharmony_ci authsize = maxauthsize; 240262306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) 240362306a36Sopenharmony_ci authsize = prandom_u32_below(rng, maxauthsize + 1); 240462306a36Sopenharmony_ci if (prefer_inauthentic && authsize < MIN_COLLISION_FREE_AUTHSIZE) 240562306a36Sopenharmony_ci authsize = MIN_COLLISION_FREE_AUTHSIZE; 240662306a36Sopenharmony_ci if (WARN_ON(authsize > maxdatasize)) 240762306a36Sopenharmony_ci authsize = maxdatasize; 240862306a36Sopenharmony_ci maxdatasize -= authsize; 240962306a36Sopenharmony_ci vec->setauthsize_error = crypto_aead_setauthsize(tfm, authsize); 241062306a36Sopenharmony_ci 241162306a36Sopenharmony_ci /* AAD, plaintext, and ciphertext lengths */ 241262306a36Sopenharmony_ci total_len = generate_random_length(rng, maxdatasize); 241362306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) 241462306a36Sopenharmony_ci vec->alen = 0; 241562306a36Sopenharmony_ci else 241662306a36Sopenharmony_ci vec->alen = generate_random_length(rng, total_len); 241762306a36Sopenharmony_ci vec->plen = total_len - vec->alen; 241862306a36Sopenharmony_ci vec->clen = vec->plen + authsize; 241962306a36Sopenharmony_ci 242062306a36Sopenharmony_ci /* 242162306a36Sopenharmony_ci * Generate the AAD, plaintext, and ciphertext. Not applicable if the 242262306a36Sopenharmony_ci * key or the authentication tag size couldn't be set. 242362306a36Sopenharmony_ci */ 242462306a36Sopenharmony_ci vec->novrfy = 0; 242562306a36Sopenharmony_ci vec->crypt_error = 0; 242662306a36Sopenharmony_ci if (vec->setkey_error == 0 && vec->setauthsize_error == 0) 242762306a36Sopenharmony_ci generate_aead_message(rng, req, suite, vec, prefer_inauthentic); 242862306a36Sopenharmony_ci snprintf(name, max_namelen, 242962306a36Sopenharmony_ci "\"random: alen=%u plen=%u authsize=%u klen=%u novrfy=%d\"", 243062306a36Sopenharmony_ci vec->alen, vec->plen, authsize, vec->klen, vec->novrfy); 243162306a36Sopenharmony_ci} 243262306a36Sopenharmony_ci 243362306a36Sopenharmony_cistatic void try_to_generate_inauthentic_testvec( 243462306a36Sopenharmony_ci struct aead_extra_tests_ctx *ctx) 243562306a36Sopenharmony_ci{ 243662306a36Sopenharmony_ci int i; 243762306a36Sopenharmony_ci 243862306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 243962306a36Sopenharmony_ci generate_random_aead_testvec(&ctx->rng, ctx->req, &ctx->vec, 244062306a36Sopenharmony_ci &ctx->test_desc->suite.aead, 244162306a36Sopenharmony_ci ctx->maxkeysize, ctx->maxdatasize, 244262306a36Sopenharmony_ci ctx->vec_name, 244362306a36Sopenharmony_ci sizeof(ctx->vec_name), true); 244462306a36Sopenharmony_ci if (ctx->vec.novrfy) 244562306a36Sopenharmony_ci return; 244662306a36Sopenharmony_ci } 244762306a36Sopenharmony_ci} 244862306a36Sopenharmony_ci 244962306a36Sopenharmony_ci/* 245062306a36Sopenharmony_ci * Generate inauthentic test vectors (i.e. ciphertext, AAD pairs that aren't the 245162306a36Sopenharmony_ci * result of an encryption with the key) and verify that decryption fails. 245262306a36Sopenharmony_ci */ 245362306a36Sopenharmony_cistatic int test_aead_inauthentic_inputs(struct aead_extra_tests_ctx *ctx) 245462306a36Sopenharmony_ci{ 245562306a36Sopenharmony_ci unsigned int i; 245662306a36Sopenharmony_ci int err; 245762306a36Sopenharmony_ci 245862306a36Sopenharmony_ci for (i = 0; i < fuzz_iterations * 8; i++) { 245962306a36Sopenharmony_ci /* 246062306a36Sopenharmony_ci * Since this part of the tests isn't comparing the 246162306a36Sopenharmony_ci * implementation to another, there's no point in testing any 246262306a36Sopenharmony_ci * test vectors other than inauthentic ones (vec.novrfy=1) here. 246362306a36Sopenharmony_ci * 246462306a36Sopenharmony_ci * If we're having trouble generating such a test vector, e.g. 246562306a36Sopenharmony_ci * if the algorithm keeps rejecting the generated keys, don't 246662306a36Sopenharmony_ci * retry forever; just continue on. 246762306a36Sopenharmony_ci */ 246862306a36Sopenharmony_ci try_to_generate_inauthentic_testvec(ctx); 246962306a36Sopenharmony_ci if (ctx->vec.novrfy) { 247062306a36Sopenharmony_ci generate_random_testvec_config(&ctx->rng, &ctx->cfg, 247162306a36Sopenharmony_ci ctx->cfgname, 247262306a36Sopenharmony_ci sizeof(ctx->cfgname)); 247362306a36Sopenharmony_ci err = test_aead_vec_cfg(DECRYPT, &ctx->vec, 247462306a36Sopenharmony_ci ctx->vec_name, &ctx->cfg, 247562306a36Sopenharmony_ci ctx->req, ctx->tsgls); 247662306a36Sopenharmony_ci if (err) 247762306a36Sopenharmony_ci return err; 247862306a36Sopenharmony_ci } 247962306a36Sopenharmony_ci cond_resched(); 248062306a36Sopenharmony_ci } 248162306a36Sopenharmony_ci return 0; 248262306a36Sopenharmony_ci} 248362306a36Sopenharmony_ci 248462306a36Sopenharmony_ci/* 248562306a36Sopenharmony_ci * Test the AEAD algorithm against the corresponding generic implementation, if 248662306a36Sopenharmony_ci * one is available. 248762306a36Sopenharmony_ci */ 248862306a36Sopenharmony_cistatic int test_aead_vs_generic_impl(struct aead_extra_tests_ctx *ctx) 248962306a36Sopenharmony_ci{ 249062306a36Sopenharmony_ci struct crypto_aead *tfm = ctx->tfm; 249162306a36Sopenharmony_ci const char *algname = crypto_aead_alg(tfm)->base.cra_name; 249262306a36Sopenharmony_ci const char *driver = crypto_aead_driver_name(tfm); 249362306a36Sopenharmony_ci const char *generic_driver = ctx->test_desc->generic_driver; 249462306a36Sopenharmony_ci char _generic_driver[CRYPTO_MAX_ALG_NAME]; 249562306a36Sopenharmony_ci struct crypto_aead *generic_tfm = NULL; 249662306a36Sopenharmony_ci struct aead_request *generic_req = NULL; 249762306a36Sopenharmony_ci unsigned int i; 249862306a36Sopenharmony_ci int err; 249962306a36Sopenharmony_ci 250062306a36Sopenharmony_ci if (!generic_driver) { /* Use default naming convention? */ 250162306a36Sopenharmony_ci err = build_generic_driver_name(algname, _generic_driver); 250262306a36Sopenharmony_ci if (err) 250362306a36Sopenharmony_ci return err; 250462306a36Sopenharmony_ci generic_driver = _generic_driver; 250562306a36Sopenharmony_ci } 250662306a36Sopenharmony_ci 250762306a36Sopenharmony_ci if (strcmp(generic_driver, driver) == 0) /* Already the generic impl? */ 250862306a36Sopenharmony_ci return 0; 250962306a36Sopenharmony_ci 251062306a36Sopenharmony_ci generic_tfm = crypto_alloc_aead(generic_driver, 0, 0); 251162306a36Sopenharmony_ci if (IS_ERR(generic_tfm)) { 251262306a36Sopenharmony_ci err = PTR_ERR(generic_tfm); 251362306a36Sopenharmony_ci if (err == -ENOENT) { 251462306a36Sopenharmony_ci pr_warn("alg: aead: skipping comparison tests for %s because %s is unavailable\n", 251562306a36Sopenharmony_ci driver, generic_driver); 251662306a36Sopenharmony_ci return 0; 251762306a36Sopenharmony_ci } 251862306a36Sopenharmony_ci pr_err("alg: aead: error allocating %s (generic impl of %s): %d\n", 251962306a36Sopenharmony_ci generic_driver, algname, err); 252062306a36Sopenharmony_ci return err; 252162306a36Sopenharmony_ci } 252262306a36Sopenharmony_ci 252362306a36Sopenharmony_ci generic_req = aead_request_alloc(generic_tfm, GFP_KERNEL); 252462306a36Sopenharmony_ci if (!generic_req) { 252562306a36Sopenharmony_ci err = -ENOMEM; 252662306a36Sopenharmony_ci goto out; 252762306a36Sopenharmony_ci } 252862306a36Sopenharmony_ci 252962306a36Sopenharmony_ci /* Check the algorithm properties for consistency. */ 253062306a36Sopenharmony_ci 253162306a36Sopenharmony_ci if (crypto_aead_maxauthsize(tfm) != 253262306a36Sopenharmony_ci crypto_aead_maxauthsize(generic_tfm)) { 253362306a36Sopenharmony_ci pr_err("alg: aead: maxauthsize for %s (%u) doesn't match generic impl (%u)\n", 253462306a36Sopenharmony_ci driver, crypto_aead_maxauthsize(tfm), 253562306a36Sopenharmony_ci crypto_aead_maxauthsize(generic_tfm)); 253662306a36Sopenharmony_ci err = -EINVAL; 253762306a36Sopenharmony_ci goto out; 253862306a36Sopenharmony_ci } 253962306a36Sopenharmony_ci 254062306a36Sopenharmony_ci if (crypto_aead_ivsize(tfm) != crypto_aead_ivsize(generic_tfm)) { 254162306a36Sopenharmony_ci pr_err("alg: aead: ivsize for %s (%u) doesn't match generic impl (%u)\n", 254262306a36Sopenharmony_ci driver, crypto_aead_ivsize(tfm), 254362306a36Sopenharmony_ci crypto_aead_ivsize(generic_tfm)); 254462306a36Sopenharmony_ci err = -EINVAL; 254562306a36Sopenharmony_ci goto out; 254662306a36Sopenharmony_ci } 254762306a36Sopenharmony_ci 254862306a36Sopenharmony_ci if (crypto_aead_blocksize(tfm) != crypto_aead_blocksize(generic_tfm)) { 254962306a36Sopenharmony_ci pr_err("alg: aead: blocksize for %s (%u) doesn't match generic impl (%u)\n", 255062306a36Sopenharmony_ci driver, crypto_aead_blocksize(tfm), 255162306a36Sopenharmony_ci crypto_aead_blocksize(generic_tfm)); 255262306a36Sopenharmony_ci err = -EINVAL; 255362306a36Sopenharmony_ci goto out; 255462306a36Sopenharmony_ci } 255562306a36Sopenharmony_ci 255662306a36Sopenharmony_ci /* 255762306a36Sopenharmony_ci * Now generate test vectors using the generic implementation, and test 255862306a36Sopenharmony_ci * the other implementation against them. 255962306a36Sopenharmony_ci */ 256062306a36Sopenharmony_ci for (i = 0; i < fuzz_iterations * 8; i++) { 256162306a36Sopenharmony_ci generate_random_aead_testvec(&ctx->rng, generic_req, &ctx->vec, 256262306a36Sopenharmony_ci &ctx->test_desc->suite.aead, 256362306a36Sopenharmony_ci ctx->maxkeysize, ctx->maxdatasize, 256462306a36Sopenharmony_ci ctx->vec_name, 256562306a36Sopenharmony_ci sizeof(ctx->vec_name), false); 256662306a36Sopenharmony_ci generate_random_testvec_config(&ctx->rng, &ctx->cfg, 256762306a36Sopenharmony_ci ctx->cfgname, 256862306a36Sopenharmony_ci sizeof(ctx->cfgname)); 256962306a36Sopenharmony_ci if (!ctx->vec.novrfy) { 257062306a36Sopenharmony_ci err = test_aead_vec_cfg(ENCRYPT, &ctx->vec, 257162306a36Sopenharmony_ci ctx->vec_name, &ctx->cfg, 257262306a36Sopenharmony_ci ctx->req, ctx->tsgls); 257362306a36Sopenharmony_ci if (err) 257462306a36Sopenharmony_ci goto out; 257562306a36Sopenharmony_ci } 257662306a36Sopenharmony_ci if (ctx->vec.crypt_error == 0 || ctx->vec.novrfy) { 257762306a36Sopenharmony_ci err = test_aead_vec_cfg(DECRYPT, &ctx->vec, 257862306a36Sopenharmony_ci ctx->vec_name, &ctx->cfg, 257962306a36Sopenharmony_ci ctx->req, ctx->tsgls); 258062306a36Sopenharmony_ci if (err) 258162306a36Sopenharmony_ci goto out; 258262306a36Sopenharmony_ci } 258362306a36Sopenharmony_ci cond_resched(); 258462306a36Sopenharmony_ci } 258562306a36Sopenharmony_ci err = 0; 258662306a36Sopenharmony_ciout: 258762306a36Sopenharmony_ci crypto_free_aead(generic_tfm); 258862306a36Sopenharmony_ci aead_request_free(generic_req); 258962306a36Sopenharmony_ci return err; 259062306a36Sopenharmony_ci} 259162306a36Sopenharmony_ci 259262306a36Sopenharmony_cistatic int test_aead_extra(const struct alg_test_desc *test_desc, 259362306a36Sopenharmony_ci struct aead_request *req, 259462306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 259562306a36Sopenharmony_ci{ 259662306a36Sopenharmony_ci struct aead_extra_tests_ctx *ctx; 259762306a36Sopenharmony_ci unsigned int i; 259862306a36Sopenharmony_ci int err; 259962306a36Sopenharmony_ci 260062306a36Sopenharmony_ci if (noextratests) 260162306a36Sopenharmony_ci return 0; 260262306a36Sopenharmony_ci 260362306a36Sopenharmony_ci ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 260462306a36Sopenharmony_ci if (!ctx) 260562306a36Sopenharmony_ci return -ENOMEM; 260662306a36Sopenharmony_ci init_rnd_state(&ctx->rng); 260762306a36Sopenharmony_ci ctx->req = req; 260862306a36Sopenharmony_ci ctx->tfm = crypto_aead_reqtfm(req); 260962306a36Sopenharmony_ci ctx->test_desc = test_desc; 261062306a36Sopenharmony_ci ctx->tsgls = tsgls; 261162306a36Sopenharmony_ci ctx->maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN; 261262306a36Sopenharmony_ci ctx->maxkeysize = 0; 261362306a36Sopenharmony_ci for (i = 0; i < test_desc->suite.aead.count; i++) 261462306a36Sopenharmony_ci ctx->maxkeysize = max_t(unsigned int, ctx->maxkeysize, 261562306a36Sopenharmony_ci test_desc->suite.aead.vecs[i].klen); 261662306a36Sopenharmony_ci 261762306a36Sopenharmony_ci ctx->vec.key = kmalloc(ctx->maxkeysize, GFP_KERNEL); 261862306a36Sopenharmony_ci ctx->vec.iv = kmalloc(crypto_aead_ivsize(ctx->tfm), GFP_KERNEL); 261962306a36Sopenharmony_ci ctx->vec.assoc = kmalloc(ctx->maxdatasize, GFP_KERNEL); 262062306a36Sopenharmony_ci ctx->vec.ptext = kmalloc(ctx->maxdatasize, GFP_KERNEL); 262162306a36Sopenharmony_ci ctx->vec.ctext = kmalloc(ctx->maxdatasize, GFP_KERNEL); 262262306a36Sopenharmony_ci if (!ctx->vec.key || !ctx->vec.iv || !ctx->vec.assoc || 262362306a36Sopenharmony_ci !ctx->vec.ptext || !ctx->vec.ctext) { 262462306a36Sopenharmony_ci err = -ENOMEM; 262562306a36Sopenharmony_ci goto out; 262662306a36Sopenharmony_ci } 262762306a36Sopenharmony_ci 262862306a36Sopenharmony_ci err = test_aead_vs_generic_impl(ctx); 262962306a36Sopenharmony_ci if (err) 263062306a36Sopenharmony_ci goto out; 263162306a36Sopenharmony_ci 263262306a36Sopenharmony_ci err = test_aead_inauthentic_inputs(ctx); 263362306a36Sopenharmony_ciout: 263462306a36Sopenharmony_ci kfree(ctx->vec.key); 263562306a36Sopenharmony_ci kfree(ctx->vec.iv); 263662306a36Sopenharmony_ci kfree(ctx->vec.assoc); 263762306a36Sopenharmony_ci kfree(ctx->vec.ptext); 263862306a36Sopenharmony_ci kfree(ctx->vec.ctext); 263962306a36Sopenharmony_ci kfree(ctx); 264062306a36Sopenharmony_ci return err; 264162306a36Sopenharmony_ci} 264262306a36Sopenharmony_ci#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 264362306a36Sopenharmony_cistatic int test_aead_extra(const struct alg_test_desc *test_desc, 264462306a36Sopenharmony_ci struct aead_request *req, 264562306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 264662306a36Sopenharmony_ci{ 264762306a36Sopenharmony_ci return 0; 264862306a36Sopenharmony_ci} 264962306a36Sopenharmony_ci#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 265062306a36Sopenharmony_ci 265162306a36Sopenharmony_cistatic int test_aead(int enc, const struct aead_test_suite *suite, 265262306a36Sopenharmony_ci struct aead_request *req, 265362306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 265462306a36Sopenharmony_ci{ 265562306a36Sopenharmony_ci unsigned int i; 265662306a36Sopenharmony_ci int err; 265762306a36Sopenharmony_ci 265862306a36Sopenharmony_ci for (i = 0; i < suite->count; i++) { 265962306a36Sopenharmony_ci err = test_aead_vec(enc, &suite->vecs[i], i, req, tsgls); 266062306a36Sopenharmony_ci if (err) 266162306a36Sopenharmony_ci return err; 266262306a36Sopenharmony_ci cond_resched(); 266362306a36Sopenharmony_ci } 266462306a36Sopenharmony_ci return 0; 266562306a36Sopenharmony_ci} 266662306a36Sopenharmony_ci 266762306a36Sopenharmony_cistatic int alg_test_aead(const struct alg_test_desc *desc, const char *driver, 266862306a36Sopenharmony_ci u32 type, u32 mask) 266962306a36Sopenharmony_ci{ 267062306a36Sopenharmony_ci const struct aead_test_suite *suite = &desc->suite.aead; 267162306a36Sopenharmony_ci struct crypto_aead *tfm; 267262306a36Sopenharmony_ci struct aead_request *req = NULL; 267362306a36Sopenharmony_ci struct cipher_test_sglists *tsgls = NULL; 267462306a36Sopenharmony_ci int err; 267562306a36Sopenharmony_ci 267662306a36Sopenharmony_ci if (suite->count <= 0) { 267762306a36Sopenharmony_ci pr_err("alg: aead: empty test suite for %s\n", driver); 267862306a36Sopenharmony_ci return -EINVAL; 267962306a36Sopenharmony_ci } 268062306a36Sopenharmony_ci 268162306a36Sopenharmony_ci tfm = crypto_alloc_aead(driver, type, mask); 268262306a36Sopenharmony_ci if (IS_ERR(tfm)) { 268362306a36Sopenharmony_ci pr_err("alg: aead: failed to allocate transform for %s: %ld\n", 268462306a36Sopenharmony_ci driver, PTR_ERR(tfm)); 268562306a36Sopenharmony_ci return PTR_ERR(tfm); 268662306a36Sopenharmony_ci } 268762306a36Sopenharmony_ci driver = crypto_aead_driver_name(tfm); 268862306a36Sopenharmony_ci 268962306a36Sopenharmony_ci req = aead_request_alloc(tfm, GFP_KERNEL); 269062306a36Sopenharmony_ci if (!req) { 269162306a36Sopenharmony_ci pr_err("alg: aead: failed to allocate request for %s\n", 269262306a36Sopenharmony_ci driver); 269362306a36Sopenharmony_ci err = -ENOMEM; 269462306a36Sopenharmony_ci goto out; 269562306a36Sopenharmony_ci } 269662306a36Sopenharmony_ci 269762306a36Sopenharmony_ci tsgls = alloc_cipher_test_sglists(); 269862306a36Sopenharmony_ci if (!tsgls) { 269962306a36Sopenharmony_ci pr_err("alg: aead: failed to allocate test buffers for %s\n", 270062306a36Sopenharmony_ci driver); 270162306a36Sopenharmony_ci err = -ENOMEM; 270262306a36Sopenharmony_ci goto out; 270362306a36Sopenharmony_ci } 270462306a36Sopenharmony_ci 270562306a36Sopenharmony_ci err = test_aead(ENCRYPT, suite, req, tsgls); 270662306a36Sopenharmony_ci if (err) 270762306a36Sopenharmony_ci goto out; 270862306a36Sopenharmony_ci 270962306a36Sopenharmony_ci err = test_aead(DECRYPT, suite, req, tsgls); 271062306a36Sopenharmony_ci if (err) 271162306a36Sopenharmony_ci goto out; 271262306a36Sopenharmony_ci 271362306a36Sopenharmony_ci err = test_aead_extra(desc, req, tsgls); 271462306a36Sopenharmony_ciout: 271562306a36Sopenharmony_ci free_cipher_test_sglists(tsgls); 271662306a36Sopenharmony_ci aead_request_free(req); 271762306a36Sopenharmony_ci crypto_free_aead(tfm); 271862306a36Sopenharmony_ci return err; 271962306a36Sopenharmony_ci} 272062306a36Sopenharmony_ci 272162306a36Sopenharmony_cistatic int test_cipher(struct crypto_cipher *tfm, int enc, 272262306a36Sopenharmony_ci const struct cipher_testvec *template, 272362306a36Sopenharmony_ci unsigned int tcount) 272462306a36Sopenharmony_ci{ 272562306a36Sopenharmony_ci const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); 272662306a36Sopenharmony_ci unsigned int i, j, k; 272762306a36Sopenharmony_ci char *q; 272862306a36Sopenharmony_ci const char *e; 272962306a36Sopenharmony_ci const char *input, *result; 273062306a36Sopenharmony_ci void *data; 273162306a36Sopenharmony_ci char *xbuf[XBUFSIZE]; 273262306a36Sopenharmony_ci int ret = -ENOMEM; 273362306a36Sopenharmony_ci 273462306a36Sopenharmony_ci if (testmgr_alloc_buf(xbuf)) 273562306a36Sopenharmony_ci goto out_nobuf; 273662306a36Sopenharmony_ci 273762306a36Sopenharmony_ci if (enc == ENCRYPT) 273862306a36Sopenharmony_ci e = "encryption"; 273962306a36Sopenharmony_ci else 274062306a36Sopenharmony_ci e = "decryption"; 274162306a36Sopenharmony_ci 274262306a36Sopenharmony_ci j = 0; 274362306a36Sopenharmony_ci for (i = 0; i < tcount; i++) { 274462306a36Sopenharmony_ci 274562306a36Sopenharmony_ci if (fips_enabled && template[i].fips_skip) 274662306a36Sopenharmony_ci continue; 274762306a36Sopenharmony_ci 274862306a36Sopenharmony_ci input = enc ? template[i].ptext : template[i].ctext; 274962306a36Sopenharmony_ci result = enc ? template[i].ctext : template[i].ptext; 275062306a36Sopenharmony_ci j++; 275162306a36Sopenharmony_ci 275262306a36Sopenharmony_ci ret = -EINVAL; 275362306a36Sopenharmony_ci if (WARN_ON(template[i].len > PAGE_SIZE)) 275462306a36Sopenharmony_ci goto out; 275562306a36Sopenharmony_ci 275662306a36Sopenharmony_ci data = xbuf[0]; 275762306a36Sopenharmony_ci memcpy(data, input, template[i].len); 275862306a36Sopenharmony_ci 275962306a36Sopenharmony_ci crypto_cipher_clear_flags(tfm, ~0); 276062306a36Sopenharmony_ci if (template[i].wk) 276162306a36Sopenharmony_ci crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 276262306a36Sopenharmony_ci 276362306a36Sopenharmony_ci ret = crypto_cipher_setkey(tfm, template[i].key, 276462306a36Sopenharmony_ci template[i].klen); 276562306a36Sopenharmony_ci if (ret) { 276662306a36Sopenharmony_ci if (ret == template[i].setkey_error) 276762306a36Sopenharmony_ci continue; 276862306a36Sopenharmony_ci pr_err("alg: cipher: %s setkey failed on test vector %u; expected_error=%d, actual_error=%d, flags=%#x\n", 276962306a36Sopenharmony_ci algo, j, template[i].setkey_error, ret, 277062306a36Sopenharmony_ci crypto_cipher_get_flags(tfm)); 277162306a36Sopenharmony_ci goto out; 277262306a36Sopenharmony_ci } 277362306a36Sopenharmony_ci if (template[i].setkey_error) { 277462306a36Sopenharmony_ci pr_err("alg: cipher: %s setkey unexpectedly succeeded on test vector %u; expected_error=%d\n", 277562306a36Sopenharmony_ci algo, j, template[i].setkey_error); 277662306a36Sopenharmony_ci ret = -EINVAL; 277762306a36Sopenharmony_ci goto out; 277862306a36Sopenharmony_ci } 277962306a36Sopenharmony_ci 278062306a36Sopenharmony_ci for (k = 0; k < template[i].len; 278162306a36Sopenharmony_ci k += crypto_cipher_blocksize(tfm)) { 278262306a36Sopenharmony_ci if (enc) 278362306a36Sopenharmony_ci crypto_cipher_encrypt_one(tfm, data + k, 278462306a36Sopenharmony_ci data + k); 278562306a36Sopenharmony_ci else 278662306a36Sopenharmony_ci crypto_cipher_decrypt_one(tfm, data + k, 278762306a36Sopenharmony_ci data + k); 278862306a36Sopenharmony_ci } 278962306a36Sopenharmony_ci 279062306a36Sopenharmony_ci q = data; 279162306a36Sopenharmony_ci if (memcmp(q, result, template[i].len)) { 279262306a36Sopenharmony_ci printk(KERN_ERR "alg: cipher: Test %d failed " 279362306a36Sopenharmony_ci "on %s for %s\n", j, e, algo); 279462306a36Sopenharmony_ci hexdump(q, template[i].len); 279562306a36Sopenharmony_ci ret = -EINVAL; 279662306a36Sopenharmony_ci goto out; 279762306a36Sopenharmony_ci } 279862306a36Sopenharmony_ci } 279962306a36Sopenharmony_ci 280062306a36Sopenharmony_ci ret = 0; 280162306a36Sopenharmony_ci 280262306a36Sopenharmony_ciout: 280362306a36Sopenharmony_ci testmgr_free_buf(xbuf); 280462306a36Sopenharmony_ciout_nobuf: 280562306a36Sopenharmony_ci return ret; 280662306a36Sopenharmony_ci} 280762306a36Sopenharmony_ci 280862306a36Sopenharmony_cistatic int test_skcipher_vec_cfg(int enc, const struct cipher_testvec *vec, 280962306a36Sopenharmony_ci const char *vec_name, 281062306a36Sopenharmony_ci const struct testvec_config *cfg, 281162306a36Sopenharmony_ci struct skcipher_request *req, 281262306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 281362306a36Sopenharmony_ci{ 281462306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 281562306a36Sopenharmony_ci const unsigned int alignmask = crypto_skcipher_alignmask(tfm); 281662306a36Sopenharmony_ci const unsigned int ivsize = crypto_skcipher_ivsize(tfm); 281762306a36Sopenharmony_ci const char *driver = crypto_skcipher_driver_name(tfm); 281862306a36Sopenharmony_ci const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 281962306a36Sopenharmony_ci const char *op = enc ? "encryption" : "decryption"; 282062306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 282162306a36Sopenharmony_ci u8 _iv[3 * (MAX_ALGAPI_ALIGNMASK + 1) + MAX_IVLEN]; 282262306a36Sopenharmony_ci u8 *iv = PTR_ALIGN(&_iv[0], 2 * (MAX_ALGAPI_ALIGNMASK + 1)) + 282362306a36Sopenharmony_ci cfg->iv_offset + 282462306a36Sopenharmony_ci (cfg->iv_offset_relative_to_alignmask ? alignmask : 0); 282562306a36Sopenharmony_ci struct kvec input; 282662306a36Sopenharmony_ci int err; 282762306a36Sopenharmony_ci 282862306a36Sopenharmony_ci /* Set the key */ 282962306a36Sopenharmony_ci if (vec->wk) 283062306a36Sopenharmony_ci crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 283162306a36Sopenharmony_ci else 283262306a36Sopenharmony_ci crypto_skcipher_clear_flags(tfm, 283362306a36Sopenharmony_ci CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 283462306a36Sopenharmony_ci err = do_setkey(crypto_skcipher_setkey, tfm, vec->key, vec->klen, 283562306a36Sopenharmony_ci cfg, alignmask); 283662306a36Sopenharmony_ci if (err) { 283762306a36Sopenharmony_ci if (err == vec->setkey_error) 283862306a36Sopenharmony_ci return 0; 283962306a36Sopenharmony_ci pr_err("alg: skcipher: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n", 284062306a36Sopenharmony_ci driver, vec_name, vec->setkey_error, err, 284162306a36Sopenharmony_ci crypto_skcipher_get_flags(tfm)); 284262306a36Sopenharmony_ci return err; 284362306a36Sopenharmony_ci } 284462306a36Sopenharmony_ci if (vec->setkey_error) { 284562306a36Sopenharmony_ci pr_err("alg: skcipher: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n", 284662306a36Sopenharmony_ci driver, vec_name, vec->setkey_error); 284762306a36Sopenharmony_ci return -EINVAL; 284862306a36Sopenharmony_ci } 284962306a36Sopenharmony_ci 285062306a36Sopenharmony_ci /* The IV must be copied to a buffer, as the algorithm may modify it */ 285162306a36Sopenharmony_ci if (ivsize) { 285262306a36Sopenharmony_ci if (WARN_ON(ivsize > MAX_IVLEN)) 285362306a36Sopenharmony_ci return -EINVAL; 285462306a36Sopenharmony_ci if (vec->generates_iv && !enc) 285562306a36Sopenharmony_ci memcpy(iv, vec->iv_out, ivsize); 285662306a36Sopenharmony_ci else if (vec->iv) 285762306a36Sopenharmony_ci memcpy(iv, vec->iv, ivsize); 285862306a36Sopenharmony_ci else 285962306a36Sopenharmony_ci memset(iv, 0, ivsize); 286062306a36Sopenharmony_ci } else { 286162306a36Sopenharmony_ci if (vec->generates_iv) { 286262306a36Sopenharmony_ci pr_err("alg: skcipher: %s has ivsize=0 but test vector %s generates IV!\n", 286362306a36Sopenharmony_ci driver, vec_name); 286462306a36Sopenharmony_ci return -EINVAL; 286562306a36Sopenharmony_ci } 286662306a36Sopenharmony_ci iv = NULL; 286762306a36Sopenharmony_ci } 286862306a36Sopenharmony_ci 286962306a36Sopenharmony_ci /* Build the src/dst scatterlists */ 287062306a36Sopenharmony_ci input.iov_base = enc ? (void *)vec->ptext : (void *)vec->ctext; 287162306a36Sopenharmony_ci input.iov_len = vec->len; 287262306a36Sopenharmony_ci err = build_cipher_test_sglists(tsgls, cfg, alignmask, 287362306a36Sopenharmony_ci vec->len, vec->len, &input, 1); 287462306a36Sopenharmony_ci if (err) { 287562306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s: error preparing scatterlists for test vector %s, cfg=\"%s\"\n", 287662306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 287762306a36Sopenharmony_ci return err; 287862306a36Sopenharmony_ci } 287962306a36Sopenharmony_ci 288062306a36Sopenharmony_ci /* Do the actual encryption or decryption */ 288162306a36Sopenharmony_ci testmgr_poison(req->__ctx, crypto_skcipher_reqsize(tfm)); 288262306a36Sopenharmony_ci skcipher_request_set_callback(req, req_flags, crypto_req_done, &wait); 288362306a36Sopenharmony_ci skcipher_request_set_crypt(req, tsgls->src.sgl_ptr, tsgls->dst.sgl_ptr, 288462306a36Sopenharmony_ci vec->len, iv); 288562306a36Sopenharmony_ci if (cfg->nosimd) 288662306a36Sopenharmony_ci crypto_disable_simd_for_test(); 288762306a36Sopenharmony_ci err = enc ? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req); 288862306a36Sopenharmony_ci if (cfg->nosimd) 288962306a36Sopenharmony_ci crypto_reenable_simd_for_test(); 289062306a36Sopenharmony_ci err = crypto_wait_req(err, &wait); 289162306a36Sopenharmony_ci 289262306a36Sopenharmony_ci /* Check that the algorithm didn't overwrite things it shouldn't have */ 289362306a36Sopenharmony_ci if (req->cryptlen != vec->len || 289462306a36Sopenharmony_ci req->iv != iv || 289562306a36Sopenharmony_ci req->src != tsgls->src.sgl_ptr || 289662306a36Sopenharmony_ci req->dst != tsgls->dst.sgl_ptr || 289762306a36Sopenharmony_ci crypto_skcipher_reqtfm(req) != tfm || 289862306a36Sopenharmony_ci req->base.complete != crypto_req_done || 289962306a36Sopenharmony_ci req->base.flags != req_flags || 290062306a36Sopenharmony_ci req->base.data != &wait) { 290162306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s corrupted request struct on test vector %s, cfg=\"%s\"\n", 290262306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 290362306a36Sopenharmony_ci if (req->cryptlen != vec->len) 290462306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->cryptlen'\n"); 290562306a36Sopenharmony_ci if (req->iv != iv) 290662306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->iv'\n"); 290762306a36Sopenharmony_ci if (req->src != tsgls->src.sgl_ptr) 290862306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->src'\n"); 290962306a36Sopenharmony_ci if (req->dst != tsgls->dst.sgl_ptr) 291062306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->dst'\n"); 291162306a36Sopenharmony_ci if (crypto_skcipher_reqtfm(req) != tfm) 291262306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->base.tfm'\n"); 291362306a36Sopenharmony_ci if (req->base.complete != crypto_req_done) 291462306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->base.complete'\n"); 291562306a36Sopenharmony_ci if (req->base.flags != req_flags) 291662306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->base.flags'\n"); 291762306a36Sopenharmony_ci if (req->base.data != &wait) 291862306a36Sopenharmony_ci pr_err("alg: skcipher: changed 'req->base.data'\n"); 291962306a36Sopenharmony_ci return -EINVAL; 292062306a36Sopenharmony_ci } 292162306a36Sopenharmony_ci if (is_test_sglist_corrupted(&tsgls->src)) { 292262306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s corrupted src sgl on test vector %s, cfg=\"%s\"\n", 292362306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 292462306a36Sopenharmony_ci return -EINVAL; 292562306a36Sopenharmony_ci } 292662306a36Sopenharmony_ci if (tsgls->dst.sgl_ptr != tsgls->src.sgl && 292762306a36Sopenharmony_ci is_test_sglist_corrupted(&tsgls->dst)) { 292862306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s corrupted dst sgl on test vector %s, cfg=\"%s\"\n", 292962306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 293062306a36Sopenharmony_ci return -EINVAL; 293162306a36Sopenharmony_ci } 293262306a36Sopenharmony_ci 293362306a36Sopenharmony_ci /* Check for success or failure */ 293462306a36Sopenharmony_ci if (err) { 293562306a36Sopenharmony_ci if (err == vec->crypt_error) 293662306a36Sopenharmony_ci return 0; 293762306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s failed on test vector %s; expected_error=%d, actual_error=%d, cfg=\"%s\"\n", 293862306a36Sopenharmony_ci driver, op, vec_name, vec->crypt_error, err, cfg->name); 293962306a36Sopenharmony_ci return err; 294062306a36Sopenharmony_ci } 294162306a36Sopenharmony_ci if (vec->crypt_error) { 294262306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s unexpectedly succeeded on test vector %s; expected_error=%d, cfg=\"%s\"\n", 294362306a36Sopenharmony_ci driver, op, vec_name, vec->crypt_error, cfg->name); 294462306a36Sopenharmony_ci return -EINVAL; 294562306a36Sopenharmony_ci } 294662306a36Sopenharmony_ci 294762306a36Sopenharmony_ci /* Check for the correct output (ciphertext or plaintext) */ 294862306a36Sopenharmony_ci err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext, 294962306a36Sopenharmony_ci vec->len, 0, true); 295062306a36Sopenharmony_ci if (err == -EOVERFLOW) { 295162306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s overran dst buffer on test vector %s, cfg=\"%s\"\n", 295262306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 295362306a36Sopenharmony_ci return err; 295462306a36Sopenharmony_ci } 295562306a36Sopenharmony_ci if (err) { 295662306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s test failed (wrong result) on test vector %s, cfg=\"%s\"\n", 295762306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 295862306a36Sopenharmony_ci return err; 295962306a36Sopenharmony_ci } 296062306a36Sopenharmony_ci 296162306a36Sopenharmony_ci /* If applicable, check that the algorithm generated the correct IV */ 296262306a36Sopenharmony_ci if (vec->iv_out && memcmp(iv, vec->iv_out, ivsize) != 0) { 296362306a36Sopenharmony_ci pr_err("alg: skcipher: %s %s test failed (wrong output IV) on test vector %s, cfg=\"%s\"\n", 296462306a36Sopenharmony_ci driver, op, vec_name, cfg->name); 296562306a36Sopenharmony_ci hexdump(iv, ivsize); 296662306a36Sopenharmony_ci return -EINVAL; 296762306a36Sopenharmony_ci } 296862306a36Sopenharmony_ci 296962306a36Sopenharmony_ci return 0; 297062306a36Sopenharmony_ci} 297162306a36Sopenharmony_ci 297262306a36Sopenharmony_cistatic int test_skcipher_vec(int enc, const struct cipher_testvec *vec, 297362306a36Sopenharmony_ci unsigned int vec_num, 297462306a36Sopenharmony_ci struct skcipher_request *req, 297562306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 297662306a36Sopenharmony_ci{ 297762306a36Sopenharmony_ci char vec_name[16]; 297862306a36Sopenharmony_ci unsigned int i; 297962306a36Sopenharmony_ci int err; 298062306a36Sopenharmony_ci 298162306a36Sopenharmony_ci if (fips_enabled && vec->fips_skip) 298262306a36Sopenharmony_ci return 0; 298362306a36Sopenharmony_ci 298462306a36Sopenharmony_ci sprintf(vec_name, "%u", vec_num); 298562306a36Sopenharmony_ci 298662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) { 298762306a36Sopenharmony_ci err = test_skcipher_vec_cfg(enc, vec, vec_name, 298862306a36Sopenharmony_ci &default_cipher_testvec_configs[i], 298962306a36Sopenharmony_ci req, tsgls); 299062306a36Sopenharmony_ci if (err) 299162306a36Sopenharmony_ci return err; 299262306a36Sopenharmony_ci } 299362306a36Sopenharmony_ci 299462306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 299562306a36Sopenharmony_ci if (!noextratests) { 299662306a36Sopenharmony_ci struct rnd_state rng; 299762306a36Sopenharmony_ci struct testvec_config cfg; 299862306a36Sopenharmony_ci char cfgname[TESTVEC_CONFIG_NAMELEN]; 299962306a36Sopenharmony_ci 300062306a36Sopenharmony_ci init_rnd_state(&rng); 300162306a36Sopenharmony_ci 300262306a36Sopenharmony_ci for (i = 0; i < fuzz_iterations; i++) { 300362306a36Sopenharmony_ci generate_random_testvec_config(&rng, &cfg, cfgname, 300462306a36Sopenharmony_ci sizeof(cfgname)); 300562306a36Sopenharmony_ci err = test_skcipher_vec_cfg(enc, vec, vec_name, 300662306a36Sopenharmony_ci &cfg, req, tsgls); 300762306a36Sopenharmony_ci if (err) 300862306a36Sopenharmony_ci return err; 300962306a36Sopenharmony_ci cond_resched(); 301062306a36Sopenharmony_ci } 301162306a36Sopenharmony_ci } 301262306a36Sopenharmony_ci#endif 301362306a36Sopenharmony_ci return 0; 301462306a36Sopenharmony_ci} 301562306a36Sopenharmony_ci 301662306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 301762306a36Sopenharmony_ci/* 301862306a36Sopenharmony_ci * Generate a symmetric cipher test vector from the given implementation. 301962306a36Sopenharmony_ci * Assumes the buffers in 'vec' were already allocated. 302062306a36Sopenharmony_ci */ 302162306a36Sopenharmony_cistatic void generate_random_cipher_testvec(struct rnd_state *rng, 302262306a36Sopenharmony_ci struct skcipher_request *req, 302362306a36Sopenharmony_ci struct cipher_testvec *vec, 302462306a36Sopenharmony_ci unsigned int maxdatasize, 302562306a36Sopenharmony_ci char *name, size_t max_namelen) 302662306a36Sopenharmony_ci{ 302762306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 302862306a36Sopenharmony_ci const unsigned int maxkeysize = crypto_skcipher_max_keysize(tfm); 302962306a36Sopenharmony_ci const unsigned int ivsize = crypto_skcipher_ivsize(tfm); 303062306a36Sopenharmony_ci struct scatterlist src, dst; 303162306a36Sopenharmony_ci u8 iv[MAX_IVLEN]; 303262306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 303362306a36Sopenharmony_ci 303462306a36Sopenharmony_ci /* Key: length in [0, maxkeysize], but usually choose maxkeysize */ 303562306a36Sopenharmony_ci vec->klen = maxkeysize; 303662306a36Sopenharmony_ci if (prandom_u32_below(rng, 4) == 0) 303762306a36Sopenharmony_ci vec->klen = prandom_u32_below(rng, maxkeysize + 1); 303862306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->key, vec->klen); 303962306a36Sopenharmony_ci vec->setkey_error = crypto_skcipher_setkey(tfm, vec->key, vec->klen); 304062306a36Sopenharmony_ci 304162306a36Sopenharmony_ci /* IV */ 304262306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->iv, ivsize); 304362306a36Sopenharmony_ci 304462306a36Sopenharmony_ci /* Plaintext */ 304562306a36Sopenharmony_ci vec->len = generate_random_length(rng, maxdatasize); 304662306a36Sopenharmony_ci generate_random_bytes(rng, (u8 *)vec->ptext, vec->len); 304762306a36Sopenharmony_ci 304862306a36Sopenharmony_ci /* If the key couldn't be set, no need to continue to encrypt. */ 304962306a36Sopenharmony_ci if (vec->setkey_error) 305062306a36Sopenharmony_ci goto done; 305162306a36Sopenharmony_ci 305262306a36Sopenharmony_ci /* Ciphertext */ 305362306a36Sopenharmony_ci sg_init_one(&src, vec->ptext, vec->len); 305462306a36Sopenharmony_ci sg_init_one(&dst, vec->ctext, vec->len); 305562306a36Sopenharmony_ci memcpy(iv, vec->iv, ivsize); 305662306a36Sopenharmony_ci skcipher_request_set_callback(req, 0, crypto_req_done, &wait); 305762306a36Sopenharmony_ci skcipher_request_set_crypt(req, &src, &dst, vec->len, iv); 305862306a36Sopenharmony_ci vec->crypt_error = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 305962306a36Sopenharmony_ci if (vec->crypt_error != 0) { 306062306a36Sopenharmony_ci /* 306162306a36Sopenharmony_ci * The only acceptable error here is for an invalid length, so 306262306a36Sopenharmony_ci * skcipher decryption should fail with the same error too. 306362306a36Sopenharmony_ci * We'll test for this. But to keep the API usage well-defined, 306462306a36Sopenharmony_ci * explicitly initialize the ciphertext buffer too. 306562306a36Sopenharmony_ci */ 306662306a36Sopenharmony_ci memset((u8 *)vec->ctext, 0, vec->len); 306762306a36Sopenharmony_ci } 306862306a36Sopenharmony_cidone: 306962306a36Sopenharmony_ci snprintf(name, max_namelen, "\"random: len=%u klen=%u\"", 307062306a36Sopenharmony_ci vec->len, vec->klen); 307162306a36Sopenharmony_ci} 307262306a36Sopenharmony_ci 307362306a36Sopenharmony_ci/* 307462306a36Sopenharmony_ci * Test the skcipher algorithm represented by @req against the corresponding 307562306a36Sopenharmony_ci * generic implementation, if one is available. 307662306a36Sopenharmony_ci */ 307762306a36Sopenharmony_cistatic int test_skcipher_vs_generic_impl(const char *generic_driver, 307862306a36Sopenharmony_ci struct skcipher_request *req, 307962306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 308062306a36Sopenharmony_ci{ 308162306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 308262306a36Sopenharmony_ci const unsigned int maxkeysize = crypto_skcipher_max_keysize(tfm); 308362306a36Sopenharmony_ci const unsigned int ivsize = crypto_skcipher_ivsize(tfm); 308462306a36Sopenharmony_ci const unsigned int blocksize = crypto_skcipher_blocksize(tfm); 308562306a36Sopenharmony_ci const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN; 308662306a36Sopenharmony_ci const char *algname = crypto_skcipher_alg(tfm)->base.cra_name; 308762306a36Sopenharmony_ci const char *driver = crypto_skcipher_driver_name(tfm); 308862306a36Sopenharmony_ci struct rnd_state rng; 308962306a36Sopenharmony_ci char _generic_driver[CRYPTO_MAX_ALG_NAME]; 309062306a36Sopenharmony_ci struct crypto_skcipher *generic_tfm = NULL; 309162306a36Sopenharmony_ci struct skcipher_request *generic_req = NULL; 309262306a36Sopenharmony_ci unsigned int i; 309362306a36Sopenharmony_ci struct cipher_testvec vec = { 0 }; 309462306a36Sopenharmony_ci char vec_name[64]; 309562306a36Sopenharmony_ci struct testvec_config *cfg; 309662306a36Sopenharmony_ci char cfgname[TESTVEC_CONFIG_NAMELEN]; 309762306a36Sopenharmony_ci int err; 309862306a36Sopenharmony_ci 309962306a36Sopenharmony_ci if (noextratests) 310062306a36Sopenharmony_ci return 0; 310162306a36Sopenharmony_ci 310262306a36Sopenharmony_ci /* Keywrap isn't supported here yet as it handles its IV differently. */ 310362306a36Sopenharmony_ci if (strncmp(algname, "kw(", 3) == 0) 310462306a36Sopenharmony_ci return 0; 310562306a36Sopenharmony_ci 310662306a36Sopenharmony_ci init_rnd_state(&rng); 310762306a36Sopenharmony_ci 310862306a36Sopenharmony_ci if (!generic_driver) { /* Use default naming convention? */ 310962306a36Sopenharmony_ci err = build_generic_driver_name(algname, _generic_driver); 311062306a36Sopenharmony_ci if (err) 311162306a36Sopenharmony_ci return err; 311262306a36Sopenharmony_ci generic_driver = _generic_driver; 311362306a36Sopenharmony_ci } 311462306a36Sopenharmony_ci 311562306a36Sopenharmony_ci if (strcmp(generic_driver, driver) == 0) /* Already the generic impl? */ 311662306a36Sopenharmony_ci return 0; 311762306a36Sopenharmony_ci 311862306a36Sopenharmony_ci generic_tfm = crypto_alloc_skcipher(generic_driver, 0, 0); 311962306a36Sopenharmony_ci if (IS_ERR(generic_tfm)) { 312062306a36Sopenharmony_ci err = PTR_ERR(generic_tfm); 312162306a36Sopenharmony_ci if (err == -ENOENT) { 312262306a36Sopenharmony_ci pr_warn("alg: skcipher: skipping comparison tests for %s because %s is unavailable\n", 312362306a36Sopenharmony_ci driver, generic_driver); 312462306a36Sopenharmony_ci return 0; 312562306a36Sopenharmony_ci } 312662306a36Sopenharmony_ci pr_err("alg: skcipher: error allocating %s (generic impl of %s): %d\n", 312762306a36Sopenharmony_ci generic_driver, algname, err); 312862306a36Sopenharmony_ci return err; 312962306a36Sopenharmony_ci } 313062306a36Sopenharmony_ci 313162306a36Sopenharmony_ci cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 313262306a36Sopenharmony_ci if (!cfg) { 313362306a36Sopenharmony_ci err = -ENOMEM; 313462306a36Sopenharmony_ci goto out; 313562306a36Sopenharmony_ci } 313662306a36Sopenharmony_ci 313762306a36Sopenharmony_ci generic_req = skcipher_request_alloc(generic_tfm, GFP_KERNEL); 313862306a36Sopenharmony_ci if (!generic_req) { 313962306a36Sopenharmony_ci err = -ENOMEM; 314062306a36Sopenharmony_ci goto out; 314162306a36Sopenharmony_ci } 314262306a36Sopenharmony_ci 314362306a36Sopenharmony_ci /* Check the algorithm properties for consistency. */ 314462306a36Sopenharmony_ci 314562306a36Sopenharmony_ci if (crypto_skcipher_min_keysize(tfm) != 314662306a36Sopenharmony_ci crypto_skcipher_min_keysize(generic_tfm)) { 314762306a36Sopenharmony_ci pr_err("alg: skcipher: min keysize for %s (%u) doesn't match generic impl (%u)\n", 314862306a36Sopenharmony_ci driver, crypto_skcipher_min_keysize(tfm), 314962306a36Sopenharmony_ci crypto_skcipher_min_keysize(generic_tfm)); 315062306a36Sopenharmony_ci err = -EINVAL; 315162306a36Sopenharmony_ci goto out; 315262306a36Sopenharmony_ci } 315362306a36Sopenharmony_ci 315462306a36Sopenharmony_ci if (maxkeysize != crypto_skcipher_max_keysize(generic_tfm)) { 315562306a36Sopenharmony_ci pr_err("alg: skcipher: max keysize for %s (%u) doesn't match generic impl (%u)\n", 315662306a36Sopenharmony_ci driver, maxkeysize, 315762306a36Sopenharmony_ci crypto_skcipher_max_keysize(generic_tfm)); 315862306a36Sopenharmony_ci err = -EINVAL; 315962306a36Sopenharmony_ci goto out; 316062306a36Sopenharmony_ci } 316162306a36Sopenharmony_ci 316262306a36Sopenharmony_ci if (ivsize != crypto_skcipher_ivsize(generic_tfm)) { 316362306a36Sopenharmony_ci pr_err("alg: skcipher: ivsize for %s (%u) doesn't match generic impl (%u)\n", 316462306a36Sopenharmony_ci driver, ivsize, crypto_skcipher_ivsize(generic_tfm)); 316562306a36Sopenharmony_ci err = -EINVAL; 316662306a36Sopenharmony_ci goto out; 316762306a36Sopenharmony_ci } 316862306a36Sopenharmony_ci 316962306a36Sopenharmony_ci if (blocksize != crypto_skcipher_blocksize(generic_tfm)) { 317062306a36Sopenharmony_ci pr_err("alg: skcipher: blocksize for %s (%u) doesn't match generic impl (%u)\n", 317162306a36Sopenharmony_ci driver, blocksize, 317262306a36Sopenharmony_ci crypto_skcipher_blocksize(generic_tfm)); 317362306a36Sopenharmony_ci err = -EINVAL; 317462306a36Sopenharmony_ci goto out; 317562306a36Sopenharmony_ci } 317662306a36Sopenharmony_ci 317762306a36Sopenharmony_ci /* 317862306a36Sopenharmony_ci * Now generate test vectors using the generic implementation, and test 317962306a36Sopenharmony_ci * the other implementation against them. 318062306a36Sopenharmony_ci */ 318162306a36Sopenharmony_ci 318262306a36Sopenharmony_ci vec.key = kmalloc(maxkeysize, GFP_KERNEL); 318362306a36Sopenharmony_ci vec.iv = kmalloc(ivsize, GFP_KERNEL); 318462306a36Sopenharmony_ci vec.ptext = kmalloc(maxdatasize, GFP_KERNEL); 318562306a36Sopenharmony_ci vec.ctext = kmalloc(maxdatasize, GFP_KERNEL); 318662306a36Sopenharmony_ci if (!vec.key || !vec.iv || !vec.ptext || !vec.ctext) { 318762306a36Sopenharmony_ci err = -ENOMEM; 318862306a36Sopenharmony_ci goto out; 318962306a36Sopenharmony_ci } 319062306a36Sopenharmony_ci 319162306a36Sopenharmony_ci for (i = 0; i < fuzz_iterations * 8; i++) { 319262306a36Sopenharmony_ci generate_random_cipher_testvec(&rng, generic_req, &vec, 319362306a36Sopenharmony_ci maxdatasize, 319462306a36Sopenharmony_ci vec_name, sizeof(vec_name)); 319562306a36Sopenharmony_ci generate_random_testvec_config(&rng, cfg, cfgname, 319662306a36Sopenharmony_ci sizeof(cfgname)); 319762306a36Sopenharmony_ci 319862306a36Sopenharmony_ci err = test_skcipher_vec_cfg(ENCRYPT, &vec, vec_name, 319962306a36Sopenharmony_ci cfg, req, tsgls); 320062306a36Sopenharmony_ci if (err) 320162306a36Sopenharmony_ci goto out; 320262306a36Sopenharmony_ci err = test_skcipher_vec_cfg(DECRYPT, &vec, vec_name, 320362306a36Sopenharmony_ci cfg, req, tsgls); 320462306a36Sopenharmony_ci if (err) 320562306a36Sopenharmony_ci goto out; 320662306a36Sopenharmony_ci cond_resched(); 320762306a36Sopenharmony_ci } 320862306a36Sopenharmony_ci err = 0; 320962306a36Sopenharmony_ciout: 321062306a36Sopenharmony_ci kfree(cfg); 321162306a36Sopenharmony_ci kfree(vec.key); 321262306a36Sopenharmony_ci kfree(vec.iv); 321362306a36Sopenharmony_ci kfree(vec.ptext); 321462306a36Sopenharmony_ci kfree(vec.ctext); 321562306a36Sopenharmony_ci crypto_free_skcipher(generic_tfm); 321662306a36Sopenharmony_ci skcipher_request_free(generic_req); 321762306a36Sopenharmony_ci return err; 321862306a36Sopenharmony_ci} 321962306a36Sopenharmony_ci#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 322062306a36Sopenharmony_cistatic int test_skcipher_vs_generic_impl(const char *generic_driver, 322162306a36Sopenharmony_ci struct skcipher_request *req, 322262306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 322362306a36Sopenharmony_ci{ 322462306a36Sopenharmony_ci return 0; 322562306a36Sopenharmony_ci} 322662306a36Sopenharmony_ci#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 322762306a36Sopenharmony_ci 322862306a36Sopenharmony_cistatic int test_skcipher(int enc, const struct cipher_test_suite *suite, 322962306a36Sopenharmony_ci struct skcipher_request *req, 323062306a36Sopenharmony_ci struct cipher_test_sglists *tsgls) 323162306a36Sopenharmony_ci{ 323262306a36Sopenharmony_ci unsigned int i; 323362306a36Sopenharmony_ci int err; 323462306a36Sopenharmony_ci 323562306a36Sopenharmony_ci for (i = 0; i < suite->count; i++) { 323662306a36Sopenharmony_ci err = test_skcipher_vec(enc, &suite->vecs[i], i, req, tsgls); 323762306a36Sopenharmony_ci if (err) 323862306a36Sopenharmony_ci return err; 323962306a36Sopenharmony_ci cond_resched(); 324062306a36Sopenharmony_ci } 324162306a36Sopenharmony_ci return 0; 324262306a36Sopenharmony_ci} 324362306a36Sopenharmony_ci 324462306a36Sopenharmony_cistatic int alg_test_skcipher(const struct alg_test_desc *desc, 324562306a36Sopenharmony_ci const char *driver, u32 type, u32 mask) 324662306a36Sopenharmony_ci{ 324762306a36Sopenharmony_ci const struct cipher_test_suite *suite = &desc->suite.cipher; 324862306a36Sopenharmony_ci struct crypto_skcipher *tfm; 324962306a36Sopenharmony_ci struct skcipher_request *req = NULL; 325062306a36Sopenharmony_ci struct cipher_test_sglists *tsgls = NULL; 325162306a36Sopenharmony_ci int err; 325262306a36Sopenharmony_ci 325362306a36Sopenharmony_ci if (suite->count <= 0) { 325462306a36Sopenharmony_ci pr_err("alg: skcipher: empty test suite for %s\n", driver); 325562306a36Sopenharmony_ci return -EINVAL; 325662306a36Sopenharmony_ci } 325762306a36Sopenharmony_ci 325862306a36Sopenharmony_ci tfm = crypto_alloc_skcipher(driver, type, mask); 325962306a36Sopenharmony_ci if (IS_ERR(tfm)) { 326062306a36Sopenharmony_ci pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", 326162306a36Sopenharmony_ci driver, PTR_ERR(tfm)); 326262306a36Sopenharmony_ci return PTR_ERR(tfm); 326362306a36Sopenharmony_ci } 326462306a36Sopenharmony_ci driver = crypto_skcipher_driver_name(tfm); 326562306a36Sopenharmony_ci 326662306a36Sopenharmony_ci req = skcipher_request_alloc(tfm, GFP_KERNEL); 326762306a36Sopenharmony_ci if (!req) { 326862306a36Sopenharmony_ci pr_err("alg: skcipher: failed to allocate request for %s\n", 326962306a36Sopenharmony_ci driver); 327062306a36Sopenharmony_ci err = -ENOMEM; 327162306a36Sopenharmony_ci goto out; 327262306a36Sopenharmony_ci } 327362306a36Sopenharmony_ci 327462306a36Sopenharmony_ci tsgls = alloc_cipher_test_sglists(); 327562306a36Sopenharmony_ci if (!tsgls) { 327662306a36Sopenharmony_ci pr_err("alg: skcipher: failed to allocate test buffers for %s\n", 327762306a36Sopenharmony_ci driver); 327862306a36Sopenharmony_ci err = -ENOMEM; 327962306a36Sopenharmony_ci goto out; 328062306a36Sopenharmony_ci } 328162306a36Sopenharmony_ci 328262306a36Sopenharmony_ci err = test_skcipher(ENCRYPT, suite, req, tsgls); 328362306a36Sopenharmony_ci if (err) 328462306a36Sopenharmony_ci goto out; 328562306a36Sopenharmony_ci 328662306a36Sopenharmony_ci err = test_skcipher(DECRYPT, suite, req, tsgls); 328762306a36Sopenharmony_ci if (err) 328862306a36Sopenharmony_ci goto out; 328962306a36Sopenharmony_ci 329062306a36Sopenharmony_ci err = test_skcipher_vs_generic_impl(desc->generic_driver, req, tsgls); 329162306a36Sopenharmony_ciout: 329262306a36Sopenharmony_ci free_cipher_test_sglists(tsgls); 329362306a36Sopenharmony_ci skcipher_request_free(req); 329462306a36Sopenharmony_ci crypto_free_skcipher(tfm); 329562306a36Sopenharmony_ci return err; 329662306a36Sopenharmony_ci} 329762306a36Sopenharmony_ci 329862306a36Sopenharmony_cistatic int test_comp(struct crypto_comp *tfm, 329962306a36Sopenharmony_ci const struct comp_testvec *ctemplate, 330062306a36Sopenharmony_ci const struct comp_testvec *dtemplate, 330162306a36Sopenharmony_ci int ctcount, int dtcount) 330262306a36Sopenharmony_ci{ 330362306a36Sopenharmony_ci const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm)); 330462306a36Sopenharmony_ci char *output, *decomp_output; 330562306a36Sopenharmony_ci unsigned int i; 330662306a36Sopenharmony_ci int ret; 330762306a36Sopenharmony_ci 330862306a36Sopenharmony_ci output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 330962306a36Sopenharmony_ci if (!output) 331062306a36Sopenharmony_ci return -ENOMEM; 331162306a36Sopenharmony_ci 331262306a36Sopenharmony_ci decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 331362306a36Sopenharmony_ci if (!decomp_output) { 331462306a36Sopenharmony_ci kfree(output); 331562306a36Sopenharmony_ci return -ENOMEM; 331662306a36Sopenharmony_ci } 331762306a36Sopenharmony_ci 331862306a36Sopenharmony_ci for (i = 0; i < ctcount; i++) { 331962306a36Sopenharmony_ci int ilen; 332062306a36Sopenharmony_ci unsigned int dlen = COMP_BUF_SIZE; 332162306a36Sopenharmony_ci 332262306a36Sopenharmony_ci memset(output, 0, COMP_BUF_SIZE); 332362306a36Sopenharmony_ci memset(decomp_output, 0, COMP_BUF_SIZE); 332462306a36Sopenharmony_ci 332562306a36Sopenharmony_ci ilen = ctemplate[i].inlen; 332662306a36Sopenharmony_ci ret = crypto_comp_compress(tfm, ctemplate[i].input, 332762306a36Sopenharmony_ci ilen, output, &dlen); 332862306a36Sopenharmony_ci if (ret) { 332962306a36Sopenharmony_ci printk(KERN_ERR "alg: comp: compression failed " 333062306a36Sopenharmony_ci "on test %d for %s: ret=%d\n", i + 1, algo, 333162306a36Sopenharmony_ci -ret); 333262306a36Sopenharmony_ci goto out; 333362306a36Sopenharmony_ci } 333462306a36Sopenharmony_ci 333562306a36Sopenharmony_ci ilen = dlen; 333662306a36Sopenharmony_ci dlen = COMP_BUF_SIZE; 333762306a36Sopenharmony_ci ret = crypto_comp_decompress(tfm, output, 333862306a36Sopenharmony_ci ilen, decomp_output, &dlen); 333962306a36Sopenharmony_ci if (ret) { 334062306a36Sopenharmony_ci pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n", 334162306a36Sopenharmony_ci i + 1, algo, -ret); 334262306a36Sopenharmony_ci goto out; 334362306a36Sopenharmony_ci } 334462306a36Sopenharmony_ci 334562306a36Sopenharmony_ci if (dlen != ctemplate[i].inlen) { 334662306a36Sopenharmony_ci printk(KERN_ERR "alg: comp: Compression test %d " 334762306a36Sopenharmony_ci "failed for %s: output len = %d\n", i + 1, algo, 334862306a36Sopenharmony_ci dlen); 334962306a36Sopenharmony_ci ret = -EINVAL; 335062306a36Sopenharmony_ci goto out; 335162306a36Sopenharmony_ci } 335262306a36Sopenharmony_ci 335362306a36Sopenharmony_ci if (memcmp(decomp_output, ctemplate[i].input, 335462306a36Sopenharmony_ci ctemplate[i].inlen)) { 335562306a36Sopenharmony_ci pr_err("alg: comp: compression failed: output differs: on test %d for %s\n", 335662306a36Sopenharmony_ci i + 1, algo); 335762306a36Sopenharmony_ci hexdump(decomp_output, dlen); 335862306a36Sopenharmony_ci ret = -EINVAL; 335962306a36Sopenharmony_ci goto out; 336062306a36Sopenharmony_ci } 336162306a36Sopenharmony_ci } 336262306a36Sopenharmony_ci 336362306a36Sopenharmony_ci for (i = 0; i < dtcount; i++) { 336462306a36Sopenharmony_ci int ilen; 336562306a36Sopenharmony_ci unsigned int dlen = COMP_BUF_SIZE; 336662306a36Sopenharmony_ci 336762306a36Sopenharmony_ci memset(decomp_output, 0, COMP_BUF_SIZE); 336862306a36Sopenharmony_ci 336962306a36Sopenharmony_ci ilen = dtemplate[i].inlen; 337062306a36Sopenharmony_ci ret = crypto_comp_decompress(tfm, dtemplate[i].input, 337162306a36Sopenharmony_ci ilen, decomp_output, &dlen); 337262306a36Sopenharmony_ci if (ret) { 337362306a36Sopenharmony_ci printk(KERN_ERR "alg: comp: decompression failed " 337462306a36Sopenharmony_ci "on test %d for %s: ret=%d\n", i + 1, algo, 337562306a36Sopenharmony_ci -ret); 337662306a36Sopenharmony_ci goto out; 337762306a36Sopenharmony_ci } 337862306a36Sopenharmony_ci 337962306a36Sopenharmony_ci if (dlen != dtemplate[i].outlen) { 338062306a36Sopenharmony_ci printk(KERN_ERR "alg: comp: Decompression test %d " 338162306a36Sopenharmony_ci "failed for %s: output len = %d\n", i + 1, algo, 338262306a36Sopenharmony_ci dlen); 338362306a36Sopenharmony_ci ret = -EINVAL; 338462306a36Sopenharmony_ci goto out; 338562306a36Sopenharmony_ci } 338662306a36Sopenharmony_ci 338762306a36Sopenharmony_ci if (memcmp(decomp_output, dtemplate[i].output, dlen)) { 338862306a36Sopenharmony_ci printk(KERN_ERR "alg: comp: Decompression test %d " 338962306a36Sopenharmony_ci "failed for %s\n", i + 1, algo); 339062306a36Sopenharmony_ci hexdump(decomp_output, dlen); 339162306a36Sopenharmony_ci ret = -EINVAL; 339262306a36Sopenharmony_ci goto out; 339362306a36Sopenharmony_ci } 339462306a36Sopenharmony_ci } 339562306a36Sopenharmony_ci 339662306a36Sopenharmony_ci ret = 0; 339762306a36Sopenharmony_ci 339862306a36Sopenharmony_ciout: 339962306a36Sopenharmony_ci kfree(decomp_output); 340062306a36Sopenharmony_ci kfree(output); 340162306a36Sopenharmony_ci return ret; 340262306a36Sopenharmony_ci} 340362306a36Sopenharmony_ci 340462306a36Sopenharmony_cistatic int test_acomp(struct crypto_acomp *tfm, 340562306a36Sopenharmony_ci const struct comp_testvec *ctemplate, 340662306a36Sopenharmony_ci const struct comp_testvec *dtemplate, 340762306a36Sopenharmony_ci int ctcount, int dtcount) 340862306a36Sopenharmony_ci{ 340962306a36Sopenharmony_ci const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); 341062306a36Sopenharmony_ci unsigned int i; 341162306a36Sopenharmony_ci char *output, *decomp_out; 341262306a36Sopenharmony_ci int ret; 341362306a36Sopenharmony_ci struct scatterlist src, dst; 341462306a36Sopenharmony_ci struct acomp_req *req; 341562306a36Sopenharmony_ci struct crypto_wait wait; 341662306a36Sopenharmony_ci 341762306a36Sopenharmony_ci output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 341862306a36Sopenharmony_ci if (!output) 341962306a36Sopenharmony_ci return -ENOMEM; 342062306a36Sopenharmony_ci 342162306a36Sopenharmony_ci decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 342262306a36Sopenharmony_ci if (!decomp_out) { 342362306a36Sopenharmony_ci kfree(output); 342462306a36Sopenharmony_ci return -ENOMEM; 342562306a36Sopenharmony_ci } 342662306a36Sopenharmony_ci 342762306a36Sopenharmony_ci for (i = 0; i < ctcount; i++) { 342862306a36Sopenharmony_ci unsigned int dlen = COMP_BUF_SIZE; 342962306a36Sopenharmony_ci int ilen = ctemplate[i].inlen; 343062306a36Sopenharmony_ci void *input_vec; 343162306a36Sopenharmony_ci 343262306a36Sopenharmony_ci input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); 343362306a36Sopenharmony_ci if (!input_vec) { 343462306a36Sopenharmony_ci ret = -ENOMEM; 343562306a36Sopenharmony_ci goto out; 343662306a36Sopenharmony_ci } 343762306a36Sopenharmony_ci 343862306a36Sopenharmony_ci memset(output, 0, dlen); 343962306a36Sopenharmony_ci crypto_init_wait(&wait); 344062306a36Sopenharmony_ci sg_init_one(&src, input_vec, ilen); 344162306a36Sopenharmony_ci sg_init_one(&dst, output, dlen); 344262306a36Sopenharmony_ci 344362306a36Sopenharmony_ci req = acomp_request_alloc(tfm); 344462306a36Sopenharmony_ci if (!req) { 344562306a36Sopenharmony_ci pr_err("alg: acomp: request alloc failed for %s\n", 344662306a36Sopenharmony_ci algo); 344762306a36Sopenharmony_ci kfree(input_vec); 344862306a36Sopenharmony_ci ret = -ENOMEM; 344962306a36Sopenharmony_ci goto out; 345062306a36Sopenharmony_ci } 345162306a36Sopenharmony_ci 345262306a36Sopenharmony_ci acomp_request_set_params(req, &src, &dst, ilen, dlen); 345362306a36Sopenharmony_ci acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 345462306a36Sopenharmony_ci crypto_req_done, &wait); 345562306a36Sopenharmony_ci 345662306a36Sopenharmony_ci ret = crypto_wait_req(crypto_acomp_compress(req), &wait); 345762306a36Sopenharmony_ci if (ret) { 345862306a36Sopenharmony_ci pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 345962306a36Sopenharmony_ci i + 1, algo, -ret); 346062306a36Sopenharmony_ci kfree(input_vec); 346162306a36Sopenharmony_ci acomp_request_free(req); 346262306a36Sopenharmony_ci goto out; 346362306a36Sopenharmony_ci } 346462306a36Sopenharmony_ci 346562306a36Sopenharmony_ci ilen = req->dlen; 346662306a36Sopenharmony_ci dlen = COMP_BUF_SIZE; 346762306a36Sopenharmony_ci sg_init_one(&src, output, ilen); 346862306a36Sopenharmony_ci sg_init_one(&dst, decomp_out, dlen); 346962306a36Sopenharmony_ci crypto_init_wait(&wait); 347062306a36Sopenharmony_ci acomp_request_set_params(req, &src, &dst, ilen, dlen); 347162306a36Sopenharmony_ci 347262306a36Sopenharmony_ci ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 347362306a36Sopenharmony_ci if (ret) { 347462306a36Sopenharmony_ci pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 347562306a36Sopenharmony_ci i + 1, algo, -ret); 347662306a36Sopenharmony_ci kfree(input_vec); 347762306a36Sopenharmony_ci acomp_request_free(req); 347862306a36Sopenharmony_ci goto out; 347962306a36Sopenharmony_ci } 348062306a36Sopenharmony_ci 348162306a36Sopenharmony_ci if (req->dlen != ctemplate[i].inlen) { 348262306a36Sopenharmony_ci pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", 348362306a36Sopenharmony_ci i + 1, algo, req->dlen); 348462306a36Sopenharmony_ci ret = -EINVAL; 348562306a36Sopenharmony_ci kfree(input_vec); 348662306a36Sopenharmony_ci acomp_request_free(req); 348762306a36Sopenharmony_ci goto out; 348862306a36Sopenharmony_ci } 348962306a36Sopenharmony_ci 349062306a36Sopenharmony_ci if (memcmp(input_vec, decomp_out, req->dlen)) { 349162306a36Sopenharmony_ci pr_err("alg: acomp: Compression test %d failed for %s\n", 349262306a36Sopenharmony_ci i + 1, algo); 349362306a36Sopenharmony_ci hexdump(output, req->dlen); 349462306a36Sopenharmony_ci ret = -EINVAL; 349562306a36Sopenharmony_ci kfree(input_vec); 349662306a36Sopenharmony_ci acomp_request_free(req); 349762306a36Sopenharmony_ci goto out; 349862306a36Sopenharmony_ci } 349962306a36Sopenharmony_ci 350062306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 350162306a36Sopenharmony_ci crypto_init_wait(&wait); 350262306a36Sopenharmony_ci sg_init_one(&src, input_vec, ilen); 350362306a36Sopenharmony_ci acomp_request_set_params(req, &src, NULL, ilen, 0); 350462306a36Sopenharmony_ci 350562306a36Sopenharmony_ci ret = crypto_wait_req(crypto_acomp_compress(req), &wait); 350662306a36Sopenharmony_ci if (ret) { 350762306a36Sopenharmony_ci pr_err("alg: acomp: compression failed on NULL dst buffer test %d for %s: ret=%d\n", 350862306a36Sopenharmony_ci i + 1, algo, -ret); 350962306a36Sopenharmony_ci kfree(input_vec); 351062306a36Sopenharmony_ci acomp_request_free(req); 351162306a36Sopenharmony_ci goto out; 351262306a36Sopenharmony_ci } 351362306a36Sopenharmony_ci#endif 351462306a36Sopenharmony_ci 351562306a36Sopenharmony_ci kfree(input_vec); 351662306a36Sopenharmony_ci acomp_request_free(req); 351762306a36Sopenharmony_ci } 351862306a36Sopenharmony_ci 351962306a36Sopenharmony_ci for (i = 0; i < dtcount; i++) { 352062306a36Sopenharmony_ci unsigned int dlen = COMP_BUF_SIZE; 352162306a36Sopenharmony_ci int ilen = dtemplate[i].inlen; 352262306a36Sopenharmony_ci void *input_vec; 352362306a36Sopenharmony_ci 352462306a36Sopenharmony_ci input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL); 352562306a36Sopenharmony_ci if (!input_vec) { 352662306a36Sopenharmony_ci ret = -ENOMEM; 352762306a36Sopenharmony_ci goto out; 352862306a36Sopenharmony_ci } 352962306a36Sopenharmony_ci 353062306a36Sopenharmony_ci memset(output, 0, dlen); 353162306a36Sopenharmony_ci crypto_init_wait(&wait); 353262306a36Sopenharmony_ci sg_init_one(&src, input_vec, ilen); 353362306a36Sopenharmony_ci sg_init_one(&dst, output, dlen); 353462306a36Sopenharmony_ci 353562306a36Sopenharmony_ci req = acomp_request_alloc(tfm); 353662306a36Sopenharmony_ci if (!req) { 353762306a36Sopenharmony_ci pr_err("alg: acomp: request alloc failed for %s\n", 353862306a36Sopenharmony_ci algo); 353962306a36Sopenharmony_ci kfree(input_vec); 354062306a36Sopenharmony_ci ret = -ENOMEM; 354162306a36Sopenharmony_ci goto out; 354262306a36Sopenharmony_ci } 354362306a36Sopenharmony_ci 354462306a36Sopenharmony_ci acomp_request_set_params(req, &src, &dst, ilen, dlen); 354562306a36Sopenharmony_ci acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 354662306a36Sopenharmony_ci crypto_req_done, &wait); 354762306a36Sopenharmony_ci 354862306a36Sopenharmony_ci ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 354962306a36Sopenharmony_ci if (ret) { 355062306a36Sopenharmony_ci pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n", 355162306a36Sopenharmony_ci i + 1, algo, -ret); 355262306a36Sopenharmony_ci kfree(input_vec); 355362306a36Sopenharmony_ci acomp_request_free(req); 355462306a36Sopenharmony_ci goto out; 355562306a36Sopenharmony_ci } 355662306a36Sopenharmony_ci 355762306a36Sopenharmony_ci if (req->dlen != dtemplate[i].outlen) { 355862306a36Sopenharmony_ci pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n", 355962306a36Sopenharmony_ci i + 1, algo, req->dlen); 356062306a36Sopenharmony_ci ret = -EINVAL; 356162306a36Sopenharmony_ci kfree(input_vec); 356262306a36Sopenharmony_ci acomp_request_free(req); 356362306a36Sopenharmony_ci goto out; 356462306a36Sopenharmony_ci } 356562306a36Sopenharmony_ci 356662306a36Sopenharmony_ci if (memcmp(output, dtemplate[i].output, req->dlen)) { 356762306a36Sopenharmony_ci pr_err("alg: acomp: Decompression test %d failed for %s\n", 356862306a36Sopenharmony_ci i + 1, algo); 356962306a36Sopenharmony_ci hexdump(output, req->dlen); 357062306a36Sopenharmony_ci ret = -EINVAL; 357162306a36Sopenharmony_ci kfree(input_vec); 357262306a36Sopenharmony_ci acomp_request_free(req); 357362306a36Sopenharmony_ci goto out; 357462306a36Sopenharmony_ci } 357562306a36Sopenharmony_ci 357662306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 357762306a36Sopenharmony_ci crypto_init_wait(&wait); 357862306a36Sopenharmony_ci acomp_request_set_params(req, &src, NULL, ilen, 0); 357962306a36Sopenharmony_ci 358062306a36Sopenharmony_ci ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 358162306a36Sopenharmony_ci if (ret) { 358262306a36Sopenharmony_ci pr_err("alg: acomp: decompression failed on NULL dst buffer test %d for %s: ret=%d\n", 358362306a36Sopenharmony_ci i + 1, algo, -ret); 358462306a36Sopenharmony_ci kfree(input_vec); 358562306a36Sopenharmony_ci acomp_request_free(req); 358662306a36Sopenharmony_ci goto out; 358762306a36Sopenharmony_ci } 358862306a36Sopenharmony_ci#endif 358962306a36Sopenharmony_ci 359062306a36Sopenharmony_ci kfree(input_vec); 359162306a36Sopenharmony_ci acomp_request_free(req); 359262306a36Sopenharmony_ci } 359362306a36Sopenharmony_ci 359462306a36Sopenharmony_ci ret = 0; 359562306a36Sopenharmony_ci 359662306a36Sopenharmony_ciout: 359762306a36Sopenharmony_ci kfree(decomp_out); 359862306a36Sopenharmony_ci kfree(output); 359962306a36Sopenharmony_ci return ret; 360062306a36Sopenharmony_ci} 360162306a36Sopenharmony_ci 360262306a36Sopenharmony_cistatic int test_cprng(struct crypto_rng *tfm, 360362306a36Sopenharmony_ci const struct cprng_testvec *template, 360462306a36Sopenharmony_ci unsigned int tcount) 360562306a36Sopenharmony_ci{ 360662306a36Sopenharmony_ci const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); 360762306a36Sopenharmony_ci int err = 0, i, j, seedsize; 360862306a36Sopenharmony_ci u8 *seed; 360962306a36Sopenharmony_ci char result[32]; 361062306a36Sopenharmony_ci 361162306a36Sopenharmony_ci seedsize = crypto_rng_seedsize(tfm); 361262306a36Sopenharmony_ci 361362306a36Sopenharmony_ci seed = kmalloc(seedsize, GFP_KERNEL); 361462306a36Sopenharmony_ci if (!seed) { 361562306a36Sopenharmony_ci printk(KERN_ERR "alg: cprng: Failed to allocate seed space " 361662306a36Sopenharmony_ci "for %s\n", algo); 361762306a36Sopenharmony_ci return -ENOMEM; 361862306a36Sopenharmony_ci } 361962306a36Sopenharmony_ci 362062306a36Sopenharmony_ci for (i = 0; i < tcount; i++) { 362162306a36Sopenharmony_ci memset(result, 0, 32); 362262306a36Sopenharmony_ci 362362306a36Sopenharmony_ci memcpy(seed, template[i].v, template[i].vlen); 362462306a36Sopenharmony_ci memcpy(seed + template[i].vlen, template[i].key, 362562306a36Sopenharmony_ci template[i].klen); 362662306a36Sopenharmony_ci memcpy(seed + template[i].vlen + template[i].klen, 362762306a36Sopenharmony_ci template[i].dt, template[i].dtlen); 362862306a36Sopenharmony_ci 362962306a36Sopenharmony_ci err = crypto_rng_reset(tfm, seed, seedsize); 363062306a36Sopenharmony_ci if (err) { 363162306a36Sopenharmony_ci printk(KERN_ERR "alg: cprng: Failed to reset rng " 363262306a36Sopenharmony_ci "for %s\n", algo); 363362306a36Sopenharmony_ci goto out; 363462306a36Sopenharmony_ci } 363562306a36Sopenharmony_ci 363662306a36Sopenharmony_ci for (j = 0; j < template[i].loops; j++) { 363762306a36Sopenharmony_ci err = crypto_rng_get_bytes(tfm, result, 363862306a36Sopenharmony_ci template[i].rlen); 363962306a36Sopenharmony_ci if (err < 0) { 364062306a36Sopenharmony_ci printk(KERN_ERR "alg: cprng: Failed to obtain " 364162306a36Sopenharmony_ci "the correct amount of random data for " 364262306a36Sopenharmony_ci "%s (requested %d)\n", algo, 364362306a36Sopenharmony_ci template[i].rlen); 364462306a36Sopenharmony_ci goto out; 364562306a36Sopenharmony_ci } 364662306a36Sopenharmony_ci } 364762306a36Sopenharmony_ci 364862306a36Sopenharmony_ci err = memcmp(result, template[i].result, 364962306a36Sopenharmony_ci template[i].rlen); 365062306a36Sopenharmony_ci if (err) { 365162306a36Sopenharmony_ci printk(KERN_ERR "alg: cprng: Test %d failed for %s\n", 365262306a36Sopenharmony_ci i, algo); 365362306a36Sopenharmony_ci hexdump(result, template[i].rlen); 365462306a36Sopenharmony_ci err = -EINVAL; 365562306a36Sopenharmony_ci goto out; 365662306a36Sopenharmony_ci } 365762306a36Sopenharmony_ci } 365862306a36Sopenharmony_ci 365962306a36Sopenharmony_ciout: 366062306a36Sopenharmony_ci kfree(seed); 366162306a36Sopenharmony_ci return err; 366262306a36Sopenharmony_ci} 366362306a36Sopenharmony_ci 366462306a36Sopenharmony_cistatic int alg_test_cipher(const struct alg_test_desc *desc, 366562306a36Sopenharmony_ci const char *driver, u32 type, u32 mask) 366662306a36Sopenharmony_ci{ 366762306a36Sopenharmony_ci const struct cipher_test_suite *suite = &desc->suite.cipher; 366862306a36Sopenharmony_ci struct crypto_cipher *tfm; 366962306a36Sopenharmony_ci int err; 367062306a36Sopenharmony_ci 367162306a36Sopenharmony_ci tfm = crypto_alloc_cipher(driver, type, mask); 367262306a36Sopenharmony_ci if (IS_ERR(tfm)) { 367362306a36Sopenharmony_ci printk(KERN_ERR "alg: cipher: Failed to load transform for " 367462306a36Sopenharmony_ci "%s: %ld\n", driver, PTR_ERR(tfm)); 367562306a36Sopenharmony_ci return PTR_ERR(tfm); 367662306a36Sopenharmony_ci } 367762306a36Sopenharmony_ci 367862306a36Sopenharmony_ci err = test_cipher(tfm, ENCRYPT, suite->vecs, suite->count); 367962306a36Sopenharmony_ci if (!err) 368062306a36Sopenharmony_ci err = test_cipher(tfm, DECRYPT, suite->vecs, suite->count); 368162306a36Sopenharmony_ci 368262306a36Sopenharmony_ci crypto_free_cipher(tfm); 368362306a36Sopenharmony_ci return err; 368462306a36Sopenharmony_ci} 368562306a36Sopenharmony_ci 368662306a36Sopenharmony_cistatic int alg_test_comp(const struct alg_test_desc *desc, const char *driver, 368762306a36Sopenharmony_ci u32 type, u32 mask) 368862306a36Sopenharmony_ci{ 368962306a36Sopenharmony_ci struct crypto_comp *comp; 369062306a36Sopenharmony_ci struct crypto_acomp *acomp; 369162306a36Sopenharmony_ci int err; 369262306a36Sopenharmony_ci u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK; 369362306a36Sopenharmony_ci 369462306a36Sopenharmony_ci if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) { 369562306a36Sopenharmony_ci acomp = crypto_alloc_acomp(driver, type, mask); 369662306a36Sopenharmony_ci if (IS_ERR(acomp)) { 369762306a36Sopenharmony_ci pr_err("alg: acomp: Failed to load transform for %s: %ld\n", 369862306a36Sopenharmony_ci driver, PTR_ERR(acomp)); 369962306a36Sopenharmony_ci return PTR_ERR(acomp); 370062306a36Sopenharmony_ci } 370162306a36Sopenharmony_ci err = test_acomp(acomp, desc->suite.comp.comp.vecs, 370262306a36Sopenharmony_ci desc->suite.comp.decomp.vecs, 370362306a36Sopenharmony_ci desc->suite.comp.comp.count, 370462306a36Sopenharmony_ci desc->suite.comp.decomp.count); 370562306a36Sopenharmony_ci crypto_free_acomp(acomp); 370662306a36Sopenharmony_ci } else { 370762306a36Sopenharmony_ci comp = crypto_alloc_comp(driver, type, mask); 370862306a36Sopenharmony_ci if (IS_ERR(comp)) { 370962306a36Sopenharmony_ci pr_err("alg: comp: Failed to load transform for %s: %ld\n", 371062306a36Sopenharmony_ci driver, PTR_ERR(comp)); 371162306a36Sopenharmony_ci return PTR_ERR(comp); 371262306a36Sopenharmony_ci } 371362306a36Sopenharmony_ci 371462306a36Sopenharmony_ci err = test_comp(comp, desc->suite.comp.comp.vecs, 371562306a36Sopenharmony_ci desc->suite.comp.decomp.vecs, 371662306a36Sopenharmony_ci desc->suite.comp.comp.count, 371762306a36Sopenharmony_ci desc->suite.comp.decomp.count); 371862306a36Sopenharmony_ci 371962306a36Sopenharmony_ci crypto_free_comp(comp); 372062306a36Sopenharmony_ci } 372162306a36Sopenharmony_ci return err; 372262306a36Sopenharmony_ci} 372362306a36Sopenharmony_ci 372462306a36Sopenharmony_cistatic int alg_test_crc32c(const struct alg_test_desc *desc, 372562306a36Sopenharmony_ci const char *driver, u32 type, u32 mask) 372662306a36Sopenharmony_ci{ 372762306a36Sopenharmony_ci struct crypto_shash *tfm; 372862306a36Sopenharmony_ci __le32 val; 372962306a36Sopenharmony_ci int err; 373062306a36Sopenharmony_ci 373162306a36Sopenharmony_ci err = alg_test_hash(desc, driver, type, mask); 373262306a36Sopenharmony_ci if (err) 373362306a36Sopenharmony_ci return err; 373462306a36Sopenharmony_ci 373562306a36Sopenharmony_ci tfm = crypto_alloc_shash(driver, type, mask); 373662306a36Sopenharmony_ci if (IS_ERR(tfm)) { 373762306a36Sopenharmony_ci if (PTR_ERR(tfm) == -ENOENT) { 373862306a36Sopenharmony_ci /* 373962306a36Sopenharmony_ci * This crc32c implementation is only available through 374062306a36Sopenharmony_ci * ahash API, not the shash API, so the remaining part 374162306a36Sopenharmony_ci * of the test is not applicable to it. 374262306a36Sopenharmony_ci */ 374362306a36Sopenharmony_ci return 0; 374462306a36Sopenharmony_ci } 374562306a36Sopenharmony_ci printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: " 374662306a36Sopenharmony_ci "%ld\n", driver, PTR_ERR(tfm)); 374762306a36Sopenharmony_ci return PTR_ERR(tfm); 374862306a36Sopenharmony_ci } 374962306a36Sopenharmony_ci driver = crypto_shash_driver_name(tfm); 375062306a36Sopenharmony_ci 375162306a36Sopenharmony_ci do { 375262306a36Sopenharmony_ci SHASH_DESC_ON_STACK(shash, tfm); 375362306a36Sopenharmony_ci u32 *ctx = (u32 *)shash_desc_ctx(shash); 375462306a36Sopenharmony_ci 375562306a36Sopenharmony_ci shash->tfm = tfm; 375662306a36Sopenharmony_ci 375762306a36Sopenharmony_ci *ctx = 420553207; 375862306a36Sopenharmony_ci err = crypto_shash_final(shash, (u8 *)&val); 375962306a36Sopenharmony_ci if (err) { 376062306a36Sopenharmony_ci printk(KERN_ERR "alg: crc32c: Operation failed for " 376162306a36Sopenharmony_ci "%s: %d\n", driver, err); 376262306a36Sopenharmony_ci break; 376362306a36Sopenharmony_ci } 376462306a36Sopenharmony_ci 376562306a36Sopenharmony_ci if (val != cpu_to_le32(~420553207)) { 376662306a36Sopenharmony_ci pr_err("alg: crc32c: Test failed for %s: %u\n", 376762306a36Sopenharmony_ci driver, le32_to_cpu(val)); 376862306a36Sopenharmony_ci err = -EINVAL; 376962306a36Sopenharmony_ci } 377062306a36Sopenharmony_ci } while (0); 377162306a36Sopenharmony_ci 377262306a36Sopenharmony_ci crypto_free_shash(tfm); 377362306a36Sopenharmony_ci 377462306a36Sopenharmony_ci return err; 377562306a36Sopenharmony_ci} 377662306a36Sopenharmony_ci 377762306a36Sopenharmony_cistatic int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, 377862306a36Sopenharmony_ci u32 type, u32 mask) 377962306a36Sopenharmony_ci{ 378062306a36Sopenharmony_ci struct crypto_rng *rng; 378162306a36Sopenharmony_ci int err; 378262306a36Sopenharmony_ci 378362306a36Sopenharmony_ci rng = crypto_alloc_rng(driver, type, mask); 378462306a36Sopenharmony_ci if (IS_ERR(rng)) { 378562306a36Sopenharmony_ci printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " 378662306a36Sopenharmony_ci "%ld\n", driver, PTR_ERR(rng)); 378762306a36Sopenharmony_ci return PTR_ERR(rng); 378862306a36Sopenharmony_ci } 378962306a36Sopenharmony_ci 379062306a36Sopenharmony_ci err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count); 379162306a36Sopenharmony_ci 379262306a36Sopenharmony_ci crypto_free_rng(rng); 379362306a36Sopenharmony_ci 379462306a36Sopenharmony_ci return err; 379562306a36Sopenharmony_ci} 379662306a36Sopenharmony_ci 379762306a36Sopenharmony_ci 379862306a36Sopenharmony_cistatic int drbg_cavs_test(const struct drbg_testvec *test, int pr, 379962306a36Sopenharmony_ci const char *driver, u32 type, u32 mask) 380062306a36Sopenharmony_ci{ 380162306a36Sopenharmony_ci int ret = -EAGAIN; 380262306a36Sopenharmony_ci struct crypto_rng *drng; 380362306a36Sopenharmony_ci struct drbg_test_data test_data; 380462306a36Sopenharmony_ci struct drbg_string addtl, pers, testentropy; 380562306a36Sopenharmony_ci unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL); 380662306a36Sopenharmony_ci 380762306a36Sopenharmony_ci if (!buf) 380862306a36Sopenharmony_ci return -ENOMEM; 380962306a36Sopenharmony_ci 381062306a36Sopenharmony_ci drng = crypto_alloc_rng(driver, type, mask); 381162306a36Sopenharmony_ci if (IS_ERR(drng)) { 381262306a36Sopenharmony_ci printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " 381362306a36Sopenharmony_ci "%s\n", driver); 381462306a36Sopenharmony_ci kfree_sensitive(buf); 381562306a36Sopenharmony_ci return -ENOMEM; 381662306a36Sopenharmony_ci } 381762306a36Sopenharmony_ci 381862306a36Sopenharmony_ci test_data.testentropy = &testentropy; 381962306a36Sopenharmony_ci drbg_string_fill(&testentropy, test->entropy, test->entropylen); 382062306a36Sopenharmony_ci drbg_string_fill(&pers, test->pers, test->perslen); 382162306a36Sopenharmony_ci ret = crypto_drbg_reset_test(drng, &pers, &test_data); 382262306a36Sopenharmony_ci if (ret) { 382362306a36Sopenharmony_ci printk(KERN_ERR "alg: drbg: Failed to reset rng\n"); 382462306a36Sopenharmony_ci goto outbuf; 382562306a36Sopenharmony_ci } 382662306a36Sopenharmony_ci 382762306a36Sopenharmony_ci drbg_string_fill(&addtl, test->addtla, test->addtllen); 382862306a36Sopenharmony_ci if (pr) { 382962306a36Sopenharmony_ci drbg_string_fill(&testentropy, test->entpra, test->entprlen); 383062306a36Sopenharmony_ci ret = crypto_drbg_get_bytes_addtl_test(drng, 383162306a36Sopenharmony_ci buf, test->expectedlen, &addtl, &test_data); 383262306a36Sopenharmony_ci } else { 383362306a36Sopenharmony_ci ret = crypto_drbg_get_bytes_addtl(drng, 383462306a36Sopenharmony_ci buf, test->expectedlen, &addtl); 383562306a36Sopenharmony_ci } 383662306a36Sopenharmony_ci if (ret < 0) { 383762306a36Sopenharmony_ci printk(KERN_ERR "alg: drbg: could not obtain random data for " 383862306a36Sopenharmony_ci "driver %s\n", driver); 383962306a36Sopenharmony_ci goto outbuf; 384062306a36Sopenharmony_ci } 384162306a36Sopenharmony_ci 384262306a36Sopenharmony_ci drbg_string_fill(&addtl, test->addtlb, test->addtllen); 384362306a36Sopenharmony_ci if (pr) { 384462306a36Sopenharmony_ci drbg_string_fill(&testentropy, test->entprb, test->entprlen); 384562306a36Sopenharmony_ci ret = crypto_drbg_get_bytes_addtl_test(drng, 384662306a36Sopenharmony_ci buf, test->expectedlen, &addtl, &test_data); 384762306a36Sopenharmony_ci } else { 384862306a36Sopenharmony_ci ret = crypto_drbg_get_bytes_addtl(drng, 384962306a36Sopenharmony_ci buf, test->expectedlen, &addtl); 385062306a36Sopenharmony_ci } 385162306a36Sopenharmony_ci if (ret < 0) { 385262306a36Sopenharmony_ci printk(KERN_ERR "alg: drbg: could not obtain random data for " 385362306a36Sopenharmony_ci "driver %s\n", driver); 385462306a36Sopenharmony_ci goto outbuf; 385562306a36Sopenharmony_ci } 385662306a36Sopenharmony_ci 385762306a36Sopenharmony_ci ret = memcmp(test->expected, buf, test->expectedlen); 385862306a36Sopenharmony_ci 385962306a36Sopenharmony_cioutbuf: 386062306a36Sopenharmony_ci crypto_free_rng(drng); 386162306a36Sopenharmony_ci kfree_sensitive(buf); 386262306a36Sopenharmony_ci return ret; 386362306a36Sopenharmony_ci} 386462306a36Sopenharmony_ci 386562306a36Sopenharmony_ci 386662306a36Sopenharmony_cistatic int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, 386762306a36Sopenharmony_ci u32 type, u32 mask) 386862306a36Sopenharmony_ci{ 386962306a36Sopenharmony_ci int err = 0; 387062306a36Sopenharmony_ci int pr = 0; 387162306a36Sopenharmony_ci int i = 0; 387262306a36Sopenharmony_ci const struct drbg_testvec *template = desc->suite.drbg.vecs; 387362306a36Sopenharmony_ci unsigned int tcount = desc->suite.drbg.count; 387462306a36Sopenharmony_ci 387562306a36Sopenharmony_ci if (0 == memcmp(driver, "drbg_pr_", 8)) 387662306a36Sopenharmony_ci pr = 1; 387762306a36Sopenharmony_ci 387862306a36Sopenharmony_ci for (i = 0; i < tcount; i++) { 387962306a36Sopenharmony_ci err = drbg_cavs_test(&template[i], pr, driver, type, mask); 388062306a36Sopenharmony_ci if (err) { 388162306a36Sopenharmony_ci printk(KERN_ERR "alg: drbg: Test %d failed for %s\n", 388262306a36Sopenharmony_ci i, driver); 388362306a36Sopenharmony_ci err = -EINVAL; 388462306a36Sopenharmony_ci break; 388562306a36Sopenharmony_ci } 388662306a36Sopenharmony_ci } 388762306a36Sopenharmony_ci return err; 388862306a36Sopenharmony_ci 388962306a36Sopenharmony_ci} 389062306a36Sopenharmony_ci 389162306a36Sopenharmony_cistatic int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, 389262306a36Sopenharmony_ci const char *alg) 389362306a36Sopenharmony_ci{ 389462306a36Sopenharmony_ci struct kpp_request *req; 389562306a36Sopenharmony_ci void *input_buf = NULL; 389662306a36Sopenharmony_ci void *output_buf = NULL; 389762306a36Sopenharmony_ci void *a_public = NULL; 389862306a36Sopenharmony_ci void *a_ss = NULL; 389962306a36Sopenharmony_ci void *shared_secret = NULL; 390062306a36Sopenharmony_ci struct crypto_wait wait; 390162306a36Sopenharmony_ci unsigned int out_len_max; 390262306a36Sopenharmony_ci int err = -ENOMEM; 390362306a36Sopenharmony_ci struct scatterlist src, dst; 390462306a36Sopenharmony_ci 390562306a36Sopenharmony_ci req = kpp_request_alloc(tfm, GFP_KERNEL); 390662306a36Sopenharmony_ci if (!req) 390762306a36Sopenharmony_ci return err; 390862306a36Sopenharmony_ci 390962306a36Sopenharmony_ci crypto_init_wait(&wait); 391062306a36Sopenharmony_ci 391162306a36Sopenharmony_ci err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size); 391262306a36Sopenharmony_ci if (err < 0) 391362306a36Sopenharmony_ci goto free_req; 391462306a36Sopenharmony_ci 391562306a36Sopenharmony_ci out_len_max = crypto_kpp_maxsize(tfm); 391662306a36Sopenharmony_ci output_buf = kzalloc(out_len_max, GFP_KERNEL); 391762306a36Sopenharmony_ci if (!output_buf) { 391862306a36Sopenharmony_ci err = -ENOMEM; 391962306a36Sopenharmony_ci goto free_req; 392062306a36Sopenharmony_ci } 392162306a36Sopenharmony_ci 392262306a36Sopenharmony_ci /* Use appropriate parameter as base */ 392362306a36Sopenharmony_ci kpp_request_set_input(req, NULL, 0); 392462306a36Sopenharmony_ci sg_init_one(&dst, output_buf, out_len_max); 392562306a36Sopenharmony_ci kpp_request_set_output(req, &dst, out_len_max); 392662306a36Sopenharmony_ci kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 392762306a36Sopenharmony_ci crypto_req_done, &wait); 392862306a36Sopenharmony_ci 392962306a36Sopenharmony_ci /* Compute party A's public key */ 393062306a36Sopenharmony_ci err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait); 393162306a36Sopenharmony_ci if (err) { 393262306a36Sopenharmony_ci pr_err("alg: %s: Party A: generate public key test failed. err %d\n", 393362306a36Sopenharmony_ci alg, err); 393462306a36Sopenharmony_ci goto free_output; 393562306a36Sopenharmony_ci } 393662306a36Sopenharmony_ci 393762306a36Sopenharmony_ci if (vec->genkey) { 393862306a36Sopenharmony_ci /* Save party A's public key */ 393962306a36Sopenharmony_ci a_public = kmemdup(sg_virt(req->dst), out_len_max, GFP_KERNEL); 394062306a36Sopenharmony_ci if (!a_public) { 394162306a36Sopenharmony_ci err = -ENOMEM; 394262306a36Sopenharmony_ci goto free_output; 394362306a36Sopenharmony_ci } 394462306a36Sopenharmony_ci } else { 394562306a36Sopenharmony_ci /* Verify calculated public key */ 394662306a36Sopenharmony_ci if (memcmp(vec->expected_a_public, sg_virt(req->dst), 394762306a36Sopenharmony_ci vec->expected_a_public_size)) { 394862306a36Sopenharmony_ci pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n", 394962306a36Sopenharmony_ci alg); 395062306a36Sopenharmony_ci err = -EINVAL; 395162306a36Sopenharmony_ci goto free_output; 395262306a36Sopenharmony_ci } 395362306a36Sopenharmony_ci } 395462306a36Sopenharmony_ci 395562306a36Sopenharmony_ci /* Calculate shared secret key by using counter part (b) public key. */ 395662306a36Sopenharmony_ci input_buf = kmemdup(vec->b_public, vec->b_public_size, GFP_KERNEL); 395762306a36Sopenharmony_ci if (!input_buf) { 395862306a36Sopenharmony_ci err = -ENOMEM; 395962306a36Sopenharmony_ci goto free_output; 396062306a36Sopenharmony_ci } 396162306a36Sopenharmony_ci 396262306a36Sopenharmony_ci sg_init_one(&src, input_buf, vec->b_public_size); 396362306a36Sopenharmony_ci sg_init_one(&dst, output_buf, out_len_max); 396462306a36Sopenharmony_ci kpp_request_set_input(req, &src, vec->b_public_size); 396562306a36Sopenharmony_ci kpp_request_set_output(req, &dst, out_len_max); 396662306a36Sopenharmony_ci kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 396762306a36Sopenharmony_ci crypto_req_done, &wait); 396862306a36Sopenharmony_ci err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait); 396962306a36Sopenharmony_ci if (err) { 397062306a36Sopenharmony_ci pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n", 397162306a36Sopenharmony_ci alg, err); 397262306a36Sopenharmony_ci goto free_all; 397362306a36Sopenharmony_ci } 397462306a36Sopenharmony_ci 397562306a36Sopenharmony_ci if (vec->genkey) { 397662306a36Sopenharmony_ci /* Save the shared secret obtained by party A */ 397762306a36Sopenharmony_ci a_ss = kmemdup(sg_virt(req->dst), vec->expected_ss_size, GFP_KERNEL); 397862306a36Sopenharmony_ci if (!a_ss) { 397962306a36Sopenharmony_ci err = -ENOMEM; 398062306a36Sopenharmony_ci goto free_all; 398162306a36Sopenharmony_ci } 398262306a36Sopenharmony_ci 398362306a36Sopenharmony_ci /* 398462306a36Sopenharmony_ci * Calculate party B's shared secret by using party A's 398562306a36Sopenharmony_ci * public key. 398662306a36Sopenharmony_ci */ 398762306a36Sopenharmony_ci err = crypto_kpp_set_secret(tfm, vec->b_secret, 398862306a36Sopenharmony_ci vec->b_secret_size); 398962306a36Sopenharmony_ci if (err < 0) 399062306a36Sopenharmony_ci goto free_all; 399162306a36Sopenharmony_ci 399262306a36Sopenharmony_ci sg_init_one(&src, a_public, vec->expected_a_public_size); 399362306a36Sopenharmony_ci sg_init_one(&dst, output_buf, out_len_max); 399462306a36Sopenharmony_ci kpp_request_set_input(req, &src, vec->expected_a_public_size); 399562306a36Sopenharmony_ci kpp_request_set_output(req, &dst, out_len_max); 399662306a36Sopenharmony_ci kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 399762306a36Sopenharmony_ci crypto_req_done, &wait); 399862306a36Sopenharmony_ci err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), 399962306a36Sopenharmony_ci &wait); 400062306a36Sopenharmony_ci if (err) { 400162306a36Sopenharmony_ci pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", 400262306a36Sopenharmony_ci alg, err); 400362306a36Sopenharmony_ci goto free_all; 400462306a36Sopenharmony_ci } 400562306a36Sopenharmony_ci 400662306a36Sopenharmony_ci shared_secret = a_ss; 400762306a36Sopenharmony_ci } else { 400862306a36Sopenharmony_ci shared_secret = (void *)vec->expected_ss; 400962306a36Sopenharmony_ci } 401062306a36Sopenharmony_ci 401162306a36Sopenharmony_ci /* 401262306a36Sopenharmony_ci * verify shared secret from which the user will derive 401362306a36Sopenharmony_ci * secret key by executing whatever hash it has chosen 401462306a36Sopenharmony_ci */ 401562306a36Sopenharmony_ci if (memcmp(shared_secret, sg_virt(req->dst), 401662306a36Sopenharmony_ci vec->expected_ss_size)) { 401762306a36Sopenharmony_ci pr_err("alg: %s: compute shared secret test failed. Invalid output\n", 401862306a36Sopenharmony_ci alg); 401962306a36Sopenharmony_ci err = -EINVAL; 402062306a36Sopenharmony_ci } 402162306a36Sopenharmony_ci 402262306a36Sopenharmony_cifree_all: 402362306a36Sopenharmony_ci kfree(a_ss); 402462306a36Sopenharmony_ci kfree(input_buf); 402562306a36Sopenharmony_cifree_output: 402662306a36Sopenharmony_ci kfree(a_public); 402762306a36Sopenharmony_ci kfree(output_buf); 402862306a36Sopenharmony_cifree_req: 402962306a36Sopenharmony_ci kpp_request_free(req); 403062306a36Sopenharmony_ci return err; 403162306a36Sopenharmony_ci} 403262306a36Sopenharmony_ci 403362306a36Sopenharmony_cistatic int test_kpp(struct crypto_kpp *tfm, const char *alg, 403462306a36Sopenharmony_ci const struct kpp_testvec *vecs, unsigned int tcount) 403562306a36Sopenharmony_ci{ 403662306a36Sopenharmony_ci int ret, i; 403762306a36Sopenharmony_ci 403862306a36Sopenharmony_ci for (i = 0; i < tcount; i++) { 403962306a36Sopenharmony_ci ret = do_test_kpp(tfm, vecs++, alg); 404062306a36Sopenharmony_ci if (ret) { 404162306a36Sopenharmony_ci pr_err("alg: %s: test failed on vector %d, err=%d\n", 404262306a36Sopenharmony_ci alg, i + 1, ret); 404362306a36Sopenharmony_ci return ret; 404462306a36Sopenharmony_ci } 404562306a36Sopenharmony_ci } 404662306a36Sopenharmony_ci return 0; 404762306a36Sopenharmony_ci} 404862306a36Sopenharmony_ci 404962306a36Sopenharmony_cistatic int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, 405062306a36Sopenharmony_ci u32 type, u32 mask) 405162306a36Sopenharmony_ci{ 405262306a36Sopenharmony_ci struct crypto_kpp *tfm; 405362306a36Sopenharmony_ci int err = 0; 405462306a36Sopenharmony_ci 405562306a36Sopenharmony_ci tfm = crypto_alloc_kpp(driver, type, mask); 405662306a36Sopenharmony_ci if (IS_ERR(tfm)) { 405762306a36Sopenharmony_ci pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", 405862306a36Sopenharmony_ci driver, PTR_ERR(tfm)); 405962306a36Sopenharmony_ci return PTR_ERR(tfm); 406062306a36Sopenharmony_ci } 406162306a36Sopenharmony_ci if (desc->suite.kpp.vecs) 406262306a36Sopenharmony_ci err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs, 406362306a36Sopenharmony_ci desc->suite.kpp.count); 406462306a36Sopenharmony_ci 406562306a36Sopenharmony_ci crypto_free_kpp(tfm); 406662306a36Sopenharmony_ci return err; 406762306a36Sopenharmony_ci} 406862306a36Sopenharmony_ci 406962306a36Sopenharmony_cistatic u8 *test_pack_u32(u8 *dst, u32 val) 407062306a36Sopenharmony_ci{ 407162306a36Sopenharmony_ci memcpy(dst, &val, sizeof(val)); 407262306a36Sopenharmony_ci return dst + sizeof(val); 407362306a36Sopenharmony_ci} 407462306a36Sopenharmony_ci 407562306a36Sopenharmony_cistatic int test_akcipher_one(struct crypto_akcipher *tfm, 407662306a36Sopenharmony_ci const struct akcipher_testvec *vecs) 407762306a36Sopenharmony_ci{ 407862306a36Sopenharmony_ci char *xbuf[XBUFSIZE]; 407962306a36Sopenharmony_ci struct akcipher_request *req; 408062306a36Sopenharmony_ci void *outbuf_enc = NULL; 408162306a36Sopenharmony_ci void *outbuf_dec = NULL; 408262306a36Sopenharmony_ci struct crypto_wait wait; 408362306a36Sopenharmony_ci unsigned int out_len_max, out_len = 0; 408462306a36Sopenharmony_ci int err = -ENOMEM; 408562306a36Sopenharmony_ci struct scatterlist src, dst, src_tab[3]; 408662306a36Sopenharmony_ci const char *m, *c; 408762306a36Sopenharmony_ci unsigned int m_size, c_size; 408862306a36Sopenharmony_ci const char *op; 408962306a36Sopenharmony_ci u8 *key, *ptr; 409062306a36Sopenharmony_ci 409162306a36Sopenharmony_ci if (testmgr_alloc_buf(xbuf)) 409262306a36Sopenharmony_ci return err; 409362306a36Sopenharmony_ci 409462306a36Sopenharmony_ci req = akcipher_request_alloc(tfm, GFP_KERNEL); 409562306a36Sopenharmony_ci if (!req) 409662306a36Sopenharmony_ci goto free_xbuf; 409762306a36Sopenharmony_ci 409862306a36Sopenharmony_ci crypto_init_wait(&wait); 409962306a36Sopenharmony_ci 410062306a36Sopenharmony_ci key = kmalloc(vecs->key_len + sizeof(u32) * 2 + vecs->param_len, 410162306a36Sopenharmony_ci GFP_KERNEL); 410262306a36Sopenharmony_ci if (!key) 410362306a36Sopenharmony_ci goto free_req; 410462306a36Sopenharmony_ci memcpy(key, vecs->key, vecs->key_len); 410562306a36Sopenharmony_ci ptr = key + vecs->key_len; 410662306a36Sopenharmony_ci ptr = test_pack_u32(ptr, vecs->algo); 410762306a36Sopenharmony_ci ptr = test_pack_u32(ptr, vecs->param_len); 410862306a36Sopenharmony_ci memcpy(ptr, vecs->params, vecs->param_len); 410962306a36Sopenharmony_ci 411062306a36Sopenharmony_ci if (vecs->public_key_vec) 411162306a36Sopenharmony_ci err = crypto_akcipher_set_pub_key(tfm, key, vecs->key_len); 411262306a36Sopenharmony_ci else 411362306a36Sopenharmony_ci err = crypto_akcipher_set_priv_key(tfm, key, vecs->key_len); 411462306a36Sopenharmony_ci if (err) 411562306a36Sopenharmony_ci goto free_key; 411662306a36Sopenharmony_ci 411762306a36Sopenharmony_ci /* 411862306a36Sopenharmony_ci * First run test which do not require a private key, such as 411962306a36Sopenharmony_ci * encrypt or verify. 412062306a36Sopenharmony_ci */ 412162306a36Sopenharmony_ci err = -ENOMEM; 412262306a36Sopenharmony_ci out_len_max = crypto_akcipher_maxsize(tfm); 412362306a36Sopenharmony_ci outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); 412462306a36Sopenharmony_ci if (!outbuf_enc) 412562306a36Sopenharmony_ci goto free_key; 412662306a36Sopenharmony_ci 412762306a36Sopenharmony_ci if (!vecs->siggen_sigver_test) { 412862306a36Sopenharmony_ci m = vecs->m; 412962306a36Sopenharmony_ci m_size = vecs->m_size; 413062306a36Sopenharmony_ci c = vecs->c; 413162306a36Sopenharmony_ci c_size = vecs->c_size; 413262306a36Sopenharmony_ci op = "encrypt"; 413362306a36Sopenharmony_ci } else { 413462306a36Sopenharmony_ci /* Swap args so we could keep plaintext (digest) 413562306a36Sopenharmony_ci * in vecs->m, and cooked signature in vecs->c. 413662306a36Sopenharmony_ci */ 413762306a36Sopenharmony_ci m = vecs->c; /* signature */ 413862306a36Sopenharmony_ci m_size = vecs->c_size; 413962306a36Sopenharmony_ci c = vecs->m; /* digest */ 414062306a36Sopenharmony_ci c_size = vecs->m_size; 414162306a36Sopenharmony_ci op = "verify"; 414262306a36Sopenharmony_ci } 414362306a36Sopenharmony_ci 414462306a36Sopenharmony_ci err = -E2BIG; 414562306a36Sopenharmony_ci if (WARN_ON(m_size > PAGE_SIZE)) 414662306a36Sopenharmony_ci goto free_all; 414762306a36Sopenharmony_ci memcpy(xbuf[0], m, m_size); 414862306a36Sopenharmony_ci 414962306a36Sopenharmony_ci sg_init_table(src_tab, 3); 415062306a36Sopenharmony_ci sg_set_buf(&src_tab[0], xbuf[0], 8); 415162306a36Sopenharmony_ci sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8); 415262306a36Sopenharmony_ci if (vecs->siggen_sigver_test) { 415362306a36Sopenharmony_ci if (WARN_ON(c_size > PAGE_SIZE)) 415462306a36Sopenharmony_ci goto free_all; 415562306a36Sopenharmony_ci memcpy(xbuf[1], c, c_size); 415662306a36Sopenharmony_ci sg_set_buf(&src_tab[2], xbuf[1], c_size); 415762306a36Sopenharmony_ci akcipher_request_set_crypt(req, src_tab, NULL, m_size, c_size); 415862306a36Sopenharmony_ci } else { 415962306a36Sopenharmony_ci sg_init_one(&dst, outbuf_enc, out_len_max); 416062306a36Sopenharmony_ci akcipher_request_set_crypt(req, src_tab, &dst, m_size, 416162306a36Sopenharmony_ci out_len_max); 416262306a36Sopenharmony_ci } 416362306a36Sopenharmony_ci akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 416462306a36Sopenharmony_ci crypto_req_done, &wait); 416562306a36Sopenharmony_ci 416662306a36Sopenharmony_ci err = crypto_wait_req(vecs->siggen_sigver_test ? 416762306a36Sopenharmony_ci /* Run asymmetric signature verification */ 416862306a36Sopenharmony_ci crypto_akcipher_verify(req) : 416962306a36Sopenharmony_ci /* Run asymmetric encrypt */ 417062306a36Sopenharmony_ci crypto_akcipher_encrypt(req), &wait); 417162306a36Sopenharmony_ci if (err) { 417262306a36Sopenharmony_ci pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 417362306a36Sopenharmony_ci goto free_all; 417462306a36Sopenharmony_ci } 417562306a36Sopenharmony_ci if (!vecs->siggen_sigver_test && c) { 417662306a36Sopenharmony_ci if (req->dst_len != c_size) { 417762306a36Sopenharmony_ci pr_err("alg: akcipher: %s test failed. Invalid output len\n", 417862306a36Sopenharmony_ci op); 417962306a36Sopenharmony_ci err = -EINVAL; 418062306a36Sopenharmony_ci goto free_all; 418162306a36Sopenharmony_ci } 418262306a36Sopenharmony_ci /* verify that encrypted message is equal to expected */ 418362306a36Sopenharmony_ci if (memcmp(c, outbuf_enc, c_size) != 0) { 418462306a36Sopenharmony_ci pr_err("alg: akcipher: %s test failed. Invalid output\n", 418562306a36Sopenharmony_ci op); 418662306a36Sopenharmony_ci hexdump(outbuf_enc, c_size); 418762306a36Sopenharmony_ci err = -EINVAL; 418862306a36Sopenharmony_ci goto free_all; 418962306a36Sopenharmony_ci } 419062306a36Sopenharmony_ci } 419162306a36Sopenharmony_ci 419262306a36Sopenharmony_ci /* 419362306a36Sopenharmony_ci * Don't invoke (decrypt or sign) test which require a private key 419462306a36Sopenharmony_ci * for vectors with only a public key. 419562306a36Sopenharmony_ci */ 419662306a36Sopenharmony_ci if (vecs->public_key_vec) { 419762306a36Sopenharmony_ci err = 0; 419862306a36Sopenharmony_ci goto free_all; 419962306a36Sopenharmony_ci } 420062306a36Sopenharmony_ci outbuf_dec = kzalloc(out_len_max, GFP_KERNEL); 420162306a36Sopenharmony_ci if (!outbuf_dec) { 420262306a36Sopenharmony_ci err = -ENOMEM; 420362306a36Sopenharmony_ci goto free_all; 420462306a36Sopenharmony_ci } 420562306a36Sopenharmony_ci 420662306a36Sopenharmony_ci if (!vecs->siggen_sigver_test && !c) { 420762306a36Sopenharmony_ci c = outbuf_enc; 420862306a36Sopenharmony_ci c_size = req->dst_len; 420962306a36Sopenharmony_ci } 421062306a36Sopenharmony_ci 421162306a36Sopenharmony_ci err = -E2BIG; 421262306a36Sopenharmony_ci op = vecs->siggen_sigver_test ? "sign" : "decrypt"; 421362306a36Sopenharmony_ci if (WARN_ON(c_size > PAGE_SIZE)) 421462306a36Sopenharmony_ci goto free_all; 421562306a36Sopenharmony_ci memcpy(xbuf[0], c, c_size); 421662306a36Sopenharmony_ci 421762306a36Sopenharmony_ci sg_init_one(&src, xbuf[0], c_size); 421862306a36Sopenharmony_ci sg_init_one(&dst, outbuf_dec, out_len_max); 421962306a36Sopenharmony_ci crypto_init_wait(&wait); 422062306a36Sopenharmony_ci akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max); 422162306a36Sopenharmony_ci 422262306a36Sopenharmony_ci err = crypto_wait_req(vecs->siggen_sigver_test ? 422362306a36Sopenharmony_ci /* Run asymmetric signature generation */ 422462306a36Sopenharmony_ci crypto_akcipher_sign(req) : 422562306a36Sopenharmony_ci /* Run asymmetric decrypt */ 422662306a36Sopenharmony_ci crypto_akcipher_decrypt(req), &wait); 422762306a36Sopenharmony_ci if (err) { 422862306a36Sopenharmony_ci pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 422962306a36Sopenharmony_ci goto free_all; 423062306a36Sopenharmony_ci } 423162306a36Sopenharmony_ci out_len = req->dst_len; 423262306a36Sopenharmony_ci if (out_len < m_size) { 423362306a36Sopenharmony_ci pr_err("alg: akcipher: %s test failed. Invalid output len %u\n", 423462306a36Sopenharmony_ci op, out_len); 423562306a36Sopenharmony_ci err = -EINVAL; 423662306a36Sopenharmony_ci goto free_all; 423762306a36Sopenharmony_ci } 423862306a36Sopenharmony_ci /* verify that decrypted message is equal to the original msg */ 423962306a36Sopenharmony_ci if (memchr_inv(outbuf_dec, 0, out_len - m_size) || 424062306a36Sopenharmony_ci memcmp(m, outbuf_dec + out_len - m_size, m_size)) { 424162306a36Sopenharmony_ci pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 424262306a36Sopenharmony_ci hexdump(outbuf_dec, out_len); 424362306a36Sopenharmony_ci err = -EINVAL; 424462306a36Sopenharmony_ci } 424562306a36Sopenharmony_cifree_all: 424662306a36Sopenharmony_ci kfree(outbuf_dec); 424762306a36Sopenharmony_ci kfree(outbuf_enc); 424862306a36Sopenharmony_cifree_key: 424962306a36Sopenharmony_ci kfree(key); 425062306a36Sopenharmony_cifree_req: 425162306a36Sopenharmony_ci akcipher_request_free(req); 425262306a36Sopenharmony_cifree_xbuf: 425362306a36Sopenharmony_ci testmgr_free_buf(xbuf); 425462306a36Sopenharmony_ci return err; 425562306a36Sopenharmony_ci} 425662306a36Sopenharmony_ci 425762306a36Sopenharmony_cistatic int test_akcipher(struct crypto_akcipher *tfm, const char *alg, 425862306a36Sopenharmony_ci const struct akcipher_testvec *vecs, 425962306a36Sopenharmony_ci unsigned int tcount) 426062306a36Sopenharmony_ci{ 426162306a36Sopenharmony_ci const char *algo = 426262306a36Sopenharmony_ci crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm)); 426362306a36Sopenharmony_ci int ret, i; 426462306a36Sopenharmony_ci 426562306a36Sopenharmony_ci for (i = 0; i < tcount; i++) { 426662306a36Sopenharmony_ci ret = test_akcipher_one(tfm, vecs++); 426762306a36Sopenharmony_ci if (!ret) 426862306a36Sopenharmony_ci continue; 426962306a36Sopenharmony_ci 427062306a36Sopenharmony_ci pr_err("alg: akcipher: test %d failed for %s, err=%d\n", 427162306a36Sopenharmony_ci i + 1, algo, ret); 427262306a36Sopenharmony_ci return ret; 427362306a36Sopenharmony_ci } 427462306a36Sopenharmony_ci return 0; 427562306a36Sopenharmony_ci} 427662306a36Sopenharmony_ci 427762306a36Sopenharmony_cistatic int alg_test_akcipher(const struct alg_test_desc *desc, 427862306a36Sopenharmony_ci const char *driver, u32 type, u32 mask) 427962306a36Sopenharmony_ci{ 428062306a36Sopenharmony_ci struct crypto_akcipher *tfm; 428162306a36Sopenharmony_ci int err = 0; 428262306a36Sopenharmony_ci 428362306a36Sopenharmony_ci tfm = crypto_alloc_akcipher(driver, type, mask); 428462306a36Sopenharmony_ci if (IS_ERR(tfm)) { 428562306a36Sopenharmony_ci pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", 428662306a36Sopenharmony_ci driver, PTR_ERR(tfm)); 428762306a36Sopenharmony_ci return PTR_ERR(tfm); 428862306a36Sopenharmony_ci } 428962306a36Sopenharmony_ci if (desc->suite.akcipher.vecs) 429062306a36Sopenharmony_ci err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs, 429162306a36Sopenharmony_ci desc->suite.akcipher.count); 429262306a36Sopenharmony_ci 429362306a36Sopenharmony_ci crypto_free_akcipher(tfm); 429462306a36Sopenharmony_ci return err; 429562306a36Sopenharmony_ci} 429662306a36Sopenharmony_ci 429762306a36Sopenharmony_cistatic int alg_test_null(const struct alg_test_desc *desc, 429862306a36Sopenharmony_ci const char *driver, u32 type, u32 mask) 429962306a36Sopenharmony_ci{ 430062306a36Sopenharmony_ci return 0; 430162306a36Sopenharmony_ci} 430262306a36Sopenharmony_ci 430362306a36Sopenharmony_ci#define ____VECS(tv) .vecs = tv, .count = ARRAY_SIZE(tv) 430462306a36Sopenharmony_ci#define __VECS(tv) { ____VECS(tv) } 430562306a36Sopenharmony_ci 430662306a36Sopenharmony_ci/* Please keep this list sorted by algorithm name. */ 430762306a36Sopenharmony_cistatic const struct alg_test_desc alg_test_descs[] = { 430862306a36Sopenharmony_ci { 430962306a36Sopenharmony_ci .alg = "adiantum(xchacha12,aes)", 431062306a36Sopenharmony_ci .generic_driver = "adiantum(xchacha12-generic,aes-generic,nhpoly1305-generic)", 431162306a36Sopenharmony_ci .test = alg_test_skcipher, 431262306a36Sopenharmony_ci .suite = { 431362306a36Sopenharmony_ci .cipher = __VECS(adiantum_xchacha12_aes_tv_template) 431462306a36Sopenharmony_ci }, 431562306a36Sopenharmony_ci }, { 431662306a36Sopenharmony_ci .alg = "adiantum(xchacha20,aes)", 431762306a36Sopenharmony_ci .generic_driver = "adiantum(xchacha20-generic,aes-generic,nhpoly1305-generic)", 431862306a36Sopenharmony_ci .test = alg_test_skcipher, 431962306a36Sopenharmony_ci .suite = { 432062306a36Sopenharmony_ci .cipher = __VECS(adiantum_xchacha20_aes_tv_template) 432162306a36Sopenharmony_ci }, 432262306a36Sopenharmony_ci }, { 432362306a36Sopenharmony_ci .alg = "aegis128", 432462306a36Sopenharmony_ci .test = alg_test_aead, 432562306a36Sopenharmony_ci .suite = { 432662306a36Sopenharmony_ci .aead = __VECS(aegis128_tv_template) 432762306a36Sopenharmony_ci } 432862306a36Sopenharmony_ci }, { 432962306a36Sopenharmony_ci .alg = "ansi_cprng", 433062306a36Sopenharmony_ci .test = alg_test_cprng, 433162306a36Sopenharmony_ci .suite = { 433262306a36Sopenharmony_ci .cprng = __VECS(ansi_cprng_aes_tv_template) 433362306a36Sopenharmony_ci } 433462306a36Sopenharmony_ci }, { 433562306a36Sopenharmony_ci .alg = "authenc(hmac(md5),ecb(cipher_null))", 433662306a36Sopenharmony_ci .test = alg_test_aead, 433762306a36Sopenharmony_ci .suite = { 433862306a36Sopenharmony_ci .aead = __VECS(hmac_md5_ecb_cipher_null_tv_template) 433962306a36Sopenharmony_ci } 434062306a36Sopenharmony_ci }, { 434162306a36Sopenharmony_ci .alg = "authenc(hmac(sha1),cbc(aes))", 434262306a36Sopenharmony_ci .test = alg_test_aead, 434362306a36Sopenharmony_ci .fips_allowed = 1, 434462306a36Sopenharmony_ci .suite = { 434562306a36Sopenharmony_ci .aead = __VECS(hmac_sha1_aes_cbc_tv_temp) 434662306a36Sopenharmony_ci } 434762306a36Sopenharmony_ci }, { 434862306a36Sopenharmony_ci .alg = "authenc(hmac(sha1),cbc(des))", 434962306a36Sopenharmony_ci .test = alg_test_aead, 435062306a36Sopenharmony_ci .suite = { 435162306a36Sopenharmony_ci .aead = __VECS(hmac_sha1_des_cbc_tv_temp) 435262306a36Sopenharmony_ci } 435362306a36Sopenharmony_ci }, { 435462306a36Sopenharmony_ci .alg = "authenc(hmac(sha1),cbc(des3_ede))", 435562306a36Sopenharmony_ci .test = alg_test_aead, 435662306a36Sopenharmony_ci .suite = { 435762306a36Sopenharmony_ci .aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp) 435862306a36Sopenharmony_ci } 435962306a36Sopenharmony_ci }, { 436062306a36Sopenharmony_ci .alg = "authenc(hmac(sha1),ctr(aes))", 436162306a36Sopenharmony_ci .test = alg_test_null, 436262306a36Sopenharmony_ci .fips_allowed = 1, 436362306a36Sopenharmony_ci }, { 436462306a36Sopenharmony_ci .alg = "authenc(hmac(sha1),ecb(cipher_null))", 436562306a36Sopenharmony_ci .test = alg_test_aead, 436662306a36Sopenharmony_ci .suite = { 436762306a36Sopenharmony_ci .aead = __VECS(hmac_sha1_ecb_cipher_null_tv_temp) 436862306a36Sopenharmony_ci } 436962306a36Sopenharmony_ci }, { 437062306a36Sopenharmony_ci .alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 437162306a36Sopenharmony_ci .test = alg_test_null, 437262306a36Sopenharmony_ci .fips_allowed = 1, 437362306a36Sopenharmony_ci }, { 437462306a36Sopenharmony_ci .alg = "authenc(hmac(sha224),cbc(des))", 437562306a36Sopenharmony_ci .test = alg_test_aead, 437662306a36Sopenharmony_ci .suite = { 437762306a36Sopenharmony_ci .aead = __VECS(hmac_sha224_des_cbc_tv_temp) 437862306a36Sopenharmony_ci } 437962306a36Sopenharmony_ci }, { 438062306a36Sopenharmony_ci .alg = "authenc(hmac(sha224),cbc(des3_ede))", 438162306a36Sopenharmony_ci .test = alg_test_aead, 438262306a36Sopenharmony_ci .suite = { 438362306a36Sopenharmony_ci .aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp) 438462306a36Sopenharmony_ci } 438562306a36Sopenharmony_ci }, { 438662306a36Sopenharmony_ci .alg = "authenc(hmac(sha256),cbc(aes))", 438762306a36Sopenharmony_ci .test = alg_test_aead, 438862306a36Sopenharmony_ci .fips_allowed = 1, 438962306a36Sopenharmony_ci .suite = { 439062306a36Sopenharmony_ci .aead = __VECS(hmac_sha256_aes_cbc_tv_temp) 439162306a36Sopenharmony_ci } 439262306a36Sopenharmony_ci }, { 439362306a36Sopenharmony_ci .alg = "authenc(hmac(sha256),cbc(des))", 439462306a36Sopenharmony_ci .test = alg_test_aead, 439562306a36Sopenharmony_ci .suite = { 439662306a36Sopenharmony_ci .aead = __VECS(hmac_sha256_des_cbc_tv_temp) 439762306a36Sopenharmony_ci } 439862306a36Sopenharmony_ci }, { 439962306a36Sopenharmony_ci .alg = "authenc(hmac(sha256),cbc(des3_ede))", 440062306a36Sopenharmony_ci .test = alg_test_aead, 440162306a36Sopenharmony_ci .suite = { 440262306a36Sopenharmony_ci .aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp) 440362306a36Sopenharmony_ci } 440462306a36Sopenharmony_ci }, { 440562306a36Sopenharmony_ci .alg = "authenc(hmac(sha256),ctr(aes))", 440662306a36Sopenharmony_ci .test = alg_test_null, 440762306a36Sopenharmony_ci .fips_allowed = 1, 440862306a36Sopenharmony_ci }, { 440962306a36Sopenharmony_ci .alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 441062306a36Sopenharmony_ci .test = alg_test_null, 441162306a36Sopenharmony_ci .fips_allowed = 1, 441262306a36Sopenharmony_ci }, { 441362306a36Sopenharmony_ci .alg = "authenc(hmac(sha384),cbc(des))", 441462306a36Sopenharmony_ci .test = alg_test_aead, 441562306a36Sopenharmony_ci .suite = { 441662306a36Sopenharmony_ci .aead = __VECS(hmac_sha384_des_cbc_tv_temp) 441762306a36Sopenharmony_ci } 441862306a36Sopenharmony_ci }, { 441962306a36Sopenharmony_ci .alg = "authenc(hmac(sha384),cbc(des3_ede))", 442062306a36Sopenharmony_ci .test = alg_test_aead, 442162306a36Sopenharmony_ci .suite = { 442262306a36Sopenharmony_ci .aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp) 442362306a36Sopenharmony_ci } 442462306a36Sopenharmony_ci }, { 442562306a36Sopenharmony_ci .alg = "authenc(hmac(sha384),ctr(aes))", 442662306a36Sopenharmony_ci .test = alg_test_null, 442762306a36Sopenharmony_ci .fips_allowed = 1, 442862306a36Sopenharmony_ci }, { 442962306a36Sopenharmony_ci .alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 443062306a36Sopenharmony_ci .test = alg_test_null, 443162306a36Sopenharmony_ci .fips_allowed = 1, 443262306a36Sopenharmony_ci }, { 443362306a36Sopenharmony_ci .alg = "authenc(hmac(sha512),cbc(aes))", 443462306a36Sopenharmony_ci .fips_allowed = 1, 443562306a36Sopenharmony_ci .test = alg_test_aead, 443662306a36Sopenharmony_ci .suite = { 443762306a36Sopenharmony_ci .aead = __VECS(hmac_sha512_aes_cbc_tv_temp) 443862306a36Sopenharmony_ci } 443962306a36Sopenharmony_ci }, { 444062306a36Sopenharmony_ci .alg = "authenc(hmac(sha512),cbc(des))", 444162306a36Sopenharmony_ci .test = alg_test_aead, 444262306a36Sopenharmony_ci .suite = { 444362306a36Sopenharmony_ci .aead = __VECS(hmac_sha512_des_cbc_tv_temp) 444462306a36Sopenharmony_ci } 444562306a36Sopenharmony_ci }, { 444662306a36Sopenharmony_ci .alg = "authenc(hmac(sha512),cbc(des3_ede))", 444762306a36Sopenharmony_ci .test = alg_test_aead, 444862306a36Sopenharmony_ci .suite = { 444962306a36Sopenharmony_ci .aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp) 445062306a36Sopenharmony_ci } 445162306a36Sopenharmony_ci }, { 445262306a36Sopenharmony_ci .alg = "authenc(hmac(sha512),ctr(aes))", 445362306a36Sopenharmony_ci .test = alg_test_null, 445462306a36Sopenharmony_ci .fips_allowed = 1, 445562306a36Sopenharmony_ci }, { 445662306a36Sopenharmony_ci .alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 445762306a36Sopenharmony_ci .test = alg_test_null, 445862306a36Sopenharmony_ci .fips_allowed = 1, 445962306a36Sopenharmony_ci }, { 446062306a36Sopenharmony_ci .alg = "blake2b-160", 446162306a36Sopenharmony_ci .test = alg_test_hash, 446262306a36Sopenharmony_ci .fips_allowed = 0, 446362306a36Sopenharmony_ci .suite = { 446462306a36Sopenharmony_ci .hash = __VECS(blake2b_160_tv_template) 446562306a36Sopenharmony_ci } 446662306a36Sopenharmony_ci }, { 446762306a36Sopenharmony_ci .alg = "blake2b-256", 446862306a36Sopenharmony_ci .test = alg_test_hash, 446962306a36Sopenharmony_ci .fips_allowed = 0, 447062306a36Sopenharmony_ci .suite = { 447162306a36Sopenharmony_ci .hash = __VECS(blake2b_256_tv_template) 447262306a36Sopenharmony_ci } 447362306a36Sopenharmony_ci }, { 447462306a36Sopenharmony_ci .alg = "blake2b-384", 447562306a36Sopenharmony_ci .test = alg_test_hash, 447662306a36Sopenharmony_ci .fips_allowed = 0, 447762306a36Sopenharmony_ci .suite = { 447862306a36Sopenharmony_ci .hash = __VECS(blake2b_384_tv_template) 447962306a36Sopenharmony_ci } 448062306a36Sopenharmony_ci }, { 448162306a36Sopenharmony_ci .alg = "blake2b-512", 448262306a36Sopenharmony_ci .test = alg_test_hash, 448362306a36Sopenharmony_ci .fips_allowed = 0, 448462306a36Sopenharmony_ci .suite = { 448562306a36Sopenharmony_ci .hash = __VECS(blake2b_512_tv_template) 448662306a36Sopenharmony_ci } 448762306a36Sopenharmony_ci }, { 448862306a36Sopenharmony_ci .alg = "cbc(aes)", 448962306a36Sopenharmony_ci .test = alg_test_skcipher, 449062306a36Sopenharmony_ci .fips_allowed = 1, 449162306a36Sopenharmony_ci .suite = { 449262306a36Sopenharmony_ci .cipher = __VECS(aes_cbc_tv_template) 449362306a36Sopenharmony_ci }, 449462306a36Sopenharmony_ci }, { 449562306a36Sopenharmony_ci .alg = "cbc(anubis)", 449662306a36Sopenharmony_ci .test = alg_test_skcipher, 449762306a36Sopenharmony_ci .suite = { 449862306a36Sopenharmony_ci .cipher = __VECS(anubis_cbc_tv_template) 449962306a36Sopenharmony_ci }, 450062306a36Sopenharmony_ci }, { 450162306a36Sopenharmony_ci .alg = "cbc(aria)", 450262306a36Sopenharmony_ci .test = alg_test_skcipher, 450362306a36Sopenharmony_ci .suite = { 450462306a36Sopenharmony_ci .cipher = __VECS(aria_cbc_tv_template) 450562306a36Sopenharmony_ci }, 450662306a36Sopenharmony_ci }, { 450762306a36Sopenharmony_ci .alg = "cbc(blowfish)", 450862306a36Sopenharmony_ci .test = alg_test_skcipher, 450962306a36Sopenharmony_ci .suite = { 451062306a36Sopenharmony_ci .cipher = __VECS(bf_cbc_tv_template) 451162306a36Sopenharmony_ci }, 451262306a36Sopenharmony_ci }, { 451362306a36Sopenharmony_ci .alg = "cbc(camellia)", 451462306a36Sopenharmony_ci .test = alg_test_skcipher, 451562306a36Sopenharmony_ci .suite = { 451662306a36Sopenharmony_ci .cipher = __VECS(camellia_cbc_tv_template) 451762306a36Sopenharmony_ci }, 451862306a36Sopenharmony_ci }, { 451962306a36Sopenharmony_ci .alg = "cbc(cast5)", 452062306a36Sopenharmony_ci .test = alg_test_skcipher, 452162306a36Sopenharmony_ci .suite = { 452262306a36Sopenharmony_ci .cipher = __VECS(cast5_cbc_tv_template) 452362306a36Sopenharmony_ci }, 452462306a36Sopenharmony_ci }, { 452562306a36Sopenharmony_ci .alg = "cbc(cast6)", 452662306a36Sopenharmony_ci .test = alg_test_skcipher, 452762306a36Sopenharmony_ci .suite = { 452862306a36Sopenharmony_ci .cipher = __VECS(cast6_cbc_tv_template) 452962306a36Sopenharmony_ci }, 453062306a36Sopenharmony_ci }, { 453162306a36Sopenharmony_ci .alg = "cbc(des)", 453262306a36Sopenharmony_ci .test = alg_test_skcipher, 453362306a36Sopenharmony_ci .suite = { 453462306a36Sopenharmony_ci .cipher = __VECS(des_cbc_tv_template) 453562306a36Sopenharmony_ci }, 453662306a36Sopenharmony_ci }, { 453762306a36Sopenharmony_ci .alg = "cbc(des3_ede)", 453862306a36Sopenharmony_ci .test = alg_test_skcipher, 453962306a36Sopenharmony_ci .suite = { 454062306a36Sopenharmony_ci .cipher = __VECS(des3_ede_cbc_tv_template) 454162306a36Sopenharmony_ci }, 454262306a36Sopenharmony_ci }, { 454362306a36Sopenharmony_ci /* Same as cbc(aes) except the key is stored in 454462306a36Sopenharmony_ci * hardware secure memory which we reference by index 454562306a36Sopenharmony_ci */ 454662306a36Sopenharmony_ci .alg = "cbc(paes)", 454762306a36Sopenharmony_ci .test = alg_test_null, 454862306a36Sopenharmony_ci .fips_allowed = 1, 454962306a36Sopenharmony_ci }, { 455062306a36Sopenharmony_ci /* Same as cbc(sm4) except the key is stored in 455162306a36Sopenharmony_ci * hardware secure memory which we reference by index 455262306a36Sopenharmony_ci */ 455362306a36Sopenharmony_ci .alg = "cbc(psm4)", 455462306a36Sopenharmony_ci .test = alg_test_null, 455562306a36Sopenharmony_ci }, { 455662306a36Sopenharmony_ci .alg = "cbc(serpent)", 455762306a36Sopenharmony_ci .test = alg_test_skcipher, 455862306a36Sopenharmony_ci .suite = { 455962306a36Sopenharmony_ci .cipher = __VECS(serpent_cbc_tv_template) 456062306a36Sopenharmony_ci }, 456162306a36Sopenharmony_ci }, { 456262306a36Sopenharmony_ci .alg = "cbc(sm4)", 456362306a36Sopenharmony_ci .test = alg_test_skcipher, 456462306a36Sopenharmony_ci .suite = { 456562306a36Sopenharmony_ci .cipher = __VECS(sm4_cbc_tv_template) 456662306a36Sopenharmony_ci } 456762306a36Sopenharmony_ci }, { 456862306a36Sopenharmony_ci .alg = "cbc(twofish)", 456962306a36Sopenharmony_ci .test = alg_test_skcipher, 457062306a36Sopenharmony_ci .suite = { 457162306a36Sopenharmony_ci .cipher = __VECS(tf_cbc_tv_template) 457262306a36Sopenharmony_ci }, 457362306a36Sopenharmony_ci }, { 457462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CRYPTO_PAES_S390) 457562306a36Sopenharmony_ci .alg = "cbc-paes-s390", 457662306a36Sopenharmony_ci .fips_allowed = 1, 457762306a36Sopenharmony_ci .test = alg_test_skcipher, 457862306a36Sopenharmony_ci .suite = { 457962306a36Sopenharmony_ci .cipher = __VECS(aes_cbc_tv_template) 458062306a36Sopenharmony_ci } 458162306a36Sopenharmony_ci }, { 458262306a36Sopenharmony_ci#endif 458362306a36Sopenharmony_ci .alg = "cbcmac(aes)", 458462306a36Sopenharmony_ci .test = alg_test_hash, 458562306a36Sopenharmony_ci .suite = { 458662306a36Sopenharmony_ci .hash = __VECS(aes_cbcmac_tv_template) 458762306a36Sopenharmony_ci } 458862306a36Sopenharmony_ci }, { 458962306a36Sopenharmony_ci .alg = "cbcmac(sm4)", 459062306a36Sopenharmony_ci .test = alg_test_hash, 459162306a36Sopenharmony_ci .suite = { 459262306a36Sopenharmony_ci .hash = __VECS(sm4_cbcmac_tv_template) 459362306a36Sopenharmony_ci } 459462306a36Sopenharmony_ci }, { 459562306a36Sopenharmony_ci .alg = "ccm(aes)", 459662306a36Sopenharmony_ci .generic_driver = "ccm_base(ctr(aes-generic),cbcmac(aes-generic))", 459762306a36Sopenharmony_ci .test = alg_test_aead, 459862306a36Sopenharmony_ci .fips_allowed = 1, 459962306a36Sopenharmony_ci .suite = { 460062306a36Sopenharmony_ci .aead = { 460162306a36Sopenharmony_ci ____VECS(aes_ccm_tv_template), 460262306a36Sopenharmony_ci .einval_allowed = 1, 460362306a36Sopenharmony_ci } 460462306a36Sopenharmony_ci } 460562306a36Sopenharmony_ci }, { 460662306a36Sopenharmony_ci .alg = "ccm(sm4)", 460762306a36Sopenharmony_ci .generic_driver = "ccm_base(ctr(sm4-generic),cbcmac(sm4-generic))", 460862306a36Sopenharmony_ci .test = alg_test_aead, 460962306a36Sopenharmony_ci .suite = { 461062306a36Sopenharmony_ci .aead = { 461162306a36Sopenharmony_ci ____VECS(sm4_ccm_tv_template), 461262306a36Sopenharmony_ci .einval_allowed = 1, 461362306a36Sopenharmony_ci } 461462306a36Sopenharmony_ci } 461562306a36Sopenharmony_ci }, { 461662306a36Sopenharmony_ci .alg = "cfb(aes)", 461762306a36Sopenharmony_ci .test = alg_test_skcipher, 461862306a36Sopenharmony_ci .fips_allowed = 1, 461962306a36Sopenharmony_ci .suite = { 462062306a36Sopenharmony_ci .cipher = __VECS(aes_cfb_tv_template) 462162306a36Sopenharmony_ci }, 462262306a36Sopenharmony_ci }, { 462362306a36Sopenharmony_ci .alg = "cfb(aria)", 462462306a36Sopenharmony_ci .test = alg_test_skcipher, 462562306a36Sopenharmony_ci .suite = { 462662306a36Sopenharmony_ci .cipher = __VECS(aria_cfb_tv_template) 462762306a36Sopenharmony_ci }, 462862306a36Sopenharmony_ci }, { 462962306a36Sopenharmony_ci .alg = "cfb(sm4)", 463062306a36Sopenharmony_ci .test = alg_test_skcipher, 463162306a36Sopenharmony_ci .suite = { 463262306a36Sopenharmony_ci .cipher = __VECS(sm4_cfb_tv_template) 463362306a36Sopenharmony_ci } 463462306a36Sopenharmony_ci }, { 463562306a36Sopenharmony_ci .alg = "chacha20", 463662306a36Sopenharmony_ci .test = alg_test_skcipher, 463762306a36Sopenharmony_ci .suite = { 463862306a36Sopenharmony_ci .cipher = __VECS(chacha20_tv_template) 463962306a36Sopenharmony_ci }, 464062306a36Sopenharmony_ci }, { 464162306a36Sopenharmony_ci .alg = "cmac(aes)", 464262306a36Sopenharmony_ci .fips_allowed = 1, 464362306a36Sopenharmony_ci .test = alg_test_hash, 464462306a36Sopenharmony_ci .suite = { 464562306a36Sopenharmony_ci .hash = __VECS(aes_cmac128_tv_template) 464662306a36Sopenharmony_ci } 464762306a36Sopenharmony_ci }, { 464862306a36Sopenharmony_ci .alg = "cmac(camellia)", 464962306a36Sopenharmony_ci .test = alg_test_hash, 465062306a36Sopenharmony_ci .suite = { 465162306a36Sopenharmony_ci .hash = __VECS(camellia_cmac128_tv_template) 465262306a36Sopenharmony_ci } 465362306a36Sopenharmony_ci }, { 465462306a36Sopenharmony_ci .alg = "cmac(des3_ede)", 465562306a36Sopenharmony_ci .test = alg_test_hash, 465662306a36Sopenharmony_ci .suite = { 465762306a36Sopenharmony_ci .hash = __VECS(des3_ede_cmac64_tv_template) 465862306a36Sopenharmony_ci } 465962306a36Sopenharmony_ci }, { 466062306a36Sopenharmony_ci .alg = "cmac(sm4)", 466162306a36Sopenharmony_ci .test = alg_test_hash, 466262306a36Sopenharmony_ci .suite = { 466362306a36Sopenharmony_ci .hash = __VECS(sm4_cmac128_tv_template) 466462306a36Sopenharmony_ci } 466562306a36Sopenharmony_ci }, { 466662306a36Sopenharmony_ci .alg = "compress_null", 466762306a36Sopenharmony_ci .test = alg_test_null, 466862306a36Sopenharmony_ci }, { 466962306a36Sopenharmony_ci .alg = "crc32", 467062306a36Sopenharmony_ci .test = alg_test_hash, 467162306a36Sopenharmony_ci .fips_allowed = 1, 467262306a36Sopenharmony_ci .suite = { 467362306a36Sopenharmony_ci .hash = __VECS(crc32_tv_template) 467462306a36Sopenharmony_ci } 467562306a36Sopenharmony_ci }, { 467662306a36Sopenharmony_ci .alg = "crc32c", 467762306a36Sopenharmony_ci .test = alg_test_crc32c, 467862306a36Sopenharmony_ci .fips_allowed = 1, 467962306a36Sopenharmony_ci .suite = { 468062306a36Sopenharmony_ci .hash = __VECS(crc32c_tv_template) 468162306a36Sopenharmony_ci } 468262306a36Sopenharmony_ci }, { 468362306a36Sopenharmony_ci .alg = "crc64-rocksoft", 468462306a36Sopenharmony_ci .test = alg_test_hash, 468562306a36Sopenharmony_ci .fips_allowed = 1, 468662306a36Sopenharmony_ci .suite = { 468762306a36Sopenharmony_ci .hash = __VECS(crc64_rocksoft_tv_template) 468862306a36Sopenharmony_ci } 468962306a36Sopenharmony_ci }, { 469062306a36Sopenharmony_ci .alg = "crct10dif", 469162306a36Sopenharmony_ci .test = alg_test_hash, 469262306a36Sopenharmony_ci .fips_allowed = 1, 469362306a36Sopenharmony_ci .suite = { 469462306a36Sopenharmony_ci .hash = __VECS(crct10dif_tv_template) 469562306a36Sopenharmony_ci } 469662306a36Sopenharmony_ci }, { 469762306a36Sopenharmony_ci .alg = "ctr(aes)", 469862306a36Sopenharmony_ci .test = alg_test_skcipher, 469962306a36Sopenharmony_ci .fips_allowed = 1, 470062306a36Sopenharmony_ci .suite = { 470162306a36Sopenharmony_ci .cipher = __VECS(aes_ctr_tv_template) 470262306a36Sopenharmony_ci } 470362306a36Sopenharmony_ci }, { 470462306a36Sopenharmony_ci .alg = "ctr(aria)", 470562306a36Sopenharmony_ci .test = alg_test_skcipher, 470662306a36Sopenharmony_ci .suite = { 470762306a36Sopenharmony_ci .cipher = __VECS(aria_ctr_tv_template) 470862306a36Sopenharmony_ci } 470962306a36Sopenharmony_ci }, { 471062306a36Sopenharmony_ci .alg = "ctr(blowfish)", 471162306a36Sopenharmony_ci .test = alg_test_skcipher, 471262306a36Sopenharmony_ci .suite = { 471362306a36Sopenharmony_ci .cipher = __VECS(bf_ctr_tv_template) 471462306a36Sopenharmony_ci } 471562306a36Sopenharmony_ci }, { 471662306a36Sopenharmony_ci .alg = "ctr(camellia)", 471762306a36Sopenharmony_ci .test = alg_test_skcipher, 471862306a36Sopenharmony_ci .suite = { 471962306a36Sopenharmony_ci .cipher = __VECS(camellia_ctr_tv_template) 472062306a36Sopenharmony_ci } 472162306a36Sopenharmony_ci }, { 472262306a36Sopenharmony_ci .alg = "ctr(cast5)", 472362306a36Sopenharmony_ci .test = alg_test_skcipher, 472462306a36Sopenharmony_ci .suite = { 472562306a36Sopenharmony_ci .cipher = __VECS(cast5_ctr_tv_template) 472662306a36Sopenharmony_ci } 472762306a36Sopenharmony_ci }, { 472862306a36Sopenharmony_ci .alg = "ctr(cast6)", 472962306a36Sopenharmony_ci .test = alg_test_skcipher, 473062306a36Sopenharmony_ci .suite = { 473162306a36Sopenharmony_ci .cipher = __VECS(cast6_ctr_tv_template) 473262306a36Sopenharmony_ci } 473362306a36Sopenharmony_ci }, { 473462306a36Sopenharmony_ci .alg = "ctr(des)", 473562306a36Sopenharmony_ci .test = alg_test_skcipher, 473662306a36Sopenharmony_ci .suite = { 473762306a36Sopenharmony_ci .cipher = __VECS(des_ctr_tv_template) 473862306a36Sopenharmony_ci } 473962306a36Sopenharmony_ci }, { 474062306a36Sopenharmony_ci .alg = "ctr(des3_ede)", 474162306a36Sopenharmony_ci .test = alg_test_skcipher, 474262306a36Sopenharmony_ci .suite = { 474362306a36Sopenharmony_ci .cipher = __VECS(des3_ede_ctr_tv_template) 474462306a36Sopenharmony_ci } 474562306a36Sopenharmony_ci }, { 474662306a36Sopenharmony_ci /* Same as ctr(aes) except the key is stored in 474762306a36Sopenharmony_ci * hardware secure memory which we reference by index 474862306a36Sopenharmony_ci */ 474962306a36Sopenharmony_ci .alg = "ctr(paes)", 475062306a36Sopenharmony_ci .test = alg_test_null, 475162306a36Sopenharmony_ci .fips_allowed = 1, 475262306a36Sopenharmony_ci }, { 475362306a36Sopenharmony_ci 475462306a36Sopenharmony_ci /* Same as ctr(sm4) except the key is stored in 475562306a36Sopenharmony_ci * hardware secure memory which we reference by index 475662306a36Sopenharmony_ci */ 475762306a36Sopenharmony_ci .alg = "ctr(psm4)", 475862306a36Sopenharmony_ci .test = alg_test_null, 475962306a36Sopenharmony_ci }, { 476062306a36Sopenharmony_ci .alg = "ctr(serpent)", 476162306a36Sopenharmony_ci .test = alg_test_skcipher, 476262306a36Sopenharmony_ci .suite = { 476362306a36Sopenharmony_ci .cipher = __VECS(serpent_ctr_tv_template) 476462306a36Sopenharmony_ci } 476562306a36Sopenharmony_ci }, { 476662306a36Sopenharmony_ci .alg = "ctr(sm4)", 476762306a36Sopenharmony_ci .test = alg_test_skcipher, 476862306a36Sopenharmony_ci .suite = { 476962306a36Sopenharmony_ci .cipher = __VECS(sm4_ctr_tv_template) 477062306a36Sopenharmony_ci } 477162306a36Sopenharmony_ci }, { 477262306a36Sopenharmony_ci .alg = "ctr(twofish)", 477362306a36Sopenharmony_ci .test = alg_test_skcipher, 477462306a36Sopenharmony_ci .suite = { 477562306a36Sopenharmony_ci .cipher = __VECS(tf_ctr_tv_template) 477662306a36Sopenharmony_ci } 477762306a36Sopenharmony_ci }, { 477862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CRYPTO_PAES_S390) 477962306a36Sopenharmony_ci .alg = "ctr-paes-s390", 478062306a36Sopenharmony_ci .fips_allowed = 1, 478162306a36Sopenharmony_ci .test = alg_test_skcipher, 478262306a36Sopenharmony_ci .suite = { 478362306a36Sopenharmony_ci .cipher = __VECS(aes_ctr_tv_template) 478462306a36Sopenharmony_ci } 478562306a36Sopenharmony_ci }, { 478662306a36Sopenharmony_ci#endif 478762306a36Sopenharmony_ci .alg = "cts(cbc(aes))", 478862306a36Sopenharmony_ci .test = alg_test_skcipher, 478962306a36Sopenharmony_ci .fips_allowed = 1, 479062306a36Sopenharmony_ci .suite = { 479162306a36Sopenharmony_ci .cipher = __VECS(cts_mode_tv_template) 479262306a36Sopenharmony_ci } 479362306a36Sopenharmony_ci }, { 479462306a36Sopenharmony_ci /* Same as cts(cbc((aes)) except the key is stored in 479562306a36Sopenharmony_ci * hardware secure memory which we reference by index 479662306a36Sopenharmony_ci */ 479762306a36Sopenharmony_ci .alg = "cts(cbc(paes))", 479862306a36Sopenharmony_ci .test = alg_test_null, 479962306a36Sopenharmony_ci .fips_allowed = 1, 480062306a36Sopenharmony_ci }, { 480162306a36Sopenharmony_ci .alg = "cts(cbc(sm4))", 480262306a36Sopenharmony_ci .test = alg_test_skcipher, 480362306a36Sopenharmony_ci .suite = { 480462306a36Sopenharmony_ci .cipher = __VECS(sm4_cts_tv_template) 480562306a36Sopenharmony_ci } 480662306a36Sopenharmony_ci }, { 480762306a36Sopenharmony_ci .alg = "curve25519", 480862306a36Sopenharmony_ci .test = alg_test_kpp, 480962306a36Sopenharmony_ci .suite = { 481062306a36Sopenharmony_ci .kpp = __VECS(curve25519_tv_template) 481162306a36Sopenharmony_ci } 481262306a36Sopenharmony_ci }, { 481362306a36Sopenharmony_ci .alg = "deflate", 481462306a36Sopenharmony_ci .test = alg_test_comp, 481562306a36Sopenharmony_ci .fips_allowed = 1, 481662306a36Sopenharmony_ci .suite = { 481762306a36Sopenharmony_ci .comp = { 481862306a36Sopenharmony_ci .comp = __VECS(deflate_comp_tv_template), 481962306a36Sopenharmony_ci .decomp = __VECS(deflate_decomp_tv_template) 482062306a36Sopenharmony_ci } 482162306a36Sopenharmony_ci } 482262306a36Sopenharmony_ci }, { 482362306a36Sopenharmony_ci .alg = "dh", 482462306a36Sopenharmony_ci .test = alg_test_kpp, 482562306a36Sopenharmony_ci .suite = { 482662306a36Sopenharmony_ci .kpp = __VECS(dh_tv_template) 482762306a36Sopenharmony_ci } 482862306a36Sopenharmony_ci }, { 482962306a36Sopenharmony_ci .alg = "digest_null", 483062306a36Sopenharmony_ci .test = alg_test_null, 483162306a36Sopenharmony_ci }, { 483262306a36Sopenharmony_ci .alg = "drbg_nopr_ctr_aes128", 483362306a36Sopenharmony_ci .test = alg_test_drbg, 483462306a36Sopenharmony_ci .fips_allowed = 1, 483562306a36Sopenharmony_ci .suite = { 483662306a36Sopenharmony_ci .drbg = __VECS(drbg_nopr_ctr_aes128_tv_template) 483762306a36Sopenharmony_ci } 483862306a36Sopenharmony_ci }, { 483962306a36Sopenharmony_ci .alg = "drbg_nopr_ctr_aes192", 484062306a36Sopenharmony_ci .test = alg_test_drbg, 484162306a36Sopenharmony_ci .fips_allowed = 1, 484262306a36Sopenharmony_ci .suite = { 484362306a36Sopenharmony_ci .drbg = __VECS(drbg_nopr_ctr_aes192_tv_template) 484462306a36Sopenharmony_ci } 484562306a36Sopenharmony_ci }, { 484662306a36Sopenharmony_ci .alg = "drbg_nopr_ctr_aes256", 484762306a36Sopenharmony_ci .test = alg_test_drbg, 484862306a36Sopenharmony_ci .fips_allowed = 1, 484962306a36Sopenharmony_ci .suite = { 485062306a36Sopenharmony_ci .drbg = __VECS(drbg_nopr_ctr_aes256_tv_template) 485162306a36Sopenharmony_ci } 485262306a36Sopenharmony_ci }, { 485362306a36Sopenharmony_ci /* 485462306a36Sopenharmony_ci * There is no need to specifically test the DRBG with every 485562306a36Sopenharmony_ci * backend cipher -- covered by drbg_nopr_hmac_sha256 test 485662306a36Sopenharmony_ci */ 485762306a36Sopenharmony_ci .alg = "drbg_nopr_hmac_sha1", 485862306a36Sopenharmony_ci .fips_allowed = 1, 485962306a36Sopenharmony_ci .test = alg_test_null, 486062306a36Sopenharmony_ci }, { 486162306a36Sopenharmony_ci .alg = "drbg_nopr_hmac_sha256", 486262306a36Sopenharmony_ci .test = alg_test_drbg, 486362306a36Sopenharmony_ci .fips_allowed = 1, 486462306a36Sopenharmony_ci .suite = { 486562306a36Sopenharmony_ci .drbg = __VECS(drbg_nopr_hmac_sha256_tv_template) 486662306a36Sopenharmony_ci } 486762306a36Sopenharmony_ci }, { 486862306a36Sopenharmony_ci /* covered by drbg_nopr_hmac_sha256 test */ 486962306a36Sopenharmony_ci .alg = "drbg_nopr_hmac_sha384", 487062306a36Sopenharmony_ci .test = alg_test_null, 487162306a36Sopenharmony_ci }, { 487262306a36Sopenharmony_ci .alg = "drbg_nopr_hmac_sha512", 487362306a36Sopenharmony_ci .test = alg_test_drbg, 487462306a36Sopenharmony_ci .fips_allowed = 1, 487562306a36Sopenharmony_ci .suite = { 487662306a36Sopenharmony_ci .drbg = __VECS(drbg_nopr_hmac_sha512_tv_template) 487762306a36Sopenharmony_ci } 487862306a36Sopenharmony_ci }, { 487962306a36Sopenharmony_ci .alg = "drbg_nopr_sha1", 488062306a36Sopenharmony_ci .fips_allowed = 1, 488162306a36Sopenharmony_ci .test = alg_test_null, 488262306a36Sopenharmony_ci }, { 488362306a36Sopenharmony_ci .alg = "drbg_nopr_sha256", 488462306a36Sopenharmony_ci .test = alg_test_drbg, 488562306a36Sopenharmony_ci .fips_allowed = 1, 488662306a36Sopenharmony_ci .suite = { 488762306a36Sopenharmony_ci .drbg = __VECS(drbg_nopr_sha256_tv_template) 488862306a36Sopenharmony_ci } 488962306a36Sopenharmony_ci }, { 489062306a36Sopenharmony_ci /* covered by drbg_nopr_sha256 test */ 489162306a36Sopenharmony_ci .alg = "drbg_nopr_sha384", 489262306a36Sopenharmony_ci .test = alg_test_null, 489362306a36Sopenharmony_ci }, { 489462306a36Sopenharmony_ci .alg = "drbg_nopr_sha512", 489562306a36Sopenharmony_ci .fips_allowed = 1, 489662306a36Sopenharmony_ci .test = alg_test_null, 489762306a36Sopenharmony_ci }, { 489862306a36Sopenharmony_ci .alg = "drbg_pr_ctr_aes128", 489962306a36Sopenharmony_ci .test = alg_test_drbg, 490062306a36Sopenharmony_ci .fips_allowed = 1, 490162306a36Sopenharmony_ci .suite = { 490262306a36Sopenharmony_ci .drbg = __VECS(drbg_pr_ctr_aes128_tv_template) 490362306a36Sopenharmony_ci } 490462306a36Sopenharmony_ci }, { 490562306a36Sopenharmony_ci /* covered by drbg_pr_ctr_aes128 test */ 490662306a36Sopenharmony_ci .alg = "drbg_pr_ctr_aes192", 490762306a36Sopenharmony_ci .fips_allowed = 1, 490862306a36Sopenharmony_ci .test = alg_test_null, 490962306a36Sopenharmony_ci }, { 491062306a36Sopenharmony_ci .alg = "drbg_pr_ctr_aes256", 491162306a36Sopenharmony_ci .fips_allowed = 1, 491262306a36Sopenharmony_ci .test = alg_test_null, 491362306a36Sopenharmony_ci }, { 491462306a36Sopenharmony_ci .alg = "drbg_pr_hmac_sha1", 491562306a36Sopenharmony_ci .fips_allowed = 1, 491662306a36Sopenharmony_ci .test = alg_test_null, 491762306a36Sopenharmony_ci }, { 491862306a36Sopenharmony_ci .alg = "drbg_pr_hmac_sha256", 491962306a36Sopenharmony_ci .test = alg_test_drbg, 492062306a36Sopenharmony_ci .fips_allowed = 1, 492162306a36Sopenharmony_ci .suite = { 492262306a36Sopenharmony_ci .drbg = __VECS(drbg_pr_hmac_sha256_tv_template) 492362306a36Sopenharmony_ci } 492462306a36Sopenharmony_ci }, { 492562306a36Sopenharmony_ci /* covered by drbg_pr_hmac_sha256 test */ 492662306a36Sopenharmony_ci .alg = "drbg_pr_hmac_sha384", 492762306a36Sopenharmony_ci .test = alg_test_null, 492862306a36Sopenharmony_ci }, { 492962306a36Sopenharmony_ci .alg = "drbg_pr_hmac_sha512", 493062306a36Sopenharmony_ci .test = alg_test_null, 493162306a36Sopenharmony_ci .fips_allowed = 1, 493262306a36Sopenharmony_ci }, { 493362306a36Sopenharmony_ci .alg = "drbg_pr_sha1", 493462306a36Sopenharmony_ci .fips_allowed = 1, 493562306a36Sopenharmony_ci .test = alg_test_null, 493662306a36Sopenharmony_ci }, { 493762306a36Sopenharmony_ci .alg = "drbg_pr_sha256", 493862306a36Sopenharmony_ci .test = alg_test_drbg, 493962306a36Sopenharmony_ci .fips_allowed = 1, 494062306a36Sopenharmony_ci .suite = { 494162306a36Sopenharmony_ci .drbg = __VECS(drbg_pr_sha256_tv_template) 494262306a36Sopenharmony_ci } 494362306a36Sopenharmony_ci }, { 494462306a36Sopenharmony_ci /* covered by drbg_pr_sha256 test */ 494562306a36Sopenharmony_ci .alg = "drbg_pr_sha384", 494662306a36Sopenharmony_ci .test = alg_test_null, 494762306a36Sopenharmony_ci }, { 494862306a36Sopenharmony_ci .alg = "drbg_pr_sha512", 494962306a36Sopenharmony_ci .fips_allowed = 1, 495062306a36Sopenharmony_ci .test = alg_test_null, 495162306a36Sopenharmony_ci }, { 495262306a36Sopenharmony_ci .alg = "ecb(aes)", 495362306a36Sopenharmony_ci .test = alg_test_skcipher, 495462306a36Sopenharmony_ci .fips_allowed = 1, 495562306a36Sopenharmony_ci .suite = { 495662306a36Sopenharmony_ci .cipher = __VECS(aes_tv_template) 495762306a36Sopenharmony_ci } 495862306a36Sopenharmony_ci }, { 495962306a36Sopenharmony_ci .alg = "ecb(anubis)", 496062306a36Sopenharmony_ci .test = alg_test_skcipher, 496162306a36Sopenharmony_ci .suite = { 496262306a36Sopenharmony_ci .cipher = __VECS(anubis_tv_template) 496362306a36Sopenharmony_ci } 496462306a36Sopenharmony_ci }, { 496562306a36Sopenharmony_ci .alg = "ecb(arc4)", 496662306a36Sopenharmony_ci .generic_driver = "ecb(arc4)-generic", 496762306a36Sopenharmony_ci .test = alg_test_skcipher, 496862306a36Sopenharmony_ci .suite = { 496962306a36Sopenharmony_ci .cipher = __VECS(arc4_tv_template) 497062306a36Sopenharmony_ci } 497162306a36Sopenharmony_ci }, { 497262306a36Sopenharmony_ci .alg = "ecb(aria)", 497362306a36Sopenharmony_ci .test = alg_test_skcipher, 497462306a36Sopenharmony_ci .suite = { 497562306a36Sopenharmony_ci .cipher = __VECS(aria_tv_template) 497662306a36Sopenharmony_ci } 497762306a36Sopenharmony_ci }, { 497862306a36Sopenharmony_ci .alg = "ecb(blowfish)", 497962306a36Sopenharmony_ci .test = alg_test_skcipher, 498062306a36Sopenharmony_ci .suite = { 498162306a36Sopenharmony_ci .cipher = __VECS(bf_tv_template) 498262306a36Sopenharmony_ci } 498362306a36Sopenharmony_ci }, { 498462306a36Sopenharmony_ci .alg = "ecb(camellia)", 498562306a36Sopenharmony_ci .test = alg_test_skcipher, 498662306a36Sopenharmony_ci .suite = { 498762306a36Sopenharmony_ci .cipher = __VECS(camellia_tv_template) 498862306a36Sopenharmony_ci } 498962306a36Sopenharmony_ci }, { 499062306a36Sopenharmony_ci .alg = "ecb(cast5)", 499162306a36Sopenharmony_ci .test = alg_test_skcipher, 499262306a36Sopenharmony_ci .suite = { 499362306a36Sopenharmony_ci .cipher = __VECS(cast5_tv_template) 499462306a36Sopenharmony_ci } 499562306a36Sopenharmony_ci }, { 499662306a36Sopenharmony_ci .alg = "ecb(cast6)", 499762306a36Sopenharmony_ci .test = alg_test_skcipher, 499862306a36Sopenharmony_ci .suite = { 499962306a36Sopenharmony_ci .cipher = __VECS(cast6_tv_template) 500062306a36Sopenharmony_ci } 500162306a36Sopenharmony_ci }, { 500262306a36Sopenharmony_ci .alg = "ecb(cipher_null)", 500362306a36Sopenharmony_ci .test = alg_test_null, 500462306a36Sopenharmony_ci .fips_allowed = 1, 500562306a36Sopenharmony_ci }, { 500662306a36Sopenharmony_ci .alg = "ecb(des)", 500762306a36Sopenharmony_ci .test = alg_test_skcipher, 500862306a36Sopenharmony_ci .suite = { 500962306a36Sopenharmony_ci .cipher = __VECS(des_tv_template) 501062306a36Sopenharmony_ci } 501162306a36Sopenharmony_ci }, { 501262306a36Sopenharmony_ci .alg = "ecb(des3_ede)", 501362306a36Sopenharmony_ci .test = alg_test_skcipher, 501462306a36Sopenharmony_ci .suite = { 501562306a36Sopenharmony_ci .cipher = __VECS(des3_ede_tv_template) 501662306a36Sopenharmony_ci } 501762306a36Sopenharmony_ci }, { 501862306a36Sopenharmony_ci .alg = "ecb(fcrypt)", 501962306a36Sopenharmony_ci .test = alg_test_skcipher, 502062306a36Sopenharmony_ci .suite = { 502162306a36Sopenharmony_ci .cipher = { 502262306a36Sopenharmony_ci .vecs = fcrypt_pcbc_tv_template, 502362306a36Sopenharmony_ci .count = 1 502462306a36Sopenharmony_ci } 502562306a36Sopenharmony_ci } 502662306a36Sopenharmony_ci }, { 502762306a36Sopenharmony_ci .alg = "ecb(khazad)", 502862306a36Sopenharmony_ci .test = alg_test_skcipher, 502962306a36Sopenharmony_ci .suite = { 503062306a36Sopenharmony_ci .cipher = __VECS(khazad_tv_template) 503162306a36Sopenharmony_ci } 503262306a36Sopenharmony_ci }, { 503362306a36Sopenharmony_ci /* Same as ecb(aes) except the key is stored in 503462306a36Sopenharmony_ci * hardware secure memory which we reference by index 503562306a36Sopenharmony_ci */ 503662306a36Sopenharmony_ci .alg = "ecb(paes)", 503762306a36Sopenharmony_ci .test = alg_test_null, 503862306a36Sopenharmony_ci .fips_allowed = 1, 503962306a36Sopenharmony_ci }, { 504062306a36Sopenharmony_ci .alg = "ecb(seed)", 504162306a36Sopenharmony_ci .test = alg_test_skcipher, 504262306a36Sopenharmony_ci .suite = { 504362306a36Sopenharmony_ci .cipher = __VECS(seed_tv_template) 504462306a36Sopenharmony_ci } 504562306a36Sopenharmony_ci }, { 504662306a36Sopenharmony_ci .alg = "ecb(serpent)", 504762306a36Sopenharmony_ci .test = alg_test_skcipher, 504862306a36Sopenharmony_ci .suite = { 504962306a36Sopenharmony_ci .cipher = __VECS(serpent_tv_template) 505062306a36Sopenharmony_ci } 505162306a36Sopenharmony_ci }, { 505262306a36Sopenharmony_ci .alg = "ecb(sm4)", 505362306a36Sopenharmony_ci .test = alg_test_skcipher, 505462306a36Sopenharmony_ci .suite = { 505562306a36Sopenharmony_ci .cipher = __VECS(sm4_tv_template) 505662306a36Sopenharmony_ci } 505762306a36Sopenharmony_ci }, { 505862306a36Sopenharmony_ci .alg = "ecb(tea)", 505962306a36Sopenharmony_ci .test = alg_test_skcipher, 506062306a36Sopenharmony_ci .suite = { 506162306a36Sopenharmony_ci .cipher = __VECS(tea_tv_template) 506262306a36Sopenharmony_ci } 506362306a36Sopenharmony_ci }, { 506462306a36Sopenharmony_ci .alg = "ecb(twofish)", 506562306a36Sopenharmony_ci .test = alg_test_skcipher, 506662306a36Sopenharmony_ci .suite = { 506762306a36Sopenharmony_ci .cipher = __VECS(tf_tv_template) 506862306a36Sopenharmony_ci } 506962306a36Sopenharmony_ci }, { 507062306a36Sopenharmony_ci .alg = "ecb(xeta)", 507162306a36Sopenharmony_ci .test = alg_test_skcipher, 507262306a36Sopenharmony_ci .suite = { 507362306a36Sopenharmony_ci .cipher = __VECS(xeta_tv_template) 507462306a36Sopenharmony_ci } 507562306a36Sopenharmony_ci }, { 507662306a36Sopenharmony_ci .alg = "ecb(xtea)", 507762306a36Sopenharmony_ci .test = alg_test_skcipher, 507862306a36Sopenharmony_ci .suite = { 507962306a36Sopenharmony_ci .cipher = __VECS(xtea_tv_template) 508062306a36Sopenharmony_ci } 508162306a36Sopenharmony_ci }, { 508262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CRYPTO_PAES_S390) 508362306a36Sopenharmony_ci .alg = "ecb-paes-s390", 508462306a36Sopenharmony_ci .fips_allowed = 1, 508562306a36Sopenharmony_ci .test = alg_test_skcipher, 508662306a36Sopenharmony_ci .suite = { 508762306a36Sopenharmony_ci .cipher = __VECS(aes_tv_template) 508862306a36Sopenharmony_ci } 508962306a36Sopenharmony_ci }, { 509062306a36Sopenharmony_ci#endif 509162306a36Sopenharmony_ci .alg = "ecdh-nist-p192", 509262306a36Sopenharmony_ci .test = alg_test_kpp, 509362306a36Sopenharmony_ci .suite = { 509462306a36Sopenharmony_ci .kpp = __VECS(ecdh_p192_tv_template) 509562306a36Sopenharmony_ci } 509662306a36Sopenharmony_ci }, { 509762306a36Sopenharmony_ci .alg = "ecdh-nist-p256", 509862306a36Sopenharmony_ci .test = alg_test_kpp, 509962306a36Sopenharmony_ci .fips_allowed = 1, 510062306a36Sopenharmony_ci .suite = { 510162306a36Sopenharmony_ci .kpp = __VECS(ecdh_p256_tv_template) 510262306a36Sopenharmony_ci } 510362306a36Sopenharmony_ci }, { 510462306a36Sopenharmony_ci .alg = "ecdh-nist-p384", 510562306a36Sopenharmony_ci .test = alg_test_kpp, 510662306a36Sopenharmony_ci .fips_allowed = 1, 510762306a36Sopenharmony_ci .suite = { 510862306a36Sopenharmony_ci .kpp = __VECS(ecdh_p384_tv_template) 510962306a36Sopenharmony_ci } 511062306a36Sopenharmony_ci }, { 511162306a36Sopenharmony_ci .alg = "ecdsa-nist-p192", 511262306a36Sopenharmony_ci .test = alg_test_akcipher, 511362306a36Sopenharmony_ci .suite = { 511462306a36Sopenharmony_ci .akcipher = __VECS(ecdsa_nist_p192_tv_template) 511562306a36Sopenharmony_ci } 511662306a36Sopenharmony_ci }, { 511762306a36Sopenharmony_ci .alg = "ecdsa-nist-p256", 511862306a36Sopenharmony_ci .test = alg_test_akcipher, 511962306a36Sopenharmony_ci .fips_allowed = 1, 512062306a36Sopenharmony_ci .suite = { 512162306a36Sopenharmony_ci .akcipher = __VECS(ecdsa_nist_p256_tv_template) 512262306a36Sopenharmony_ci } 512362306a36Sopenharmony_ci }, { 512462306a36Sopenharmony_ci .alg = "ecdsa-nist-p384", 512562306a36Sopenharmony_ci .test = alg_test_akcipher, 512662306a36Sopenharmony_ci .fips_allowed = 1, 512762306a36Sopenharmony_ci .suite = { 512862306a36Sopenharmony_ci .akcipher = __VECS(ecdsa_nist_p384_tv_template) 512962306a36Sopenharmony_ci } 513062306a36Sopenharmony_ci }, { 513162306a36Sopenharmony_ci .alg = "ecrdsa", 513262306a36Sopenharmony_ci .test = alg_test_akcipher, 513362306a36Sopenharmony_ci .suite = { 513462306a36Sopenharmony_ci .akcipher = __VECS(ecrdsa_tv_template) 513562306a36Sopenharmony_ci } 513662306a36Sopenharmony_ci }, { 513762306a36Sopenharmony_ci .alg = "essiv(authenc(hmac(sha256),cbc(aes)),sha256)", 513862306a36Sopenharmony_ci .test = alg_test_aead, 513962306a36Sopenharmony_ci .fips_allowed = 1, 514062306a36Sopenharmony_ci .suite = { 514162306a36Sopenharmony_ci .aead = __VECS(essiv_hmac_sha256_aes_cbc_tv_temp) 514262306a36Sopenharmony_ci } 514362306a36Sopenharmony_ci }, { 514462306a36Sopenharmony_ci .alg = "essiv(cbc(aes),sha256)", 514562306a36Sopenharmony_ci .test = alg_test_skcipher, 514662306a36Sopenharmony_ci .fips_allowed = 1, 514762306a36Sopenharmony_ci .suite = { 514862306a36Sopenharmony_ci .cipher = __VECS(essiv_aes_cbc_tv_template) 514962306a36Sopenharmony_ci } 515062306a36Sopenharmony_ci }, { 515162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CRYPTO_DH_RFC7919_GROUPS) 515262306a36Sopenharmony_ci .alg = "ffdhe2048(dh)", 515362306a36Sopenharmony_ci .test = alg_test_kpp, 515462306a36Sopenharmony_ci .fips_allowed = 1, 515562306a36Sopenharmony_ci .suite = { 515662306a36Sopenharmony_ci .kpp = __VECS(ffdhe2048_dh_tv_template) 515762306a36Sopenharmony_ci } 515862306a36Sopenharmony_ci }, { 515962306a36Sopenharmony_ci .alg = "ffdhe3072(dh)", 516062306a36Sopenharmony_ci .test = alg_test_kpp, 516162306a36Sopenharmony_ci .fips_allowed = 1, 516262306a36Sopenharmony_ci .suite = { 516362306a36Sopenharmony_ci .kpp = __VECS(ffdhe3072_dh_tv_template) 516462306a36Sopenharmony_ci } 516562306a36Sopenharmony_ci }, { 516662306a36Sopenharmony_ci .alg = "ffdhe4096(dh)", 516762306a36Sopenharmony_ci .test = alg_test_kpp, 516862306a36Sopenharmony_ci .fips_allowed = 1, 516962306a36Sopenharmony_ci .suite = { 517062306a36Sopenharmony_ci .kpp = __VECS(ffdhe4096_dh_tv_template) 517162306a36Sopenharmony_ci } 517262306a36Sopenharmony_ci }, { 517362306a36Sopenharmony_ci .alg = "ffdhe6144(dh)", 517462306a36Sopenharmony_ci .test = alg_test_kpp, 517562306a36Sopenharmony_ci .fips_allowed = 1, 517662306a36Sopenharmony_ci .suite = { 517762306a36Sopenharmony_ci .kpp = __VECS(ffdhe6144_dh_tv_template) 517862306a36Sopenharmony_ci } 517962306a36Sopenharmony_ci }, { 518062306a36Sopenharmony_ci .alg = "ffdhe8192(dh)", 518162306a36Sopenharmony_ci .test = alg_test_kpp, 518262306a36Sopenharmony_ci .fips_allowed = 1, 518362306a36Sopenharmony_ci .suite = { 518462306a36Sopenharmony_ci .kpp = __VECS(ffdhe8192_dh_tv_template) 518562306a36Sopenharmony_ci } 518662306a36Sopenharmony_ci }, { 518762306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_DH_RFC7919_GROUPS */ 518862306a36Sopenharmony_ci .alg = "gcm(aes)", 518962306a36Sopenharmony_ci .generic_driver = "gcm_base(ctr(aes-generic),ghash-generic)", 519062306a36Sopenharmony_ci .test = alg_test_aead, 519162306a36Sopenharmony_ci .fips_allowed = 1, 519262306a36Sopenharmony_ci .suite = { 519362306a36Sopenharmony_ci .aead = __VECS(aes_gcm_tv_template) 519462306a36Sopenharmony_ci } 519562306a36Sopenharmony_ci }, { 519662306a36Sopenharmony_ci .alg = "gcm(aria)", 519762306a36Sopenharmony_ci .generic_driver = "gcm_base(ctr(aria-generic),ghash-generic)", 519862306a36Sopenharmony_ci .test = alg_test_aead, 519962306a36Sopenharmony_ci .suite = { 520062306a36Sopenharmony_ci .aead = __VECS(aria_gcm_tv_template) 520162306a36Sopenharmony_ci } 520262306a36Sopenharmony_ci }, { 520362306a36Sopenharmony_ci .alg = "gcm(sm4)", 520462306a36Sopenharmony_ci .generic_driver = "gcm_base(ctr(sm4-generic),ghash-generic)", 520562306a36Sopenharmony_ci .test = alg_test_aead, 520662306a36Sopenharmony_ci .suite = { 520762306a36Sopenharmony_ci .aead = __VECS(sm4_gcm_tv_template) 520862306a36Sopenharmony_ci } 520962306a36Sopenharmony_ci }, { 521062306a36Sopenharmony_ci .alg = "ghash", 521162306a36Sopenharmony_ci .test = alg_test_hash, 521262306a36Sopenharmony_ci .suite = { 521362306a36Sopenharmony_ci .hash = __VECS(ghash_tv_template) 521462306a36Sopenharmony_ci } 521562306a36Sopenharmony_ci }, { 521662306a36Sopenharmony_ci .alg = "hctr2(aes)", 521762306a36Sopenharmony_ci .generic_driver = 521862306a36Sopenharmony_ci "hctr2_base(xctr(aes-generic),polyval-generic)", 521962306a36Sopenharmony_ci .test = alg_test_skcipher, 522062306a36Sopenharmony_ci .suite = { 522162306a36Sopenharmony_ci .cipher = __VECS(aes_hctr2_tv_template) 522262306a36Sopenharmony_ci } 522362306a36Sopenharmony_ci }, { 522462306a36Sopenharmony_ci .alg = "hmac(md5)", 522562306a36Sopenharmony_ci .test = alg_test_hash, 522662306a36Sopenharmony_ci .suite = { 522762306a36Sopenharmony_ci .hash = __VECS(hmac_md5_tv_template) 522862306a36Sopenharmony_ci } 522962306a36Sopenharmony_ci }, { 523062306a36Sopenharmony_ci .alg = "hmac(rmd160)", 523162306a36Sopenharmony_ci .test = alg_test_hash, 523262306a36Sopenharmony_ci .suite = { 523362306a36Sopenharmony_ci .hash = __VECS(hmac_rmd160_tv_template) 523462306a36Sopenharmony_ci } 523562306a36Sopenharmony_ci }, { 523662306a36Sopenharmony_ci .alg = "hmac(sha1)", 523762306a36Sopenharmony_ci .test = alg_test_hash, 523862306a36Sopenharmony_ci .fips_allowed = 1, 523962306a36Sopenharmony_ci .suite = { 524062306a36Sopenharmony_ci .hash = __VECS(hmac_sha1_tv_template) 524162306a36Sopenharmony_ci } 524262306a36Sopenharmony_ci }, { 524362306a36Sopenharmony_ci .alg = "hmac(sha224)", 524462306a36Sopenharmony_ci .test = alg_test_hash, 524562306a36Sopenharmony_ci .fips_allowed = 1, 524662306a36Sopenharmony_ci .suite = { 524762306a36Sopenharmony_ci .hash = __VECS(hmac_sha224_tv_template) 524862306a36Sopenharmony_ci } 524962306a36Sopenharmony_ci }, { 525062306a36Sopenharmony_ci .alg = "hmac(sha256)", 525162306a36Sopenharmony_ci .test = alg_test_hash, 525262306a36Sopenharmony_ci .fips_allowed = 1, 525362306a36Sopenharmony_ci .suite = { 525462306a36Sopenharmony_ci .hash = __VECS(hmac_sha256_tv_template) 525562306a36Sopenharmony_ci } 525662306a36Sopenharmony_ci }, { 525762306a36Sopenharmony_ci .alg = "hmac(sha3-224)", 525862306a36Sopenharmony_ci .test = alg_test_hash, 525962306a36Sopenharmony_ci .fips_allowed = 1, 526062306a36Sopenharmony_ci .suite = { 526162306a36Sopenharmony_ci .hash = __VECS(hmac_sha3_224_tv_template) 526262306a36Sopenharmony_ci } 526362306a36Sopenharmony_ci }, { 526462306a36Sopenharmony_ci .alg = "hmac(sha3-256)", 526562306a36Sopenharmony_ci .test = alg_test_hash, 526662306a36Sopenharmony_ci .fips_allowed = 1, 526762306a36Sopenharmony_ci .suite = { 526862306a36Sopenharmony_ci .hash = __VECS(hmac_sha3_256_tv_template) 526962306a36Sopenharmony_ci } 527062306a36Sopenharmony_ci }, { 527162306a36Sopenharmony_ci .alg = "hmac(sha3-384)", 527262306a36Sopenharmony_ci .test = alg_test_hash, 527362306a36Sopenharmony_ci .fips_allowed = 1, 527462306a36Sopenharmony_ci .suite = { 527562306a36Sopenharmony_ci .hash = __VECS(hmac_sha3_384_tv_template) 527662306a36Sopenharmony_ci } 527762306a36Sopenharmony_ci }, { 527862306a36Sopenharmony_ci .alg = "hmac(sha3-512)", 527962306a36Sopenharmony_ci .test = alg_test_hash, 528062306a36Sopenharmony_ci .fips_allowed = 1, 528162306a36Sopenharmony_ci .suite = { 528262306a36Sopenharmony_ci .hash = __VECS(hmac_sha3_512_tv_template) 528362306a36Sopenharmony_ci } 528462306a36Sopenharmony_ci }, { 528562306a36Sopenharmony_ci .alg = "hmac(sha384)", 528662306a36Sopenharmony_ci .test = alg_test_hash, 528762306a36Sopenharmony_ci .fips_allowed = 1, 528862306a36Sopenharmony_ci .suite = { 528962306a36Sopenharmony_ci .hash = __VECS(hmac_sha384_tv_template) 529062306a36Sopenharmony_ci } 529162306a36Sopenharmony_ci }, { 529262306a36Sopenharmony_ci .alg = "hmac(sha512)", 529362306a36Sopenharmony_ci .test = alg_test_hash, 529462306a36Sopenharmony_ci .fips_allowed = 1, 529562306a36Sopenharmony_ci .suite = { 529662306a36Sopenharmony_ci .hash = __VECS(hmac_sha512_tv_template) 529762306a36Sopenharmony_ci } 529862306a36Sopenharmony_ci }, { 529962306a36Sopenharmony_ci .alg = "hmac(sm3)", 530062306a36Sopenharmony_ci .test = alg_test_hash, 530162306a36Sopenharmony_ci .suite = { 530262306a36Sopenharmony_ci .hash = __VECS(hmac_sm3_tv_template) 530362306a36Sopenharmony_ci } 530462306a36Sopenharmony_ci }, { 530562306a36Sopenharmony_ci .alg = "hmac(streebog256)", 530662306a36Sopenharmony_ci .test = alg_test_hash, 530762306a36Sopenharmony_ci .suite = { 530862306a36Sopenharmony_ci .hash = __VECS(hmac_streebog256_tv_template) 530962306a36Sopenharmony_ci } 531062306a36Sopenharmony_ci }, { 531162306a36Sopenharmony_ci .alg = "hmac(streebog512)", 531262306a36Sopenharmony_ci .test = alg_test_hash, 531362306a36Sopenharmony_ci .suite = { 531462306a36Sopenharmony_ci .hash = __VECS(hmac_streebog512_tv_template) 531562306a36Sopenharmony_ci } 531662306a36Sopenharmony_ci }, { 531762306a36Sopenharmony_ci .alg = "jitterentropy_rng", 531862306a36Sopenharmony_ci .fips_allowed = 1, 531962306a36Sopenharmony_ci .test = alg_test_null, 532062306a36Sopenharmony_ci }, { 532162306a36Sopenharmony_ci .alg = "kw(aes)", 532262306a36Sopenharmony_ci .test = alg_test_skcipher, 532362306a36Sopenharmony_ci .fips_allowed = 1, 532462306a36Sopenharmony_ci .suite = { 532562306a36Sopenharmony_ci .cipher = __VECS(aes_kw_tv_template) 532662306a36Sopenharmony_ci } 532762306a36Sopenharmony_ci }, { 532862306a36Sopenharmony_ci .alg = "lrw(aes)", 532962306a36Sopenharmony_ci .generic_driver = "lrw(ecb(aes-generic))", 533062306a36Sopenharmony_ci .test = alg_test_skcipher, 533162306a36Sopenharmony_ci .suite = { 533262306a36Sopenharmony_ci .cipher = __VECS(aes_lrw_tv_template) 533362306a36Sopenharmony_ci } 533462306a36Sopenharmony_ci }, { 533562306a36Sopenharmony_ci .alg = "lrw(camellia)", 533662306a36Sopenharmony_ci .generic_driver = "lrw(ecb(camellia-generic))", 533762306a36Sopenharmony_ci .test = alg_test_skcipher, 533862306a36Sopenharmony_ci .suite = { 533962306a36Sopenharmony_ci .cipher = __VECS(camellia_lrw_tv_template) 534062306a36Sopenharmony_ci } 534162306a36Sopenharmony_ci }, { 534262306a36Sopenharmony_ci .alg = "lrw(cast6)", 534362306a36Sopenharmony_ci .generic_driver = "lrw(ecb(cast6-generic))", 534462306a36Sopenharmony_ci .test = alg_test_skcipher, 534562306a36Sopenharmony_ci .suite = { 534662306a36Sopenharmony_ci .cipher = __VECS(cast6_lrw_tv_template) 534762306a36Sopenharmony_ci } 534862306a36Sopenharmony_ci }, { 534962306a36Sopenharmony_ci .alg = "lrw(serpent)", 535062306a36Sopenharmony_ci .generic_driver = "lrw(ecb(serpent-generic))", 535162306a36Sopenharmony_ci .test = alg_test_skcipher, 535262306a36Sopenharmony_ci .suite = { 535362306a36Sopenharmony_ci .cipher = __VECS(serpent_lrw_tv_template) 535462306a36Sopenharmony_ci } 535562306a36Sopenharmony_ci }, { 535662306a36Sopenharmony_ci .alg = "lrw(twofish)", 535762306a36Sopenharmony_ci .generic_driver = "lrw(ecb(twofish-generic))", 535862306a36Sopenharmony_ci .test = alg_test_skcipher, 535962306a36Sopenharmony_ci .suite = { 536062306a36Sopenharmony_ci .cipher = __VECS(tf_lrw_tv_template) 536162306a36Sopenharmony_ci } 536262306a36Sopenharmony_ci }, { 536362306a36Sopenharmony_ci .alg = "lz4", 536462306a36Sopenharmony_ci .test = alg_test_comp, 536562306a36Sopenharmony_ci .fips_allowed = 1, 536662306a36Sopenharmony_ci .suite = { 536762306a36Sopenharmony_ci .comp = { 536862306a36Sopenharmony_ci .comp = __VECS(lz4_comp_tv_template), 536962306a36Sopenharmony_ci .decomp = __VECS(lz4_decomp_tv_template) 537062306a36Sopenharmony_ci } 537162306a36Sopenharmony_ci } 537262306a36Sopenharmony_ci }, { 537362306a36Sopenharmony_ci .alg = "lz4hc", 537462306a36Sopenharmony_ci .test = alg_test_comp, 537562306a36Sopenharmony_ci .fips_allowed = 1, 537662306a36Sopenharmony_ci .suite = { 537762306a36Sopenharmony_ci .comp = { 537862306a36Sopenharmony_ci .comp = __VECS(lz4hc_comp_tv_template), 537962306a36Sopenharmony_ci .decomp = __VECS(lz4hc_decomp_tv_template) 538062306a36Sopenharmony_ci } 538162306a36Sopenharmony_ci } 538262306a36Sopenharmony_ci }, { 538362306a36Sopenharmony_ci .alg = "lzo", 538462306a36Sopenharmony_ci .test = alg_test_comp, 538562306a36Sopenharmony_ci .fips_allowed = 1, 538662306a36Sopenharmony_ci .suite = { 538762306a36Sopenharmony_ci .comp = { 538862306a36Sopenharmony_ci .comp = __VECS(lzo_comp_tv_template), 538962306a36Sopenharmony_ci .decomp = __VECS(lzo_decomp_tv_template) 539062306a36Sopenharmony_ci } 539162306a36Sopenharmony_ci } 539262306a36Sopenharmony_ci }, { 539362306a36Sopenharmony_ci .alg = "lzo-rle", 539462306a36Sopenharmony_ci .test = alg_test_comp, 539562306a36Sopenharmony_ci .fips_allowed = 1, 539662306a36Sopenharmony_ci .suite = { 539762306a36Sopenharmony_ci .comp = { 539862306a36Sopenharmony_ci .comp = __VECS(lzorle_comp_tv_template), 539962306a36Sopenharmony_ci .decomp = __VECS(lzorle_decomp_tv_template) 540062306a36Sopenharmony_ci } 540162306a36Sopenharmony_ci } 540262306a36Sopenharmony_ci }, { 540362306a36Sopenharmony_ci .alg = "md4", 540462306a36Sopenharmony_ci .test = alg_test_hash, 540562306a36Sopenharmony_ci .suite = { 540662306a36Sopenharmony_ci .hash = __VECS(md4_tv_template) 540762306a36Sopenharmony_ci } 540862306a36Sopenharmony_ci }, { 540962306a36Sopenharmony_ci .alg = "md5", 541062306a36Sopenharmony_ci .test = alg_test_hash, 541162306a36Sopenharmony_ci .suite = { 541262306a36Sopenharmony_ci .hash = __VECS(md5_tv_template) 541362306a36Sopenharmony_ci } 541462306a36Sopenharmony_ci }, { 541562306a36Sopenharmony_ci .alg = "michael_mic", 541662306a36Sopenharmony_ci .test = alg_test_hash, 541762306a36Sopenharmony_ci .suite = { 541862306a36Sopenharmony_ci .hash = __VECS(michael_mic_tv_template) 541962306a36Sopenharmony_ci } 542062306a36Sopenharmony_ci }, { 542162306a36Sopenharmony_ci .alg = "nhpoly1305", 542262306a36Sopenharmony_ci .test = alg_test_hash, 542362306a36Sopenharmony_ci .suite = { 542462306a36Sopenharmony_ci .hash = __VECS(nhpoly1305_tv_template) 542562306a36Sopenharmony_ci } 542662306a36Sopenharmony_ci }, { 542762306a36Sopenharmony_ci .alg = "ofb(aes)", 542862306a36Sopenharmony_ci .test = alg_test_skcipher, 542962306a36Sopenharmony_ci .fips_allowed = 1, 543062306a36Sopenharmony_ci .suite = { 543162306a36Sopenharmony_ci .cipher = __VECS(aes_ofb_tv_template) 543262306a36Sopenharmony_ci } 543362306a36Sopenharmony_ci }, { 543462306a36Sopenharmony_ci /* Same as ofb(aes) except the key is stored in 543562306a36Sopenharmony_ci * hardware secure memory which we reference by index 543662306a36Sopenharmony_ci */ 543762306a36Sopenharmony_ci .alg = "ofb(paes)", 543862306a36Sopenharmony_ci .test = alg_test_null, 543962306a36Sopenharmony_ci .fips_allowed = 1, 544062306a36Sopenharmony_ci }, { 544162306a36Sopenharmony_ci .alg = "ofb(sm4)", 544262306a36Sopenharmony_ci .test = alg_test_skcipher, 544362306a36Sopenharmony_ci .suite = { 544462306a36Sopenharmony_ci .cipher = __VECS(sm4_ofb_tv_template) 544562306a36Sopenharmony_ci } 544662306a36Sopenharmony_ci }, { 544762306a36Sopenharmony_ci .alg = "pcbc(fcrypt)", 544862306a36Sopenharmony_ci .test = alg_test_skcipher, 544962306a36Sopenharmony_ci .suite = { 545062306a36Sopenharmony_ci .cipher = __VECS(fcrypt_pcbc_tv_template) 545162306a36Sopenharmony_ci } 545262306a36Sopenharmony_ci }, { 545362306a36Sopenharmony_ci .alg = "pkcs1pad(rsa,sha224)", 545462306a36Sopenharmony_ci .test = alg_test_null, 545562306a36Sopenharmony_ci .fips_allowed = 1, 545662306a36Sopenharmony_ci }, { 545762306a36Sopenharmony_ci .alg = "pkcs1pad(rsa,sha256)", 545862306a36Sopenharmony_ci .test = alg_test_akcipher, 545962306a36Sopenharmony_ci .fips_allowed = 1, 546062306a36Sopenharmony_ci .suite = { 546162306a36Sopenharmony_ci .akcipher = __VECS(pkcs1pad_rsa_tv_template) 546262306a36Sopenharmony_ci } 546362306a36Sopenharmony_ci }, { 546462306a36Sopenharmony_ci .alg = "pkcs1pad(rsa,sha384)", 546562306a36Sopenharmony_ci .test = alg_test_null, 546662306a36Sopenharmony_ci .fips_allowed = 1, 546762306a36Sopenharmony_ci }, { 546862306a36Sopenharmony_ci .alg = "pkcs1pad(rsa,sha512)", 546962306a36Sopenharmony_ci .test = alg_test_null, 547062306a36Sopenharmony_ci .fips_allowed = 1, 547162306a36Sopenharmony_ci }, { 547262306a36Sopenharmony_ci .alg = "poly1305", 547362306a36Sopenharmony_ci .test = alg_test_hash, 547462306a36Sopenharmony_ci .suite = { 547562306a36Sopenharmony_ci .hash = __VECS(poly1305_tv_template) 547662306a36Sopenharmony_ci } 547762306a36Sopenharmony_ci }, { 547862306a36Sopenharmony_ci .alg = "polyval", 547962306a36Sopenharmony_ci .test = alg_test_hash, 548062306a36Sopenharmony_ci .suite = { 548162306a36Sopenharmony_ci .hash = __VECS(polyval_tv_template) 548262306a36Sopenharmony_ci } 548362306a36Sopenharmony_ci }, { 548462306a36Sopenharmony_ci .alg = "rfc3686(ctr(aes))", 548562306a36Sopenharmony_ci .test = alg_test_skcipher, 548662306a36Sopenharmony_ci .fips_allowed = 1, 548762306a36Sopenharmony_ci .suite = { 548862306a36Sopenharmony_ci .cipher = __VECS(aes_ctr_rfc3686_tv_template) 548962306a36Sopenharmony_ci } 549062306a36Sopenharmony_ci }, { 549162306a36Sopenharmony_ci .alg = "rfc3686(ctr(sm4))", 549262306a36Sopenharmony_ci .test = alg_test_skcipher, 549362306a36Sopenharmony_ci .suite = { 549462306a36Sopenharmony_ci .cipher = __VECS(sm4_ctr_rfc3686_tv_template) 549562306a36Sopenharmony_ci } 549662306a36Sopenharmony_ci }, { 549762306a36Sopenharmony_ci .alg = "rfc4106(gcm(aes))", 549862306a36Sopenharmony_ci .generic_driver = "rfc4106(gcm_base(ctr(aes-generic),ghash-generic))", 549962306a36Sopenharmony_ci .test = alg_test_aead, 550062306a36Sopenharmony_ci .fips_allowed = 1, 550162306a36Sopenharmony_ci .suite = { 550262306a36Sopenharmony_ci .aead = { 550362306a36Sopenharmony_ci ____VECS(aes_gcm_rfc4106_tv_template), 550462306a36Sopenharmony_ci .einval_allowed = 1, 550562306a36Sopenharmony_ci .aad_iv = 1, 550662306a36Sopenharmony_ci } 550762306a36Sopenharmony_ci } 550862306a36Sopenharmony_ci }, { 550962306a36Sopenharmony_ci .alg = "rfc4309(ccm(aes))", 551062306a36Sopenharmony_ci .generic_driver = "rfc4309(ccm_base(ctr(aes-generic),cbcmac(aes-generic)))", 551162306a36Sopenharmony_ci .test = alg_test_aead, 551262306a36Sopenharmony_ci .fips_allowed = 1, 551362306a36Sopenharmony_ci .suite = { 551462306a36Sopenharmony_ci .aead = { 551562306a36Sopenharmony_ci ____VECS(aes_ccm_rfc4309_tv_template), 551662306a36Sopenharmony_ci .einval_allowed = 1, 551762306a36Sopenharmony_ci .aad_iv = 1, 551862306a36Sopenharmony_ci } 551962306a36Sopenharmony_ci } 552062306a36Sopenharmony_ci }, { 552162306a36Sopenharmony_ci .alg = "rfc4543(gcm(aes))", 552262306a36Sopenharmony_ci .generic_driver = "rfc4543(gcm_base(ctr(aes-generic),ghash-generic))", 552362306a36Sopenharmony_ci .test = alg_test_aead, 552462306a36Sopenharmony_ci .suite = { 552562306a36Sopenharmony_ci .aead = { 552662306a36Sopenharmony_ci ____VECS(aes_gcm_rfc4543_tv_template), 552762306a36Sopenharmony_ci .einval_allowed = 1, 552862306a36Sopenharmony_ci .aad_iv = 1, 552962306a36Sopenharmony_ci } 553062306a36Sopenharmony_ci } 553162306a36Sopenharmony_ci }, { 553262306a36Sopenharmony_ci .alg = "rfc7539(chacha20,poly1305)", 553362306a36Sopenharmony_ci .test = alg_test_aead, 553462306a36Sopenharmony_ci .suite = { 553562306a36Sopenharmony_ci .aead = __VECS(rfc7539_tv_template) 553662306a36Sopenharmony_ci } 553762306a36Sopenharmony_ci }, { 553862306a36Sopenharmony_ci .alg = "rfc7539esp(chacha20,poly1305)", 553962306a36Sopenharmony_ci .test = alg_test_aead, 554062306a36Sopenharmony_ci .suite = { 554162306a36Sopenharmony_ci .aead = { 554262306a36Sopenharmony_ci ____VECS(rfc7539esp_tv_template), 554362306a36Sopenharmony_ci .einval_allowed = 1, 554462306a36Sopenharmony_ci .aad_iv = 1, 554562306a36Sopenharmony_ci } 554662306a36Sopenharmony_ci } 554762306a36Sopenharmony_ci }, { 554862306a36Sopenharmony_ci .alg = "rmd160", 554962306a36Sopenharmony_ci .test = alg_test_hash, 555062306a36Sopenharmony_ci .suite = { 555162306a36Sopenharmony_ci .hash = __VECS(rmd160_tv_template) 555262306a36Sopenharmony_ci } 555362306a36Sopenharmony_ci }, { 555462306a36Sopenharmony_ci .alg = "rsa", 555562306a36Sopenharmony_ci .test = alg_test_akcipher, 555662306a36Sopenharmony_ci .fips_allowed = 1, 555762306a36Sopenharmony_ci .suite = { 555862306a36Sopenharmony_ci .akcipher = __VECS(rsa_tv_template) 555962306a36Sopenharmony_ci } 556062306a36Sopenharmony_ci }, { 556162306a36Sopenharmony_ci .alg = "sha1", 556262306a36Sopenharmony_ci .test = alg_test_hash, 556362306a36Sopenharmony_ci .fips_allowed = 1, 556462306a36Sopenharmony_ci .suite = { 556562306a36Sopenharmony_ci .hash = __VECS(sha1_tv_template) 556662306a36Sopenharmony_ci } 556762306a36Sopenharmony_ci }, { 556862306a36Sopenharmony_ci .alg = "sha224", 556962306a36Sopenharmony_ci .test = alg_test_hash, 557062306a36Sopenharmony_ci .fips_allowed = 1, 557162306a36Sopenharmony_ci .suite = { 557262306a36Sopenharmony_ci .hash = __VECS(sha224_tv_template) 557362306a36Sopenharmony_ci } 557462306a36Sopenharmony_ci }, { 557562306a36Sopenharmony_ci .alg = "sha256", 557662306a36Sopenharmony_ci .test = alg_test_hash, 557762306a36Sopenharmony_ci .fips_allowed = 1, 557862306a36Sopenharmony_ci .suite = { 557962306a36Sopenharmony_ci .hash = __VECS(sha256_tv_template) 558062306a36Sopenharmony_ci } 558162306a36Sopenharmony_ci }, { 558262306a36Sopenharmony_ci .alg = "sha3-224", 558362306a36Sopenharmony_ci .test = alg_test_hash, 558462306a36Sopenharmony_ci .fips_allowed = 1, 558562306a36Sopenharmony_ci .suite = { 558662306a36Sopenharmony_ci .hash = __VECS(sha3_224_tv_template) 558762306a36Sopenharmony_ci } 558862306a36Sopenharmony_ci }, { 558962306a36Sopenharmony_ci .alg = "sha3-256", 559062306a36Sopenharmony_ci .test = alg_test_hash, 559162306a36Sopenharmony_ci .fips_allowed = 1, 559262306a36Sopenharmony_ci .suite = { 559362306a36Sopenharmony_ci .hash = __VECS(sha3_256_tv_template) 559462306a36Sopenharmony_ci } 559562306a36Sopenharmony_ci }, { 559662306a36Sopenharmony_ci .alg = "sha3-384", 559762306a36Sopenharmony_ci .test = alg_test_hash, 559862306a36Sopenharmony_ci .fips_allowed = 1, 559962306a36Sopenharmony_ci .suite = { 560062306a36Sopenharmony_ci .hash = __VECS(sha3_384_tv_template) 560162306a36Sopenharmony_ci } 560262306a36Sopenharmony_ci }, { 560362306a36Sopenharmony_ci .alg = "sha3-512", 560462306a36Sopenharmony_ci .test = alg_test_hash, 560562306a36Sopenharmony_ci .fips_allowed = 1, 560662306a36Sopenharmony_ci .suite = { 560762306a36Sopenharmony_ci .hash = __VECS(sha3_512_tv_template) 560862306a36Sopenharmony_ci } 560962306a36Sopenharmony_ci }, { 561062306a36Sopenharmony_ci .alg = "sha384", 561162306a36Sopenharmony_ci .test = alg_test_hash, 561262306a36Sopenharmony_ci .fips_allowed = 1, 561362306a36Sopenharmony_ci .suite = { 561462306a36Sopenharmony_ci .hash = __VECS(sha384_tv_template) 561562306a36Sopenharmony_ci } 561662306a36Sopenharmony_ci }, { 561762306a36Sopenharmony_ci .alg = "sha512", 561862306a36Sopenharmony_ci .test = alg_test_hash, 561962306a36Sopenharmony_ci .fips_allowed = 1, 562062306a36Sopenharmony_ci .suite = { 562162306a36Sopenharmony_ci .hash = __VECS(sha512_tv_template) 562262306a36Sopenharmony_ci } 562362306a36Sopenharmony_ci }, { 562462306a36Sopenharmony_ci .alg = "sm2", 562562306a36Sopenharmony_ci .test = alg_test_akcipher, 562662306a36Sopenharmony_ci .suite = { 562762306a36Sopenharmony_ci .akcipher = __VECS(sm2_tv_template) 562862306a36Sopenharmony_ci } 562962306a36Sopenharmony_ci }, { 563062306a36Sopenharmony_ci .alg = "sm3", 563162306a36Sopenharmony_ci .test = alg_test_hash, 563262306a36Sopenharmony_ci .suite = { 563362306a36Sopenharmony_ci .hash = __VECS(sm3_tv_template) 563462306a36Sopenharmony_ci } 563562306a36Sopenharmony_ci }, { 563662306a36Sopenharmony_ci .alg = "streebog256", 563762306a36Sopenharmony_ci .test = alg_test_hash, 563862306a36Sopenharmony_ci .suite = { 563962306a36Sopenharmony_ci .hash = __VECS(streebog256_tv_template) 564062306a36Sopenharmony_ci } 564162306a36Sopenharmony_ci }, { 564262306a36Sopenharmony_ci .alg = "streebog512", 564362306a36Sopenharmony_ci .test = alg_test_hash, 564462306a36Sopenharmony_ci .suite = { 564562306a36Sopenharmony_ci .hash = __VECS(streebog512_tv_template) 564662306a36Sopenharmony_ci } 564762306a36Sopenharmony_ci }, { 564862306a36Sopenharmony_ci .alg = "vmac64(aes)", 564962306a36Sopenharmony_ci .test = alg_test_hash, 565062306a36Sopenharmony_ci .suite = { 565162306a36Sopenharmony_ci .hash = __VECS(vmac64_aes_tv_template) 565262306a36Sopenharmony_ci } 565362306a36Sopenharmony_ci }, { 565462306a36Sopenharmony_ci .alg = "wp256", 565562306a36Sopenharmony_ci .test = alg_test_hash, 565662306a36Sopenharmony_ci .suite = { 565762306a36Sopenharmony_ci .hash = __VECS(wp256_tv_template) 565862306a36Sopenharmony_ci } 565962306a36Sopenharmony_ci }, { 566062306a36Sopenharmony_ci .alg = "wp384", 566162306a36Sopenharmony_ci .test = alg_test_hash, 566262306a36Sopenharmony_ci .suite = { 566362306a36Sopenharmony_ci .hash = __VECS(wp384_tv_template) 566462306a36Sopenharmony_ci } 566562306a36Sopenharmony_ci }, { 566662306a36Sopenharmony_ci .alg = "wp512", 566762306a36Sopenharmony_ci .test = alg_test_hash, 566862306a36Sopenharmony_ci .suite = { 566962306a36Sopenharmony_ci .hash = __VECS(wp512_tv_template) 567062306a36Sopenharmony_ci } 567162306a36Sopenharmony_ci }, { 567262306a36Sopenharmony_ci .alg = "xcbc(aes)", 567362306a36Sopenharmony_ci .test = alg_test_hash, 567462306a36Sopenharmony_ci .suite = { 567562306a36Sopenharmony_ci .hash = __VECS(aes_xcbc128_tv_template) 567662306a36Sopenharmony_ci } 567762306a36Sopenharmony_ci }, { 567862306a36Sopenharmony_ci .alg = "xcbc(sm4)", 567962306a36Sopenharmony_ci .test = alg_test_hash, 568062306a36Sopenharmony_ci .suite = { 568162306a36Sopenharmony_ci .hash = __VECS(sm4_xcbc128_tv_template) 568262306a36Sopenharmony_ci } 568362306a36Sopenharmony_ci }, { 568462306a36Sopenharmony_ci .alg = "xchacha12", 568562306a36Sopenharmony_ci .test = alg_test_skcipher, 568662306a36Sopenharmony_ci .suite = { 568762306a36Sopenharmony_ci .cipher = __VECS(xchacha12_tv_template) 568862306a36Sopenharmony_ci }, 568962306a36Sopenharmony_ci }, { 569062306a36Sopenharmony_ci .alg = "xchacha20", 569162306a36Sopenharmony_ci .test = alg_test_skcipher, 569262306a36Sopenharmony_ci .suite = { 569362306a36Sopenharmony_ci .cipher = __VECS(xchacha20_tv_template) 569462306a36Sopenharmony_ci }, 569562306a36Sopenharmony_ci }, { 569662306a36Sopenharmony_ci .alg = "xctr(aes)", 569762306a36Sopenharmony_ci .test = alg_test_skcipher, 569862306a36Sopenharmony_ci .suite = { 569962306a36Sopenharmony_ci .cipher = __VECS(aes_xctr_tv_template) 570062306a36Sopenharmony_ci } 570162306a36Sopenharmony_ci }, { 570262306a36Sopenharmony_ci .alg = "xts(aes)", 570362306a36Sopenharmony_ci .generic_driver = "xts(ecb(aes-generic))", 570462306a36Sopenharmony_ci .test = alg_test_skcipher, 570562306a36Sopenharmony_ci .fips_allowed = 1, 570662306a36Sopenharmony_ci .suite = { 570762306a36Sopenharmony_ci .cipher = __VECS(aes_xts_tv_template) 570862306a36Sopenharmony_ci } 570962306a36Sopenharmony_ci }, { 571062306a36Sopenharmony_ci .alg = "xts(camellia)", 571162306a36Sopenharmony_ci .generic_driver = "xts(ecb(camellia-generic))", 571262306a36Sopenharmony_ci .test = alg_test_skcipher, 571362306a36Sopenharmony_ci .suite = { 571462306a36Sopenharmony_ci .cipher = __VECS(camellia_xts_tv_template) 571562306a36Sopenharmony_ci } 571662306a36Sopenharmony_ci }, { 571762306a36Sopenharmony_ci .alg = "xts(cast6)", 571862306a36Sopenharmony_ci .generic_driver = "xts(ecb(cast6-generic))", 571962306a36Sopenharmony_ci .test = alg_test_skcipher, 572062306a36Sopenharmony_ci .suite = { 572162306a36Sopenharmony_ci .cipher = __VECS(cast6_xts_tv_template) 572262306a36Sopenharmony_ci } 572362306a36Sopenharmony_ci }, { 572462306a36Sopenharmony_ci /* Same as xts(aes) except the key is stored in 572562306a36Sopenharmony_ci * hardware secure memory which we reference by index 572662306a36Sopenharmony_ci */ 572762306a36Sopenharmony_ci .alg = "xts(paes)", 572862306a36Sopenharmony_ci .test = alg_test_null, 572962306a36Sopenharmony_ci .fips_allowed = 1, 573062306a36Sopenharmony_ci }, { 573162306a36Sopenharmony_ci .alg = "xts(serpent)", 573262306a36Sopenharmony_ci .generic_driver = "xts(ecb(serpent-generic))", 573362306a36Sopenharmony_ci .test = alg_test_skcipher, 573462306a36Sopenharmony_ci .suite = { 573562306a36Sopenharmony_ci .cipher = __VECS(serpent_xts_tv_template) 573662306a36Sopenharmony_ci } 573762306a36Sopenharmony_ci }, { 573862306a36Sopenharmony_ci .alg = "xts(sm4)", 573962306a36Sopenharmony_ci .generic_driver = "xts(ecb(sm4-generic))", 574062306a36Sopenharmony_ci .test = alg_test_skcipher, 574162306a36Sopenharmony_ci .suite = { 574262306a36Sopenharmony_ci .cipher = __VECS(sm4_xts_tv_template) 574362306a36Sopenharmony_ci } 574462306a36Sopenharmony_ci }, { 574562306a36Sopenharmony_ci .alg = "xts(twofish)", 574662306a36Sopenharmony_ci .generic_driver = "xts(ecb(twofish-generic))", 574762306a36Sopenharmony_ci .test = alg_test_skcipher, 574862306a36Sopenharmony_ci .suite = { 574962306a36Sopenharmony_ci .cipher = __VECS(tf_xts_tv_template) 575062306a36Sopenharmony_ci } 575162306a36Sopenharmony_ci }, { 575262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CRYPTO_PAES_S390) 575362306a36Sopenharmony_ci .alg = "xts-paes-s390", 575462306a36Sopenharmony_ci .fips_allowed = 1, 575562306a36Sopenharmony_ci .test = alg_test_skcipher, 575662306a36Sopenharmony_ci .suite = { 575762306a36Sopenharmony_ci .cipher = __VECS(aes_xts_tv_template) 575862306a36Sopenharmony_ci } 575962306a36Sopenharmony_ci }, { 576062306a36Sopenharmony_ci#endif 576162306a36Sopenharmony_ci .alg = "xts4096(paes)", 576262306a36Sopenharmony_ci .test = alg_test_null, 576362306a36Sopenharmony_ci .fips_allowed = 1, 576462306a36Sopenharmony_ci }, { 576562306a36Sopenharmony_ci .alg = "xts512(paes)", 576662306a36Sopenharmony_ci .test = alg_test_null, 576762306a36Sopenharmony_ci .fips_allowed = 1, 576862306a36Sopenharmony_ci }, { 576962306a36Sopenharmony_ci .alg = "xxhash64", 577062306a36Sopenharmony_ci .test = alg_test_hash, 577162306a36Sopenharmony_ci .fips_allowed = 1, 577262306a36Sopenharmony_ci .suite = { 577362306a36Sopenharmony_ci .hash = __VECS(xxhash64_tv_template) 577462306a36Sopenharmony_ci } 577562306a36Sopenharmony_ci }, { 577662306a36Sopenharmony_ci .alg = "zlib-deflate", 577762306a36Sopenharmony_ci .test = alg_test_comp, 577862306a36Sopenharmony_ci .fips_allowed = 1, 577962306a36Sopenharmony_ci .suite = { 578062306a36Sopenharmony_ci .comp = { 578162306a36Sopenharmony_ci .comp = __VECS(zlib_deflate_comp_tv_template), 578262306a36Sopenharmony_ci .decomp = __VECS(zlib_deflate_decomp_tv_template) 578362306a36Sopenharmony_ci } 578462306a36Sopenharmony_ci } 578562306a36Sopenharmony_ci }, { 578662306a36Sopenharmony_ci .alg = "zstd", 578762306a36Sopenharmony_ci .test = alg_test_comp, 578862306a36Sopenharmony_ci .fips_allowed = 1, 578962306a36Sopenharmony_ci .suite = { 579062306a36Sopenharmony_ci .comp = { 579162306a36Sopenharmony_ci .comp = __VECS(zstd_comp_tv_template), 579262306a36Sopenharmony_ci .decomp = __VECS(zstd_decomp_tv_template) 579362306a36Sopenharmony_ci } 579462306a36Sopenharmony_ci } 579562306a36Sopenharmony_ci } 579662306a36Sopenharmony_ci}; 579762306a36Sopenharmony_ci 579862306a36Sopenharmony_cistatic void alg_check_test_descs_order(void) 579962306a36Sopenharmony_ci{ 580062306a36Sopenharmony_ci int i; 580162306a36Sopenharmony_ci 580262306a36Sopenharmony_ci for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) { 580362306a36Sopenharmony_ci int diff = strcmp(alg_test_descs[i - 1].alg, 580462306a36Sopenharmony_ci alg_test_descs[i].alg); 580562306a36Sopenharmony_ci 580662306a36Sopenharmony_ci if (WARN_ON(diff > 0)) { 580762306a36Sopenharmony_ci pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n", 580862306a36Sopenharmony_ci alg_test_descs[i - 1].alg, 580962306a36Sopenharmony_ci alg_test_descs[i].alg); 581062306a36Sopenharmony_ci } 581162306a36Sopenharmony_ci 581262306a36Sopenharmony_ci if (WARN_ON(diff == 0)) { 581362306a36Sopenharmony_ci pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n", 581462306a36Sopenharmony_ci alg_test_descs[i].alg); 581562306a36Sopenharmony_ci } 581662306a36Sopenharmony_ci } 581762306a36Sopenharmony_ci} 581862306a36Sopenharmony_ci 581962306a36Sopenharmony_cistatic void alg_check_testvec_configs(void) 582062306a36Sopenharmony_ci{ 582162306a36Sopenharmony_ci int i; 582262306a36Sopenharmony_ci 582362306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) 582462306a36Sopenharmony_ci WARN_ON(!valid_testvec_config( 582562306a36Sopenharmony_ci &default_cipher_testvec_configs[i])); 582662306a36Sopenharmony_ci 582762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) 582862306a36Sopenharmony_ci WARN_ON(!valid_testvec_config( 582962306a36Sopenharmony_ci &default_hash_testvec_configs[i])); 583062306a36Sopenharmony_ci} 583162306a36Sopenharmony_ci 583262306a36Sopenharmony_cistatic void testmgr_onetime_init(void) 583362306a36Sopenharmony_ci{ 583462306a36Sopenharmony_ci alg_check_test_descs_order(); 583562306a36Sopenharmony_ci alg_check_testvec_configs(); 583662306a36Sopenharmony_ci 583762306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 583862306a36Sopenharmony_ci pr_warn("alg: extra crypto tests enabled. This is intended for developer use only.\n"); 583962306a36Sopenharmony_ci#endif 584062306a36Sopenharmony_ci} 584162306a36Sopenharmony_ci 584262306a36Sopenharmony_cistatic int alg_find_test(const char *alg) 584362306a36Sopenharmony_ci{ 584462306a36Sopenharmony_ci int start = 0; 584562306a36Sopenharmony_ci int end = ARRAY_SIZE(alg_test_descs); 584662306a36Sopenharmony_ci 584762306a36Sopenharmony_ci while (start < end) { 584862306a36Sopenharmony_ci int i = (start + end) / 2; 584962306a36Sopenharmony_ci int diff = strcmp(alg_test_descs[i].alg, alg); 585062306a36Sopenharmony_ci 585162306a36Sopenharmony_ci if (diff > 0) { 585262306a36Sopenharmony_ci end = i; 585362306a36Sopenharmony_ci continue; 585462306a36Sopenharmony_ci } 585562306a36Sopenharmony_ci 585662306a36Sopenharmony_ci if (diff < 0) { 585762306a36Sopenharmony_ci start = i + 1; 585862306a36Sopenharmony_ci continue; 585962306a36Sopenharmony_ci } 586062306a36Sopenharmony_ci 586162306a36Sopenharmony_ci return i; 586262306a36Sopenharmony_ci } 586362306a36Sopenharmony_ci 586462306a36Sopenharmony_ci return -1; 586562306a36Sopenharmony_ci} 586662306a36Sopenharmony_ci 586762306a36Sopenharmony_cistatic int alg_fips_disabled(const char *driver, const char *alg) 586862306a36Sopenharmony_ci{ 586962306a36Sopenharmony_ci pr_info("alg: %s (%s) is disabled due to FIPS\n", alg, driver); 587062306a36Sopenharmony_ci 587162306a36Sopenharmony_ci return -ECANCELED; 587262306a36Sopenharmony_ci} 587362306a36Sopenharmony_ci 587462306a36Sopenharmony_ciint alg_test(const char *driver, const char *alg, u32 type, u32 mask) 587562306a36Sopenharmony_ci{ 587662306a36Sopenharmony_ci int i; 587762306a36Sopenharmony_ci int j; 587862306a36Sopenharmony_ci int rc; 587962306a36Sopenharmony_ci 588062306a36Sopenharmony_ci if (!fips_enabled && notests) { 588162306a36Sopenharmony_ci printk_once(KERN_INFO "alg: self-tests disabled\n"); 588262306a36Sopenharmony_ci return 0; 588362306a36Sopenharmony_ci } 588462306a36Sopenharmony_ci 588562306a36Sopenharmony_ci DO_ONCE(testmgr_onetime_init); 588662306a36Sopenharmony_ci 588762306a36Sopenharmony_ci if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) { 588862306a36Sopenharmony_ci char nalg[CRYPTO_MAX_ALG_NAME]; 588962306a36Sopenharmony_ci 589062306a36Sopenharmony_ci if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >= 589162306a36Sopenharmony_ci sizeof(nalg)) 589262306a36Sopenharmony_ci return -ENAMETOOLONG; 589362306a36Sopenharmony_ci 589462306a36Sopenharmony_ci i = alg_find_test(nalg); 589562306a36Sopenharmony_ci if (i < 0) 589662306a36Sopenharmony_ci goto notest; 589762306a36Sopenharmony_ci 589862306a36Sopenharmony_ci if (fips_enabled && !alg_test_descs[i].fips_allowed) 589962306a36Sopenharmony_ci goto non_fips_alg; 590062306a36Sopenharmony_ci 590162306a36Sopenharmony_ci rc = alg_test_cipher(alg_test_descs + i, driver, type, mask); 590262306a36Sopenharmony_ci goto test_done; 590362306a36Sopenharmony_ci } 590462306a36Sopenharmony_ci 590562306a36Sopenharmony_ci i = alg_find_test(alg); 590662306a36Sopenharmony_ci j = alg_find_test(driver); 590762306a36Sopenharmony_ci if (i < 0 && j < 0) 590862306a36Sopenharmony_ci goto notest; 590962306a36Sopenharmony_ci 591062306a36Sopenharmony_ci if (fips_enabled) { 591162306a36Sopenharmony_ci if (j >= 0 && !alg_test_descs[j].fips_allowed) 591262306a36Sopenharmony_ci return -EINVAL; 591362306a36Sopenharmony_ci 591462306a36Sopenharmony_ci if (i >= 0 && !alg_test_descs[i].fips_allowed) 591562306a36Sopenharmony_ci goto non_fips_alg; 591662306a36Sopenharmony_ci } 591762306a36Sopenharmony_ci 591862306a36Sopenharmony_ci rc = 0; 591962306a36Sopenharmony_ci if (i >= 0) 592062306a36Sopenharmony_ci rc |= alg_test_descs[i].test(alg_test_descs + i, driver, 592162306a36Sopenharmony_ci type, mask); 592262306a36Sopenharmony_ci if (j >= 0 && j != i) 592362306a36Sopenharmony_ci rc |= alg_test_descs[j].test(alg_test_descs + j, driver, 592462306a36Sopenharmony_ci type, mask); 592562306a36Sopenharmony_ci 592662306a36Sopenharmony_citest_done: 592762306a36Sopenharmony_ci if (rc) { 592862306a36Sopenharmony_ci if (fips_enabled || panic_on_fail) { 592962306a36Sopenharmony_ci fips_fail_notify(); 593062306a36Sopenharmony_ci panic("alg: self-tests for %s (%s) failed in %s mode!\n", 593162306a36Sopenharmony_ci driver, alg, 593262306a36Sopenharmony_ci fips_enabled ? "fips" : "panic_on_fail"); 593362306a36Sopenharmony_ci } 593462306a36Sopenharmony_ci pr_warn("alg: self-tests for %s using %s failed (rc=%d)", 593562306a36Sopenharmony_ci alg, driver, rc); 593662306a36Sopenharmony_ci WARN(rc != -ENOENT, 593762306a36Sopenharmony_ci "alg: self-tests for %s using %s failed (rc=%d)", 593862306a36Sopenharmony_ci alg, driver, rc); 593962306a36Sopenharmony_ci } else { 594062306a36Sopenharmony_ci if (fips_enabled) 594162306a36Sopenharmony_ci pr_info("alg: self-tests for %s (%s) passed\n", 594262306a36Sopenharmony_ci driver, alg); 594362306a36Sopenharmony_ci } 594462306a36Sopenharmony_ci 594562306a36Sopenharmony_ci return rc; 594662306a36Sopenharmony_ci 594762306a36Sopenharmony_cinotest: 594862306a36Sopenharmony_ci printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); 594962306a36Sopenharmony_ci 595062306a36Sopenharmony_ci if (type & CRYPTO_ALG_FIPS_INTERNAL) 595162306a36Sopenharmony_ci return alg_fips_disabled(driver, alg); 595262306a36Sopenharmony_ci 595362306a36Sopenharmony_ci return 0; 595462306a36Sopenharmony_cinon_fips_alg: 595562306a36Sopenharmony_ci return alg_fips_disabled(driver, alg); 595662306a36Sopenharmony_ci} 595762306a36Sopenharmony_ci 595862306a36Sopenharmony_ci#endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */ 595962306a36Sopenharmony_ci 596062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(alg_test); 5961