1da7f033dSHerbert Xu /* 2da7f033dSHerbert Xu * Algorithm testing framework and tests. 3da7f033dSHerbert Xu * 4da7f033dSHerbert Xu * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 5da7f033dSHerbert Xu * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> 6da7f033dSHerbert Xu * Copyright (c) 2007 Nokia Siemens Networks 7da7f033dSHerbert Xu * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> 83f47a03dSEric Biggers * Copyright (c) 2019 Google LLC 9da7f033dSHerbert Xu * 1069435b94SAdrian Hoban * Updated RFC4106 AES-GCM testing. 1169435b94SAdrian Hoban * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) 1269435b94SAdrian Hoban * Adrian Hoban <adrian.hoban@intel.com> 1369435b94SAdrian Hoban * Gabriele Paoloni <gabriele.paoloni@intel.com> 1469435b94SAdrian Hoban * Tadeusz Struk (tadeusz.struk@intel.com) 1569435b94SAdrian Hoban * Copyright (c) 2010, Intel Corporation. 1669435b94SAdrian Hoban * 17da7f033dSHerbert Xu * This program is free software; you can redistribute it and/or modify it 18da7f033dSHerbert Xu * under the terms of the GNU General Public License as published by the Free 19da7f033dSHerbert Xu * Software Foundation; either version 2 of the License, or (at your option) 20da7f033dSHerbert Xu * any later version. 21da7f033dSHerbert Xu * 22da7f033dSHerbert Xu */ 23da7f033dSHerbert Xu 241ce33115SHerbert Xu #include <crypto/aead.h> 25da7f033dSHerbert Xu #include <crypto/hash.h> 2612773d93SHerbert Xu #include <crypto/skcipher.h> 27da7f033dSHerbert Xu #include <linux/err.h> 281c41b882SHerbert Xu #include <linux/fips.h> 29da7f033dSHerbert Xu #include <linux/module.h> 303f47a03dSEric Biggers #include <linux/once.h> 3125f9dddbSEric Biggers #include <linux/random.h> 32da7f033dSHerbert Xu #include <linux/scatterlist.h> 33da7f033dSHerbert Xu #include <linux/slab.h> 34da7f033dSHerbert Xu #include <linux/string.h> 357647d6ceSJarod Wilson #include <crypto/rng.h> 3664d1cdfbSStephan Mueller #include <crypto/drbg.h> 37946cc463STadeusz Struk #include <crypto/akcipher.h> 38802c7f1cSSalvatore Benedetto #include <crypto/kpp.h> 39d7db7a88SGiovanni Cabiddu #include <crypto/acompress.h> 40da7f033dSHerbert Xu 41da7f033dSHerbert Xu #include "internal.h" 420b767f96SAlexander Shishkin 439e5c9fe4SRichard W.M. Jones static bool notests; 449e5c9fe4SRichard W.M. Jones module_param(notests, bool, 0644); 459e5c9fe4SRichard W.M. Jones MODULE_PARM_DESC(notests, "disable crypto self-tests"); 469e5c9fe4SRichard W.M. Jones 475b2706a4SEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 485b2706a4SEric Biggers static bool noextratests; 495b2706a4SEric Biggers module_param(noextratests, bool, 0644); 505b2706a4SEric Biggers MODULE_PARM_DESC(noextratests, "disable expensive crypto self-tests"); 515b2706a4SEric Biggers 525b2706a4SEric Biggers static unsigned int fuzz_iterations = 100; 535b2706a4SEric Biggers module_param(fuzz_iterations, uint, 0644); 545b2706a4SEric Biggers MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); 555b2706a4SEric Biggers #endif 565b2706a4SEric Biggers 57326a6346SHerbert Xu #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS 580b767f96SAlexander Shishkin 590b767f96SAlexander Shishkin /* a perfect nop */ 600b767f96SAlexander Shishkin int alg_test(const char *driver, const char *alg, u32 type, u32 mask) 610b767f96SAlexander Shishkin { 620b767f96SAlexander Shishkin return 0; 630b767f96SAlexander Shishkin } 640b767f96SAlexander Shishkin 650b767f96SAlexander Shishkin #else 660b767f96SAlexander Shishkin 67da7f033dSHerbert Xu #include "testmgr.h" 68da7f033dSHerbert Xu 69da7f033dSHerbert Xu /* 70da7f033dSHerbert Xu * Need slab memory for testing (size in number of pages). 71da7f033dSHerbert Xu */ 72da7f033dSHerbert Xu #define XBUFSIZE 8 73da7f033dSHerbert Xu 74da7f033dSHerbert Xu /* 75da7f033dSHerbert Xu * Indexes into the xbuf to simulate cross-page access. 76da7f033dSHerbert Xu */ 77da7f033dSHerbert Xu #define IDX1 32 78da7f033dSHerbert Xu #define IDX2 32400 7904b46fbdSArd Biesheuvel #define IDX3 1511 80da7f033dSHerbert Xu #define IDX4 8193 81da7f033dSHerbert Xu #define IDX5 22222 82da7f033dSHerbert Xu #define IDX6 17101 83da7f033dSHerbert Xu #define IDX7 27333 84da7f033dSHerbert Xu #define IDX8 3000 85da7f033dSHerbert Xu 86da7f033dSHerbert Xu /* 87da7f033dSHerbert Xu * Used by test_cipher() 88da7f033dSHerbert Xu */ 89da7f033dSHerbert Xu #define ENCRYPT 1 90da7f033dSHerbert Xu #define DECRYPT 0 91da7f033dSHerbert Xu 92da7f033dSHerbert Xu struct aead_test_suite { 93b13b1e0cSEric Biggers const struct aead_testvec *vecs; 94da7f033dSHerbert Xu unsigned int count; 95da7f033dSHerbert Xu }; 96da7f033dSHerbert Xu 97da7f033dSHerbert Xu struct cipher_test_suite { 98b13b1e0cSEric Biggers const struct cipher_testvec *vecs; 99da7f033dSHerbert Xu unsigned int count; 100da7f033dSHerbert Xu }; 101da7f033dSHerbert Xu 102da7f033dSHerbert Xu struct comp_test_suite { 103da7f033dSHerbert Xu struct { 104b13b1e0cSEric Biggers const struct comp_testvec *vecs; 105da7f033dSHerbert Xu unsigned int count; 106da7f033dSHerbert Xu } comp, decomp; 107da7f033dSHerbert Xu }; 108da7f033dSHerbert Xu 109da7f033dSHerbert Xu struct hash_test_suite { 110b13b1e0cSEric Biggers const struct hash_testvec *vecs; 111da7f033dSHerbert Xu unsigned int count; 112da7f033dSHerbert Xu }; 113da7f033dSHerbert Xu 1147647d6ceSJarod Wilson struct cprng_test_suite { 115b13b1e0cSEric Biggers const struct cprng_testvec *vecs; 1167647d6ceSJarod Wilson unsigned int count; 1177647d6ceSJarod Wilson }; 1187647d6ceSJarod Wilson 11964d1cdfbSStephan Mueller struct drbg_test_suite { 120b13b1e0cSEric Biggers const struct drbg_testvec *vecs; 12164d1cdfbSStephan Mueller unsigned int count; 12264d1cdfbSStephan Mueller }; 12364d1cdfbSStephan Mueller 124946cc463STadeusz Struk struct akcipher_test_suite { 125b13b1e0cSEric Biggers const struct akcipher_testvec *vecs; 126946cc463STadeusz Struk unsigned int count; 127946cc463STadeusz Struk }; 128946cc463STadeusz Struk 129802c7f1cSSalvatore Benedetto struct kpp_test_suite { 130b13b1e0cSEric Biggers const struct kpp_testvec *vecs; 131802c7f1cSSalvatore Benedetto unsigned int count; 132802c7f1cSSalvatore Benedetto }; 133802c7f1cSSalvatore Benedetto 134da7f033dSHerbert Xu struct alg_test_desc { 135da7f033dSHerbert Xu const char *alg; 136da7f033dSHerbert Xu int (*test)(const struct alg_test_desc *desc, const char *driver, 137da7f033dSHerbert Xu u32 type, u32 mask); 138a1915d51SJarod Wilson int fips_allowed; /* set if alg is allowed in fips mode */ 139da7f033dSHerbert Xu 140da7f033dSHerbert Xu union { 141da7f033dSHerbert Xu struct aead_test_suite aead; 142da7f033dSHerbert Xu struct cipher_test_suite cipher; 143da7f033dSHerbert Xu struct comp_test_suite comp; 144da7f033dSHerbert Xu struct hash_test_suite hash; 1457647d6ceSJarod Wilson struct cprng_test_suite cprng; 14664d1cdfbSStephan Mueller struct drbg_test_suite drbg; 147946cc463STadeusz Struk struct akcipher_test_suite akcipher; 148802c7f1cSSalvatore Benedetto struct kpp_test_suite kpp; 149da7f033dSHerbert Xu } suite; 150da7f033dSHerbert Xu }; 151da7f033dSHerbert Xu 152b13b1e0cSEric Biggers static const unsigned int IDX[8] = { 153b13b1e0cSEric Biggers IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; 154da7f033dSHerbert Xu 155da7f033dSHerbert Xu static void hexdump(unsigned char *buf, unsigned int len) 156da7f033dSHerbert Xu { 157da7f033dSHerbert Xu print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, 158da7f033dSHerbert Xu 16, 1, 159da7f033dSHerbert Xu buf, len, false); 160da7f033dSHerbert Xu } 161da7f033dSHerbert Xu 1623f47a03dSEric Biggers static int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order) 163f8b0d4d0SHerbert Xu { 164f8b0d4d0SHerbert Xu int i; 165f8b0d4d0SHerbert Xu 166f8b0d4d0SHerbert Xu for (i = 0; i < XBUFSIZE; i++) { 1673f47a03dSEric Biggers buf[i] = (char *)__get_free_pages(GFP_KERNEL, order); 168f8b0d4d0SHerbert Xu if (!buf[i]) 169f8b0d4d0SHerbert Xu goto err_free_buf; 170f8b0d4d0SHerbert Xu } 171f8b0d4d0SHerbert Xu 172f8b0d4d0SHerbert Xu return 0; 173f8b0d4d0SHerbert Xu 174f8b0d4d0SHerbert Xu err_free_buf: 175f8b0d4d0SHerbert Xu while (i-- > 0) 1763f47a03dSEric Biggers free_pages((unsigned long)buf[i], order); 177f8b0d4d0SHerbert Xu 178f8b0d4d0SHerbert Xu return -ENOMEM; 179f8b0d4d0SHerbert Xu } 180f8b0d4d0SHerbert Xu 1813f47a03dSEric Biggers static int testmgr_alloc_buf(char *buf[XBUFSIZE]) 1823f47a03dSEric Biggers { 1833f47a03dSEric Biggers return __testmgr_alloc_buf(buf, 0); 1843f47a03dSEric Biggers } 1853f47a03dSEric Biggers 1863f47a03dSEric Biggers static void __testmgr_free_buf(char *buf[XBUFSIZE], int order) 187f8b0d4d0SHerbert Xu { 188f8b0d4d0SHerbert Xu int i; 189f8b0d4d0SHerbert Xu 190f8b0d4d0SHerbert Xu for (i = 0; i < XBUFSIZE; i++) 1913f47a03dSEric Biggers free_pages((unsigned long)buf[i], order); 1923f47a03dSEric Biggers } 1933f47a03dSEric Biggers 1943f47a03dSEric Biggers static void testmgr_free_buf(char *buf[XBUFSIZE]) 1953f47a03dSEric Biggers { 1963f47a03dSEric Biggers __testmgr_free_buf(buf, 0); 1973f47a03dSEric Biggers } 1983f47a03dSEric Biggers 1993f47a03dSEric Biggers #define TESTMGR_POISON_BYTE 0xfe 2003f47a03dSEric Biggers #define TESTMGR_POISON_LEN 16 2013f47a03dSEric Biggers 2023f47a03dSEric Biggers static inline void testmgr_poison(void *addr, size_t len) 2033f47a03dSEric Biggers { 2043f47a03dSEric Biggers memset(addr, TESTMGR_POISON_BYTE, len); 2053f47a03dSEric Biggers } 2063f47a03dSEric Biggers 2073f47a03dSEric Biggers /* Is the memory region still fully poisoned? */ 2083f47a03dSEric Biggers static inline bool testmgr_is_poison(const void *addr, size_t len) 2093f47a03dSEric Biggers { 2103f47a03dSEric Biggers return memchr_inv(addr, TESTMGR_POISON_BYTE, len) == NULL; 2113f47a03dSEric Biggers } 2123f47a03dSEric Biggers 2133f47a03dSEric Biggers /* flush type for hash algorithms */ 2143f47a03dSEric Biggers enum flush_type { 2153f47a03dSEric Biggers /* merge with update of previous buffer(s) */ 2163f47a03dSEric Biggers FLUSH_TYPE_NONE = 0, 2173f47a03dSEric Biggers 2183f47a03dSEric Biggers /* update with previous buffer(s) before doing this one */ 2193f47a03dSEric Biggers FLUSH_TYPE_FLUSH, 2203f47a03dSEric Biggers 2213f47a03dSEric Biggers /* likewise, but also export and re-import the intermediate state */ 2223f47a03dSEric Biggers FLUSH_TYPE_REIMPORT, 2233f47a03dSEric Biggers }; 2243f47a03dSEric Biggers 2253f47a03dSEric Biggers /* finalization function for hash algorithms */ 2263f47a03dSEric Biggers enum finalization_type { 2273f47a03dSEric Biggers FINALIZATION_TYPE_FINAL, /* use final() */ 2283f47a03dSEric Biggers FINALIZATION_TYPE_FINUP, /* use finup() */ 2293f47a03dSEric Biggers FINALIZATION_TYPE_DIGEST, /* use digest() */ 2303f47a03dSEric Biggers }; 2313f47a03dSEric Biggers 2323f47a03dSEric Biggers #define TEST_SG_TOTAL 10000 2333f47a03dSEric Biggers 2343f47a03dSEric Biggers /** 2353f47a03dSEric Biggers * struct test_sg_division - description of a scatterlist entry 2363f47a03dSEric Biggers * 2373f47a03dSEric Biggers * This struct describes one entry of a scatterlist being constructed to check a 2383f47a03dSEric Biggers * crypto test vector. 2393f47a03dSEric Biggers * 2403f47a03dSEric Biggers * @proportion_of_total: length of this chunk relative to the total length, 2413f47a03dSEric Biggers * given as a proportion out of TEST_SG_TOTAL so that it 2423f47a03dSEric Biggers * scales to fit any test vector 2433f47a03dSEric Biggers * @offset: byte offset into a 2-page buffer at which this chunk will start 2443f47a03dSEric Biggers * @offset_relative_to_alignmask: if true, add the algorithm's alignmask to the 2453f47a03dSEric Biggers * @offset 2463f47a03dSEric Biggers * @flush_type: for hashes, whether an update() should be done now vs. 2473f47a03dSEric Biggers * continuing to accumulate data 2483f47a03dSEric Biggers */ 2493f47a03dSEric Biggers struct test_sg_division { 2503f47a03dSEric Biggers unsigned int proportion_of_total; 2513f47a03dSEric Biggers unsigned int offset; 2523f47a03dSEric Biggers bool offset_relative_to_alignmask; 2533f47a03dSEric Biggers enum flush_type flush_type; 2543f47a03dSEric Biggers }; 2553f47a03dSEric Biggers 2563f47a03dSEric Biggers /** 2573f47a03dSEric Biggers * struct testvec_config - configuration for testing a crypto test vector 2583f47a03dSEric Biggers * 2593f47a03dSEric Biggers * This struct describes the data layout and other parameters with which each 2603f47a03dSEric Biggers * crypto test vector can be tested. 2613f47a03dSEric Biggers * 2623f47a03dSEric Biggers * @name: name of this config, logged for debugging purposes if a test fails 2633f47a03dSEric Biggers * @inplace: operate on the data in-place, if applicable for the algorithm type? 2643f47a03dSEric Biggers * @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP 2653f47a03dSEric Biggers * @src_divs: description of how to arrange the source scatterlist 2663f47a03dSEric Biggers * @dst_divs: description of how to arrange the dst scatterlist, if applicable 2673f47a03dSEric Biggers * for the algorithm type. Defaults to @src_divs if unset. 2683f47a03dSEric Biggers * @iv_offset: misalignment of the IV in the range [0..MAX_ALGAPI_ALIGNMASK+1], 2693f47a03dSEric Biggers * where 0 is aligned to a 2*(MAX_ALGAPI_ALIGNMASK+1) byte boundary 2703f47a03dSEric Biggers * @iv_offset_relative_to_alignmask: if true, add the algorithm's alignmask to 2713f47a03dSEric Biggers * the @iv_offset 2723f47a03dSEric Biggers * @finalization_type: what finalization function to use for hashes 2733f47a03dSEric Biggers */ 2743f47a03dSEric Biggers struct testvec_config { 2753f47a03dSEric Biggers const char *name; 2763f47a03dSEric Biggers bool inplace; 2773f47a03dSEric Biggers u32 req_flags; 2783f47a03dSEric Biggers struct test_sg_division src_divs[XBUFSIZE]; 2793f47a03dSEric Biggers struct test_sg_division dst_divs[XBUFSIZE]; 2803f47a03dSEric Biggers unsigned int iv_offset; 2813f47a03dSEric Biggers bool iv_offset_relative_to_alignmask; 2823f47a03dSEric Biggers enum finalization_type finalization_type; 2833f47a03dSEric Biggers }; 2843f47a03dSEric Biggers 2853f47a03dSEric Biggers #define TESTVEC_CONFIG_NAMELEN 192 2863f47a03dSEric Biggers 2874e7babbaSEric Biggers /* 2884e7babbaSEric Biggers * The following are the lists of testvec_configs to test for each algorithm 2894e7babbaSEric Biggers * type when the basic crypto self-tests are enabled, i.e. when 2904e7babbaSEric Biggers * CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is unset. They aim to provide good test 2914e7babbaSEric Biggers * coverage, while keeping the test time much shorter than the full fuzz tests 2924e7babbaSEric Biggers * so that the basic tests can be enabled in a wider range of circumstances. 2934e7babbaSEric Biggers */ 2944e7babbaSEric Biggers 2954e7babbaSEric Biggers /* Configs for skciphers and aeads */ 2964e7babbaSEric Biggers static const struct testvec_config default_cipher_testvec_configs[] = { 2974e7babbaSEric Biggers { 2984e7babbaSEric Biggers .name = "in-place", 2994e7babbaSEric Biggers .inplace = true, 3004e7babbaSEric Biggers .src_divs = { { .proportion_of_total = 10000 } }, 3014e7babbaSEric Biggers }, { 3024e7babbaSEric Biggers .name = "out-of-place", 3034e7babbaSEric Biggers .src_divs = { { .proportion_of_total = 10000 } }, 3044e7babbaSEric Biggers }, { 3054e7babbaSEric Biggers .name = "unaligned buffer, offset=1", 3064e7babbaSEric Biggers .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, 3074e7babbaSEric Biggers .iv_offset = 1, 3084e7babbaSEric Biggers }, { 3094e7babbaSEric Biggers .name = "buffer aligned only to alignmask", 3104e7babbaSEric Biggers .src_divs = { 3114e7babbaSEric Biggers { 3124e7babbaSEric Biggers .proportion_of_total = 10000, 3134e7babbaSEric Biggers .offset = 1, 3144e7babbaSEric Biggers .offset_relative_to_alignmask = true, 3154e7babbaSEric Biggers }, 3164e7babbaSEric Biggers }, 3174e7babbaSEric Biggers .iv_offset = 1, 3184e7babbaSEric Biggers .iv_offset_relative_to_alignmask = true, 3194e7babbaSEric Biggers }, { 3204e7babbaSEric Biggers .name = "two even aligned splits", 3214e7babbaSEric Biggers .src_divs = { 3224e7babbaSEric Biggers { .proportion_of_total = 5000 }, 3234e7babbaSEric Biggers { .proportion_of_total = 5000 }, 3244e7babbaSEric Biggers }, 3254e7babbaSEric Biggers }, { 3264e7babbaSEric Biggers .name = "uneven misaligned splits, may sleep", 3274e7babbaSEric Biggers .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, 3284e7babbaSEric Biggers .src_divs = { 3294e7babbaSEric Biggers { .proportion_of_total = 1900, .offset = 33 }, 3304e7babbaSEric Biggers { .proportion_of_total = 3300, .offset = 7 }, 3314e7babbaSEric Biggers { .proportion_of_total = 4800, .offset = 18 }, 3324e7babbaSEric Biggers }, 3334e7babbaSEric Biggers .iv_offset = 3, 3344e7babbaSEric Biggers }, { 3354e7babbaSEric Biggers .name = "misaligned splits crossing pages, inplace", 3364e7babbaSEric Biggers .inplace = true, 3374e7babbaSEric Biggers .src_divs = { 3384e7babbaSEric Biggers { 3394e7babbaSEric Biggers .proportion_of_total = 7500, 3404e7babbaSEric Biggers .offset = PAGE_SIZE - 32 3414e7babbaSEric Biggers }, { 3424e7babbaSEric Biggers .proportion_of_total = 2500, 3434e7babbaSEric Biggers .offset = PAGE_SIZE - 7 3444e7babbaSEric Biggers }, 3454e7babbaSEric Biggers }, 3464e7babbaSEric Biggers } 3474e7babbaSEric Biggers }; 3484e7babbaSEric Biggers 3493f47a03dSEric Biggers static unsigned int count_test_sg_divisions(const struct test_sg_division *divs) 3503f47a03dSEric Biggers { 3513f47a03dSEric Biggers unsigned int remaining = TEST_SG_TOTAL; 3523f47a03dSEric Biggers unsigned int ndivs = 0; 3533f47a03dSEric Biggers 3543f47a03dSEric Biggers do { 3553f47a03dSEric Biggers remaining -= divs[ndivs++].proportion_of_total; 3563f47a03dSEric Biggers } while (remaining); 3573f47a03dSEric Biggers 3583f47a03dSEric Biggers return ndivs; 3593f47a03dSEric Biggers } 3603f47a03dSEric Biggers 3613f47a03dSEric Biggers static bool valid_sg_divisions(const struct test_sg_division *divs, 3623f47a03dSEric Biggers unsigned int count, bool *any_flushes_ret) 3633f47a03dSEric Biggers { 3643f47a03dSEric Biggers unsigned int total = 0; 3653f47a03dSEric Biggers unsigned int i; 3663f47a03dSEric Biggers 3673f47a03dSEric Biggers for (i = 0; i < count && total != TEST_SG_TOTAL; i++) { 3683f47a03dSEric Biggers if (divs[i].proportion_of_total <= 0 || 3693f47a03dSEric Biggers divs[i].proportion_of_total > TEST_SG_TOTAL - total) 3703f47a03dSEric Biggers return false; 3713f47a03dSEric Biggers total += divs[i].proportion_of_total; 3723f47a03dSEric Biggers if (divs[i].flush_type != FLUSH_TYPE_NONE) 3733f47a03dSEric Biggers *any_flushes_ret = true; 3743f47a03dSEric Biggers } 3753f47a03dSEric Biggers return total == TEST_SG_TOTAL && 3763f47a03dSEric Biggers memchr_inv(&divs[i], 0, (count - i) * sizeof(divs[0])) == NULL; 3773f47a03dSEric Biggers } 3783f47a03dSEric Biggers 3793f47a03dSEric Biggers /* 3803f47a03dSEric Biggers * Check whether the given testvec_config is valid. This isn't strictly needed 3813f47a03dSEric Biggers * since every testvec_config should be valid, but check anyway so that people 3823f47a03dSEric Biggers * don't unknowingly add broken configs that don't do what they wanted. 3833f47a03dSEric Biggers */ 3843f47a03dSEric Biggers static bool valid_testvec_config(const struct testvec_config *cfg) 3853f47a03dSEric Biggers { 3863f47a03dSEric Biggers bool any_flushes = false; 3873f47a03dSEric Biggers 3883f47a03dSEric Biggers if (cfg->name == NULL) 3893f47a03dSEric Biggers return false; 3903f47a03dSEric Biggers 3913f47a03dSEric Biggers if (!valid_sg_divisions(cfg->src_divs, ARRAY_SIZE(cfg->src_divs), 3923f47a03dSEric Biggers &any_flushes)) 3933f47a03dSEric Biggers return false; 3943f47a03dSEric Biggers 3953f47a03dSEric Biggers if (cfg->dst_divs[0].proportion_of_total) { 3963f47a03dSEric Biggers if (!valid_sg_divisions(cfg->dst_divs, 3973f47a03dSEric Biggers ARRAY_SIZE(cfg->dst_divs), 3983f47a03dSEric Biggers &any_flushes)) 3993f47a03dSEric Biggers return false; 4003f47a03dSEric Biggers } else { 4013f47a03dSEric Biggers if (memchr_inv(cfg->dst_divs, 0, sizeof(cfg->dst_divs))) 4023f47a03dSEric Biggers return false; 4033f47a03dSEric Biggers /* defaults to dst_divs=src_divs */ 4043f47a03dSEric Biggers } 4053f47a03dSEric Biggers 4063f47a03dSEric Biggers if (cfg->iv_offset + 4073f47a03dSEric Biggers (cfg->iv_offset_relative_to_alignmask ? MAX_ALGAPI_ALIGNMASK : 0) > 4083f47a03dSEric Biggers MAX_ALGAPI_ALIGNMASK + 1) 4093f47a03dSEric Biggers return false; 4103f47a03dSEric Biggers 4113f47a03dSEric Biggers if (any_flushes && cfg->finalization_type == FINALIZATION_TYPE_DIGEST) 4123f47a03dSEric Biggers return false; 4133f47a03dSEric Biggers 4143f47a03dSEric Biggers return true; 4153f47a03dSEric Biggers } 4163f47a03dSEric Biggers 4173f47a03dSEric Biggers struct test_sglist { 4183f47a03dSEric Biggers char *bufs[XBUFSIZE]; 4193f47a03dSEric Biggers struct scatterlist sgl[XBUFSIZE]; 4203f47a03dSEric Biggers struct scatterlist sgl_saved[XBUFSIZE]; 4213f47a03dSEric Biggers struct scatterlist *sgl_ptr; 4223f47a03dSEric Biggers unsigned int nents; 4233f47a03dSEric Biggers }; 4243f47a03dSEric Biggers 4253f47a03dSEric Biggers static int init_test_sglist(struct test_sglist *tsgl) 4263f47a03dSEric Biggers { 4273f47a03dSEric Biggers return __testmgr_alloc_buf(tsgl->bufs, 1 /* two pages per buffer */); 4283f47a03dSEric Biggers } 4293f47a03dSEric Biggers 4303f47a03dSEric Biggers static void destroy_test_sglist(struct test_sglist *tsgl) 4313f47a03dSEric Biggers { 4323f47a03dSEric Biggers return __testmgr_free_buf(tsgl->bufs, 1 /* two pages per buffer */); 4333f47a03dSEric Biggers } 4343f47a03dSEric Biggers 4353f47a03dSEric Biggers /** 4363f47a03dSEric Biggers * build_test_sglist() - build a scatterlist for a crypto test 4373f47a03dSEric Biggers * 4383f47a03dSEric Biggers * @tsgl: the scatterlist to build. @tsgl->bufs[] contains an array of 2-page 4393f47a03dSEric Biggers * buffers which the scatterlist @tsgl->sgl[] will be made to point into. 4403f47a03dSEric Biggers * @divs: the layout specification on which the scatterlist will be based 4413f47a03dSEric Biggers * @alignmask: the algorithm's alignmask 4423f47a03dSEric Biggers * @total_len: the total length of the scatterlist to build in bytes 4433f47a03dSEric Biggers * @data: if non-NULL, the buffers will be filled with this data until it ends. 4443f47a03dSEric Biggers * Otherwise the buffers will be poisoned. In both cases, some bytes 4453f47a03dSEric Biggers * past the end of each buffer will be poisoned to help detect overruns. 4463f47a03dSEric Biggers * @out_divs: if non-NULL, the test_sg_division to which each scatterlist entry 4473f47a03dSEric Biggers * corresponds will be returned here. This will match @divs except 4483f47a03dSEric Biggers * that divisions resolving to a length of 0 are omitted as they are 4493f47a03dSEric Biggers * not included in the scatterlist. 4503f47a03dSEric Biggers * 4513f47a03dSEric Biggers * Return: 0 or a -errno value 4523f47a03dSEric Biggers */ 4533f47a03dSEric Biggers static int build_test_sglist(struct test_sglist *tsgl, 4543f47a03dSEric Biggers const struct test_sg_division *divs, 4553f47a03dSEric Biggers const unsigned int alignmask, 4563f47a03dSEric Biggers const unsigned int total_len, 4573f47a03dSEric Biggers struct iov_iter *data, 4583f47a03dSEric Biggers const struct test_sg_division *out_divs[XBUFSIZE]) 4593f47a03dSEric Biggers { 4603f47a03dSEric Biggers struct { 4613f47a03dSEric Biggers const struct test_sg_division *div; 4623f47a03dSEric Biggers size_t length; 4633f47a03dSEric Biggers } partitions[XBUFSIZE]; 4643f47a03dSEric Biggers const unsigned int ndivs = count_test_sg_divisions(divs); 4653f47a03dSEric Biggers unsigned int len_remaining = total_len; 4663f47a03dSEric Biggers unsigned int i; 4673f47a03dSEric Biggers 4683f47a03dSEric Biggers BUILD_BUG_ON(ARRAY_SIZE(partitions) != ARRAY_SIZE(tsgl->sgl)); 4693f47a03dSEric Biggers if (WARN_ON(ndivs > ARRAY_SIZE(partitions))) 4703f47a03dSEric Biggers return -EINVAL; 4713f47a03dSEric Biggers 4723f47a03dSEric Biggers /* Calculate the (div, length) pairs */ 4733f47a03dSEric Biggers tsgl->nents = 0; 4743f47a03dSEric Biggers for (i = 0; i < ndivs; i++) { 4753f47a03dSEric Biggers unsigned int len_this_sg = 4763f47a03dSEric Biggers min(len_remaining, 4773f47a03dSEric Biggers (total_len * divs[i].proportion_of_total + 4783f47a03dSEric Biggers TEST_SG_TOTAL / 2) / TEST_SG_TOTAL); 4793f47a03dSEric Biggers 4803f47a03dSEric Biggers if (len_this_sg != 0) { 4813f47a03dSEric Biggers partitions[tsgl->nents].div = &divs[i]; 4823f47a03dSEric Biggers partitions[tsgl->nents].length = len_this_sg; 4833f47a03dSEric Biggers tsgl->nents++; 4843f47a03dSEric Biggers len_remaining -= len_this_sg; 4853f47a03dSEric Biggers } 4863f47a03dSEric Biggers } 4873f47a03dSEric Biggers if (tsgl->nents == 0) { 4883f47a03dSEric Biggers partitions[tsgl->nents].div = &divs[0]; 4893f47a03dSEric Biggers partitions[tsgl->nents].length = 0; 4903f47a03dSEric Biggers tsgl->nents++; 4913f47a03dSEric Biggers } 4923f47a03dSEric Biggers partitions[tsgl->nents - 1].length += len_remaining; 4933f47a03dSEric Biggers 4943f47a03dSEric Biggers /* Set up the sgl entries and fill the data or poison */ 4953f47a03dSEric Biggers sg_init_table(tsgl->sgl, tsgl->nents); 4963f47a03dSEric Biggers for (i = 0; i < tsgl->nents; i++) { 4973f47a03dSEric Biggers unsigned int offset = partitions[i].div->offset; 4983f47a03dSEric Biggers void *addr; 4993f47a03dSEric Biggers 5003f47a03dSEric Biggers if (partitions[i].div->offset_relative_to_alignmask) 5013f47a03dSEric Biggers offset += alignmask; 5023f47a03dSEric Biggers 5033f47a03dSEric Biggers while (offset + partitions[i].length + TESTMGR_POISON_LEN > 5043f47a03dSEric Biggers 2 * PAGE_SIZE) { 5053f47a03dSEric Biggers if (WARN_ON(offset <= 0)) 5063f47a03dSEric Biggers return -EINVAL; 5073f47a03dSEric Biggers offset /= 2; 5083f47a03dSEric Biggers } 5093f47a03dSEric Biggers 5103f47a03dSEric Biggers addr = &tsgl->bufs[i][offset]; 5113f47a03dSEric Biggers sg_set_buf(&tsgl->sgl[i], addr, partitions[i].length); 5123f47a03dSEric Biggers 5133f47a03dSEric Biggers if (out_divs) 5143f47a03dSEric Biggers out_divs[i] = partitions[i].div; 5153f47a03dSEric Biggers 5163f47a03dSEric Biggers if (data) { 5173f47a03dSEric Biggers size_t copy_len, copied; 5183f47a03dSEric Biggers 5193f47a03dSEric Biggers copy_len = min(partitions[i].length, data->count); 5203f47a03dSEric Biggers copied = copy_from_iter(addr, copy_len, data); 5213f47a03dSEric Biggers if (WARN_ON(copied != copy_len)) 5223f47a03dSEric Biggers return -EINVAL; 5233f47a03dSEric Biggers testmgr_poison(addr + copy_len, partitions[i].length + 5243f47a03dSEric Biggers TESTMGR_POISON_LEN - copy_len); 5253f47a03dSEric Biggers } else { 5263f47a03dSEric Biggers testmgr_poison(addr, partitions[i].length + 5273f47a03dSEric Biggers TESTMGR_POISON_LEN); 5283f47a03dSEric Biggers } 5293f47a03dSEric Biggers } 5303f47a03dSEric Biggers 5313f47a03dSEric Biggers sg_mark_end(&tsgl->sgl[tsgl->nents - 1]); 5323f47a03dSEric Biggers tsgl->sgl_ptr = tsgl->sgl; 5333f47a03dSEric Biggers memcpy(tsgl->sgl_saved, tsgl->sgl, tsgl->nents * sizeof(tsgl->sgl[0])); 5343f47a03dSEric Biggers return 0; 5353f47a03dSEric Biggers } 5363f47a03dSEric Biggers 5373f47a03dSEric Biggers /* 5383f47a03dSEric Biggers * Verify that a scatterlist crypto operation produced the correct output. 5393f47a03dSEric Biggers * 5403f47a03dSEric Biggers * @tsgl: scatterlist containing the actual output 5413f47a03dSEric Biggers * @expected_output: buffer containing the expected output 5423f47a03dSEric Biggers * @len_to_check: length of @expected_output in bytes 5433f47a03dSEric Biggers * @unchecked_prefix_len: number of ignored bytes in @tsgl prior to real result 5443f47a03dSEric Biggers * @check_poison: verify that the poison bytes after each chunk are intact? 5453f47a03dSEric Biggers * 5463f47a03dSEric Biggers * Return: 0 if correct, -EINVAL if incorrect, -EOVERFLOW if buffer overrun. 5473f47a03dSEric Biggers */ 5483f47a03dSEric Biggers static int verify_correct_output(const struct test_sglist *tsgl, 5493f47a03dSEric Biggers const char *expected_output, 5503f47a03dSEric Biggers unsigned int len_to_check, 5513f47a03dSEric Biggers unsigned int unchecked_prefix_len, 5523f47a03dSEric Biggers bool check_poison) 5533f47a03dSEric Biggers { 5543f47a03dSEric Biggers unsigned int i; 5553f47a03dSEric Biggers 5563f47a03dSEric Biggers for (i = 0; i < tsgl->nents; i++) { 5573f47a03dSEric Biggers struct scatterlist *sg = &tsgl->sgl_ptr[i]; 5583f47a03dSEric Biggers unsigned int len = sg->length; 5593f47a03dSEric Biggers unsigned int offset = sg->offset; 5603f47a03dSEric Biggers const char *actual_output; 5613f47a03dSEric Biggers 5623f47a03dSEric Biggers if (unchecked_prefix_len) { 5633f47a03dSEric Biggers if (unchecked_prefix_len >= len) { 5643f47a03dSEric Biggers unchecked_prefix_len -= len; 5653f47a03dSEric Biggers continue; 5663f47a03dSEric Biggers } 5673f47a03dSEric Biggers offset += unchecked_prefix_len; 5683f47a03dSEric Biggers len -= unchecked_prefix_len; 5693f47a03dSEric Biggers unchecked_prefix_len = 0; 5703f47a03dSEric Biggers } 5713f47a03dSEric Biggers len = min(len, len_to_check); 5723f47a03dSEric Biggers actual_output = page_address(sg_page(sg)) + offset; 5733f47a03dSEric Biggers if (memcmp(expected_output, actual_output, len) != 0) 5743f47a03dSEric Biggers return -EINVAL; 5753f47a03dSEric Biggers if (check_poison && 5763f47a03dSEric Biggers !testmgr_is_poison(actual_output + len, TESTMGR_POISON_LEN)) 5773f47a03dSEric Biggers return -EOVERFLOW; 5783f47a03dSEric Biggers len_to_check -= len; 5793f47a03dSEric Biggers expected_output += len; 5803f47a03dSEric Biggers } 5813f47a03dSEric Biggers if (WARN_ON(len_to_check != 0)) 5823f47a03dSEric Biggers return -EINVAL; 5833f47a03dSEric Biggers return 0; 5843f47a03dSEric Biggers } 5853f47a03dSEric Biggers 5863f47a03dSEric Biggers static bool is_test_sglist_corrupted(const struct test_sglist *tsgl) 5873f47a03dSEric Biggers { 5883f47a03dSEric Biggers unsigned int i; 5893f47a03dSEric Biggers 5903f47a03dSEric Biggers for (i = 0; i < tsgl->nents; i++) { 5913f47a03dSEric Biggers if (tsgl->sgl[i].page_link != tsgl->sgl_saved[i].page_link) 5923f47a03dSEric Biggers return true; 5933f47a03dSEric Biggers if (tsgl->sgl[i].offset != tsgl->sgl_saved[i].offset) 5943f47a03dSEric Biggers return true; 5953f47a03dSEric Biggers if (tsgl->sgl[i].length != tsgl->sgl_saved[i].length) 5963f47a03dSEric Biggers return true; 5973f47a03dSEric Biggers } 5983f47a03dSEric Biggers return false; 5993f47a03dSEric Biggers } 6003f47a03dSEric Biggers 6013f47a03dSEric Biggers struct cipher_test_sglists { 6023f47a03dSEric Biggers struct test_sglist src; 6033f47a03dSEric Biggers struct test_sglist dst; 6043f47a03dSEric Biggers }; 6053f47a03dSEric Biggers 6063f47a03dSEric Biggers static struct cipher_test_sglists *alloc_cipher_test_sglists(void) 6073f47a03dSEric Biggers { 6083f47a03dSEric Biggers struct cipher_test_sglists *tsgls; 6093f47a03dSEric Biggers 6103f47a03dSEric Biggers tsgls = kmalloc(sizeof(*tsgls), GFP_KERNEL); 6113f47a03dSEric Biggers if (!tsgls) 6123f47a03dSEric Biggers return NULL; 6133f47a03dSEric Biggers 6143f47a03dSEric Biggers if (init_test_sglist(&tsgls->src) != 0) 6153f47a03dSEric Biggers goto fail_kfree; 6163f47a03dSEric Biggers if (init_test_sglist(&tsgls->dst) != 0) 6173f47a03dSEric Biggers goto fail_destroy_src; 6183f47a03dSEric Biggers 6193f47a03dSEric Biggers return tsgls; 6203f47a03dSEric Biggers 6213f47a03dSEric Biggers fail_destroy_src: 6223f47a03dSEric Biggers destroy_test_sglist(&tsgls->src); 6233f47a03dSEric Biggers fail_kfree: 6243f47a03dSEric Biggers kfree(tsgls); 6253f47a03dSEric Biggers return NULL; 6263f47a03dSEric Biggers } 6273f47a03dSEric Biggers 6283f47a03dSEric Biggers static void free_cipher_test_sglists(struct cipher_test_sglists *tsgls) 6293f47a03dSEric Biggers { 6303f47a03dSEric Biggers if (tsgls) { 6313f47a03dSEric Biggers destroy_test_sglist(&tsgls->src); 6323f47a03dSEric Biggers destroy_test_sglist(&tsgls->dst); 6333f47a03dSEric Biggers kfree(tsgls); 6343f47a03dSEric Biggers } 6353f47a03dSEric Biggers } 6363f47a03dSEric Biggers 6373f47a03dSEric Biggers /* Build the src and dst scatterlists for an skcipher or AEAD test */ 6383f47a03dSEric Biggers static int build_cipher_test_sglists(struct cipher_test_sglists *tsgls, 6393f47a03dSEric Biggers const struct testvec_config *cfg, 6403f47a03dSEric Biggers unsigned int alignmask, 6413f47a03dSEric Biggers unsigned int src_total_len, 6423f47a03dSEric Biggers unsigned int dst_total_len, 6433f47a03dSEric Biggers const struct kvec *inputs, 6443f47a03dSEric Biggers unsigned int nr_inputs) 6453f47a03dSEric Biggers { 6463f47a03dSEric Biggers struct iov_iter input; 6473f47a03dSEric Biggers int err; 6483f47a03dSEric Biggers 6493f47a03dSEric Biggers iov_iter_kvec(&input, WRITE, inputs, nr_inputs, src_total_len); 6503f47a03dSEric Biggers err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask, 6513f47a03dSEric Biggers cfg->inplace ? 6523f47a03dSEric Biggers max(dst_total_len, src_total_len) : 6533f47a03dSEric Biggers src_total_len, 6543f47a03dSEric Biggers &input, NULL); 6553f47a03dSEric Biggers if (err) 6563f47a03dSEric Biggers return err; 6573f47a03dSEric Biggers 6583f47a03dSEric Biggers if (cfg->inplace) { 6593f47a03dSEric Biggers tsgls->dst.sgl_ptr = tsgls->src.sgl; 6603f47a03dSEric Biggers tsgls->dst.nents = tsgls->src.nents; 6613f47a03dSEric Biggers return 0; 6623f47a03dSEric Biggers } 6633f47a03dSEric Biggers return build_test_sglist(&tsgls->dst, 6643f47a03dSEric Biggers cfg->dst_divs[0].proportion_of_total ? 6653f47a03dSEric Biggers cfg->dst_divs : cfg->src_divs, 6663f47a03dSEric Biggers alignmask, dst_total_len, NULL, NULL); 667f8b0d4d0SHerbert Xu } 668f8b0d4d0SHerbert Xu 66925f9dddbSEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 67025f9dddbSEric Biggers static char *generate_random_sgl_divisions(struct test_sg_division *divs, 67125f9dddbSEric Biggers size_t max_divs, char *p, char *end, 67225f9dddbSEric Biggers bool gen_flushes) 67325f9dddbSEric Biggers { 67425f9dddbSEric Biggers struct test_sg_division *div = divs; 67525f9dddbSEric Biggers unsigned int remaining = TEST_SG_TOTAL; 67625f9dddbSEric Biggers 67725f9dddbSEric Biggers do { 67825f9dddbSEric Biggers unsigned int this_len; 67925f9dddbSEric Biggers 68025f9dddbSEric Biggers if (div == &divs[max_divs - 1] || prandom_u32() % 2 == 0) 68125f9dddbSEric Biggers this_len = remaining; 68225f9dddbSEric Biggers else 68325f9dddbSEric Biggers this_len = 1 + (prandom_u32() % remaining); 68425f9dddbSEric Biggers div->proportion_of_total = this_len; 68525f9dddbSEric Biggers 68625f9dddbSEric Biggers if (prandom_u32() % 4 == 0) 68725f9dddbSEric Biggers div->offset = (PAGE_SIZE - 128) + (prandom_u32() % 128); 68825f9dddbSEric Biggers else if (prandom_u32() % 2 == 0) 68925f9dddbSEric Biggers div->offset = prandom_u32() % 32; 69025f9dddbSEric Biggers else 69125f9dddbSEric Biggers div->offset = prandom_u32() % PAGE_SIZE; 69225f9dddbSEric Biggers if (prandom_u32() % 8 == 0) 69325f9dddbSEric Biggers div->offset_relative_to_alignmask = true; 69425f9dddbSEric Biggers 69525f9dddbSEric Biggers div->flush_type = FLUSH_TYPE_NONE; 69625f9dddbSEric Biggers if (gen_flushes) { 69725f9dddbSEric Biggers switch (prandom_u32() % 4) { 69825f9dddbSEric Biggers case 0: 69925f9dddbSEric Biggers div->flush_type = FLUSH_TYPE_REIMPORT; 70025f9dddbSEric Biggers break; 70125f9dddbSEric Biggers case 1: 70225f9dddbSEric Biggers div->flush_type = FLUSH_TYPE_FLUSH; 70325f9dddbSEric Biggers break; 70425f9dddbSEric Biggers } 70525f9dddbSEric Biggers } 70625f9dddbSEric Biggers 70725f9dddbSEric Biggers BUILD_BUG_ON(TEST_SG_TOTAL != 10000); /* for "%u.%u%%" */ 70825f9dddbSEric Biggers p += scnprintf(p, end - p, "%s%u.%u%%@%s+%u%s", 70925f9dddbSEric Biggers div->flush_type == FLUSH_TYPE_NONE ? "" : 71025f9dddbSEric Biggers div->flush_type == FLUSH_TYPE_FLUSH ? 71125f9dddbSEric Biggers "<flush> " : "<reimport> ", 71225f9dddbSEric Biggers this_len / 100, this_len % 100, 71325f9dddbSEric Biggers div->offset_relative_to_alignmask ? 71425f9dddbSEric Biggers "alignmask" : "", 71525f9dddbSEric Biggers div->offset, this_len == remaining ? "" : ", "); 71625f9dddbSEric Biggers remaining -= this_len; 71725f9dddbSEric Biggers div++; 71825f9dddbSEric Biggers } while (remaining); 71925f9dddbSEric Biggers 72025f9dddbSEric Biggers return p; 72125f9dddbSEric Biggers } 72225f9dddbSEric Biggers 72325f9dddbSEric Biggers /* Generate a random testvec_config for fuzz testing */ 72425f9dddbSEric Biggers static void generate_random_testvec_config(struct testvec_config *cfg, 72525f9dddbSEric Biggers char *name, size_t max_namelen) 72625f9dddbSEric Biggers { 72725f9dddbSEric Biggers char *p = name; 72825f9dddbSEric Biggers char * const end = name + max_namelen; 72925f9dddbSEric Biggers 73025f9dddbSEric Biggers memset(cfg, 0, sizeof(*cfg)); 73125f9dddbSEric Biggers 73225f9dddbSEric Biggers cfg->name = name; 73325f9dddbSEric Biggers 73425f9dddbSEric Biggers p += scnprintf(p, end - p, "random:"); 73525f9dddbSEric Biggers 73625f9dddbSEric Biggers if (prandom_u32() % 2 == 0) { 73725f9dddbSEric Biggers cfg->inplace = true; 73825f9dddbSEric Biggers p += scnprintf(p, end - p, " inplace"); 73925f9dddbSEric Biggers } 74025f9dddbSEric Biggers 74125f9dddbSEric Biggers if (prandom_u32() % 2 == 0) { 74225f9dddbSEric Biggers cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP; 74325f9dddbSEric Biggers p += scnprintf(p, end - p, " may_sleep"); 74425f9dddbSEric Biggers } 74525f9dddbSEric Biggers 74625f9dddbSEric Biggers switch (prandom_u32() % 4) { 74725f9dddbSEric Biggers case 0: 74825f9dddbSEric Biggers cfg->finalization_type = FINALIZATION_TYPE_FINAL; 74925f9dddbSEric Biggers p += scnprintf(p, end - p, " use_final"); 75025f9dddbSEric Biggers break; 75125f9dddbSEric Biggers case 1: 75225f9dddbSEric Biggers cfg->finalization_type = FINALIZATION_TYPE_FINUP; 75325f9dddbSEric Biggers p += scnprintf(p, end - p, " use_finup"); 75425f9dddbSEric Biggers break; 75525f9dddbSEric Biggers default: 75625f9dddbSEric Biggers cfg->finalization_type = FINALIZATION_TYPE_DIGEST; 75725f9dddbSEric Biggers p += scnprintf(p, end - p, " use_digest"); 75825f9dddbSEric Biggers break; 75925f9dddbSEric Biggers } 76025f9dddbSEric Biggers 76125f9dddbSEric Biggers p += scnprintf(p, end - p, " src_divs=["); 76225f9dddbSEric Biggers p = generate_random_sgl_divisions(cfg->src_divs, 76325f9dddbSEric Biggers ARRAY_SIZE(cfg->src_divs), p, end, 76425f9dddbSEric Biggers (cfg->finalization_type != 76525f9dddbSEric Biggers FINALIZATION_TYPE_DIGEST)); 76625f9dddbSEric Biggers p += scnprintf(p, end - p, "]"); 76725f9dddbSEric Biggers 76825f9dddbSEric Biggers if (!cfg->inplace && prandom_u32() % 2 == 0) { 76925f9dddbSEric Biggers p += scnprintf(p, end - p, " dst_divs=["); 77025f9dddbSEric Biggers p = generate_random_sgl_divisions(cfg->dst_divs, 77125f9dddbSEric Biggers ARRAY_SIZE(cfg->dst_divs), 77225f9dddbSEric Biggers p, end, false); 77325f9dddbSEric Biggers p += scnprintf(p, end - p, "]"); 77425f9dddbSEric Biggers } 77525f9dddbSEric Biggers 77625f9dddbSEric Biggers if (prandom_u32() % 2 == 0) { 77725f9dddbSEric Biggers cfg->iv_offset = 1 + (prandom_u32() % MAX_ALGAPI_ALIGNMASK); 77825f9dddbSEric Biggers p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset); 77925f9dddbSEric Biggers } 78025f9dddbSEric Biggers 78125f9dddbSEric Biggers WARN_ON_ONCE(!valid_testvec_config(cfg)); 78225f9dddbSEric Biggers } 78325f9dddbSEric Biggers #endif /* CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 78425f9dddbSEric Biggers 785466d7b9fSKamil Konieczny static int ahash_guard_result(char *result, char c, int size) 786466d7b9fSKamil Konieczny { 787466d7b9fSKamil Konieczny int i; 788466d7b9fSKamil Konieczny 789466d7b9fSKamil Konieczny for (i = 0; i < size; i++) { 790466d7b9fSKamil Konieczny if (result[i] != c) 791466d7b9fSKamil Konieczny return -EINVAL; 792466d7b9fSKamil Konieczny } 793466d7b9fSKamil Konieczny 794466d7b9fSKamil Konieczny return 0; 795466d7b9fSKamil Konieczny } 796466d7b9fSKamil Konieczny 797018ba95cSWang, Rui Y static int ahash_partial_update(struct ahash_request **preq, 798b13b1e0cSEric Biggers struct crypto_ahash *tfm, const struct hash_testvec *template, 799018ba95cSWang, Rui Y void *hash_buff, int k, int temp, struct scatterlist *sg, 8007f397136SGilad Ben-Yossef const char *algo, char *result, struct crypto_wait *wait) 801018ba95cSWang, Rui Y { 802018ba95cSWang, Rui Y char *state; 803018ba95cSWang, Rui Y struct ahash_request *req; 804018ba95cSWang, Rui Y int statesize, ret = -EINVAL; 805da1729ceSJoey Pabalinas static const unsigned char guard[] = { 0x00, 0xba, 0xad, 0x00 }; 806466d7b9fSKamil Konieczny int digestsize = crypto_ahash_digestsize(tfm); 807018ba95cSWang, Rui Y 808018ba95cSWang, Rui Y req = *preq; 809018ba95cSWang, Rui Y statesize = crypto_ahash_statesize( 810018ba95cSWang, Rui Y crypto_ahash_reqtfm(req)); 8117bcb87bcSJan Stancek state = kmalloc(statesize + sizeof(guard), GFP_KERNEL); 812018ba95cSWang, Rui Y if (!state) { 813cf3f9609SGilad Ben-Yossef pr_err("alg: hash: Failed to alloc state for %s\n", algo); 814018ba95cSWang, Rui Y goto out_nostate; 815018ba95cSWang, Rui Y } 8167bcb87bcSJan Stancek memcpy(state + statesize, guard, sizeof(guard)); 817466d7b9fSKamil Konieczny memset(result, 1, digestsize); 818018ba95cSWang, Rui Y ret = crypto_ahash_export(req, state); 8197bcb87bcSJan Stancek WARN_ON(memcmp(state + statesize, guard, sizeof(guard))); 820018ba95cSWang, Rui Y if (ret) { 821cf3f9609SGilad Ben-Yossef pr_err("alg: hash: Failed to export() for %s\n", algo); 822018ba95cSWang, Rui Y goto out; 823018ba95cSWang, Rui Y } 824466d7b9fSKamil Konieczny ret = ahash_guard_result(result, 1, digestsize); 825466d7b9fSKamil Konieczny if (ret) { 826466d7b9fSKamil Konieczny pr_err("alg: hash: Failed, export used req->result for %s\n", 827466d7b9fSKamil Konieczny algo); 828466d7b9fSKamil Konieczny goto out; 829466d7b9fSKamil Konieczny } 830018ba95cSWang, Rui Y ahash_request_free(req); 831018ba95cSWang, Rui Y req = ahash_request_alloc(tfm, GFP_KERNEL); 832018ba95cSWang, Rui Y if (!req) { 833018ba95cSWang, Rui Y pr_err("alg: hash: Failed to alloc request for %s\n", algo); 834018ba95cSWang, Rui Y goto out_noreq; 835018ba95cSWang, Rui Y } 836018ba95cSWang, Rui Y ahash_request_set_callback(req, 837018ba95cSWang, Rui Y CRYPTO_TFM_REQ_MAY_BACKLOG, 8387f397136SGilad Ben-Yossef crypto_req_done, wait); 839018ba95cSWang, Rui Y 840018ba95cSWang, Rui Y memcpy(hash_buff, template->plaintext + temp, 841018ba95cSWang, Rui Y template->tap[k]); 842018ba95cSWang, Rui Y sg_init_one(&sg[0], hash_buff, template->tap[k]); 843018ba95cSWang, Rui Y ahash_request_set_crypt(req, sg, result, template->tap[k]); 844018ba95cSWang, Rui Y ret = crypto_ahash_import(req, state); 845018ba95cSWang, Rui Y if (ret) { 846018ba95cSWang, Rui Y pr_err("alg: hash: Failed to import() for %s\n", algo); 847018ba95cSWang, Rui Y goto out; 848018ba95cSWang, Rui Y } 849466d7b9fSKamil Konieczny ret = ahash_guard_result(result, 1, digestsize); 850466d7b9fSKamil Konieczny if (ret) { 851466d7b9fSKamil Konieczny pr_err("alg: hash: Failed, import used req->result for %s\n", 852466d7b9fSKamil Konieczny algo); 853466d7b9fSKamil Konieczny goto out; 854466d7b9fSKamil Konieczny } 8557f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_update(req), wait); 856018ba95cSWang, Rui Y if (ret) 857018ba95cSWang, Rui Y goto out; 858018ba95cSWang, Rui Y *preq = req; 859018ba95cSWang, Rui Y ret = 0; 860018ba95cSWang, Rui Y goto out_noreq; 861018ba95cSWang, Rui Y out: 862018ba95cSWang, Rui Y ahash_request_free(req); 863018ba95cSWang, Rui Y out_noreq: 864018ba95cSWang, Rui Y kfree(state); 865018ba95cSWang, Rui Y out_nostate: 866018ba95cSWang, Rui Y return ret; 867018ba95cSWang, Rui Y } 868018ba95cSWang, Rui Y 86976715095SGilad Ben-Yossef enum hash_test { 87076715095SGilad Ben-Yossef HASH_TEST_DIGEST, 87176715095SGilad Ben-Yossef HASH_TEST_FINAL, 87276715095SGilad Ben-Yossef HASH_TEST_FINUP 87376715095SGilad Ben-Yossef }; 87476715095SGilad Ben-Yossef 875b13b1e0cSEric Biggers static int __test_hash(struct crypto_ahash *tfm, 876b13b1e0cSEric Biggers const struct hash_testvec *template, unsigned int tcount, 87776715095SGilad Ben-Yossef enum hash_test test_type, const int align_offset) 878da7f033dSHerbert Xu { 879da7f033dSHerbert Xu const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm)); 880e93acd6fSAndrew Lutomirski size_t digest_size = crypto_ahash_digestsize(tfm); 881da7f033dSHerbert Xu unsigned int i, j, k, temp; 882da7f033dSHerbert Xu struct scatterlist sg[8]; 88329b77e5dSHoria Geanta char *result; 88429b77e5dSHoria Geanta char *key; 885da7f033dSHerbert Xu struct ahash_request *req; 8867f397136SGilad Ben-Yossef struct crypto_wait wait; 887da7f033dSHerbert Xu void *hash_buff; 888f8b0d4d0SHerbert Xu char *xbuf[XBUFSIZE]; 889f8b0d4d0SHerbert Xu int ret = -ENOMEM; 890f8b0d4d0SHerbert Xu 891e93acd6fSAndrew Lutomirski result = kmalloc(digest_size, GFP_KERNEL); 89229b77e5dSHoria Geanta if (!result) 89329b77e5dSHoria Geanta return ret; 89429b77e5dSHoria Geanta key = kmalloc(MAX_KEYLEN, GFP_KERNEL); 89529b77e5dSHoria Geanta if (!key) 89629b77e5dSHoria Geanta goto out_nobuf; 897f8b0d4d0SHerbert Xu if (testmgr_alloc_buf(xbuf)) 898f8b0d4d0SHerbert Xu goto out_nobuf; 899da7f033dSHerbert Xu 9007f397136SGilad Ben-Yossef crypto_init_wait(&wait); 901da7f033dSHerbert Xu 902da7f033dSHerbert Xu req = ahash_request_alloc(tfm, GFP_KERNEL); 903da7f033dSHerbert Xu if (!req) { 904da7f033dSHerbert Xu printk(KERN_ERR "alg: hash: Failed to allocate request for " 905da7f033dSHerbert Xu "%s\n", algo); 906da7f033dSHerbert Xu goto out_noreq; 907da7f033dSHerbert Xu } 908da7f033dSHerbert Xu ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 9097f397136SGilad Ben-Yossef crypto_req_done, &wait); 910da7f033dSHerbert Xu 911a0cfae59SHerbert Xu j = 0; 912da7f033dSHerbert Xu for (i = 0; i < tcount; i++) { 913a0cfae59SHerbert Xu if (template[i].np) 914a0cfae59SHerbert Xu continue; 915a0cfae59SHerbert Xu 916da5ffe11SJussi Kivilinna ret = -EINVAL; 917da5ffe11SJussi Kivilinna if (WARN_ON(align_offset + template[i].psize > PAGE_SIZE)) 918da5ffe11SJussi Kivilinna goto out; 919da5ffe11SJussi Kivilinna 920a0cfae59SHerbert Xu j++; 921e93acd6fSAndrew Lutomirski memset(result, 0, digest_size); 922da7f033dSHerbert Xu 923da7f033dSHerbert Xu hash_buff = xbuf[0]; 924da5ffe11SJussi Kivilinna hash_buff += align_offset; 925da7f033dSHerbert Xu 926da7f033dSHerbert Xu memcpy(hash_buff, template[i].plaintext, template[i].psize); 927da7f033dSHerbert Xu sg_init_one(&sg[0], hash_buff, template[i].psize); 928da7f033dSHerbert Xu 929da7f033dSHerbert Xu if (template[i].ksize) { 930da7f033dSHerbert Xu crypto_ahash_clear_flags(tfm, ~0); 93129b77e5dSHoria Geanta if (template[i].ksize > MAX_KEYLEN) { 93229b77e5dSHoria Geanta pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", 93329b77e5dSHoria Geanta j, algo, template[i].ksize, MAX_KEYLEN); 93429b77e5dSHoria Geanta ret = -EINVAL; 93529b77e5dSHoria Geanta goto out; 93629b77e5dSHoria Geanta } 93729b77e5dSHoria Geanta memcpy(key, template[i].key, template[i].ksize); 93829b77e5dSHoria Geanta ret = crypto_ahash_setkey(tfm, key, template[i].ksize); 939da7f033dSHerbert Xu if (ret) { 940da7f033dSHerbert Xu printk(KERN_ERR "alg: hash: setkey failed on " 941a0cfae59SHerbert Xu "test %d for %s: ret=%d\n", j, algo, 942da7f033dSHerbert Xu -ret); 943da7f033dSHerbert Xu goto out; 944da7f033dSHerbert Xu } 945da7f033dSHerbert Xu } 946da7f033dSHerbert Xu 947da7f033dSHerbert Xu ahash_request_set_crypt(req, sg, result, template[i].psize); 94876715095SGilad Ben-Yossef switch (test_type) { 94976715095SGilad Ben-Yossef case HASH_TEST_DIGEST: 9507f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_digest(req), &wait); 951a8f1a052SDavid S. Miller if (ret) { 952a8f1a052SDavid S. Miller pr_err("alg: hash: digest failed on test %d " 953a0cfae59SHerbert Xu "for %s: ret=%d\n", j, algo, -ret); 954da7f033dSHerbert Xu goto out; 955da7f033dSHerbert Xu } 95676715095SGilad Ben-Yossef break; 95776715095SGilad Ben-Yossef 95876715095SGilad Ben-Yossef case HASH_TEST_FINAL: 959466d7b9fSKamil Konieczny memset(result, 1, digest_size); 9607f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_init(req), &wait); 961a8f1a052SDavid S. Miller if (ret) { 962cf3f9609SGilad Ben-Yossef pr_err("alg: hash: init failed on test %d " 963a8f1a052SDavid S. Miller "for %s: ret=%d\n", j, algo, -ret); 964a8f1a052SDavid S. Miller goto out; 965a8f1a052SDavid S. Miller } 966466d7b9fSKamil Konieczny ret = ahash_guard_result(result, 1, digest_size); 967466d7b9fSKamil Konieczny if (ret) { 968466d7b9fSKamil Konieczny pr_err("alg: hash: init failed on test %d " 969466d7b9fSKamil Konieczny "for %s: used req->result\n", j, algo); 970466d7b9fSKamil Konieczny goto out; 971466d7b9fSKamil Konieczny } 9727f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_update(req), &wait); 973a8f1a052SDavid S. Miller if (ret) { 974cf3f9609SGilad Ben-Yossef pr_err("alg: hash: update failed on test %d " 975a8f1a052SDavid S. Miller "for %s: ret=%d\n", j, algo, -ret); 976a8f1a052SDavid S. Miller goto out; 977a8f1a052SDavid S. Miller } 978466d7b9fSKamil Konieczny ret = ahash_guard_result(result, 1, digest_size); 979466d7b9fSKamil Konieczny if (ret) { 980466d7b9fSKamil Konieczny pr_err("alg: hash: update failed on test %d " 981466d7b9fSKamil Konieczny "for %s: used req->result\n", j, algo); 982466d7b9fSKamil Konieczny goto out; 983466d7b9fSKamil Konieczny } 9847f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_final(req), &wait); 985a8f1a052SDavid S. Miller if (ret) { 986cf3f9609SGilad Ben-Yossef pr_err("alg: hash: final failed on test %d " 987a8f1a052SDavid S. Miller "for %s: ret=%d\n", j, algo, -ret); 988a8f1a052SDavid S. Miller goto out; 989a8f1a052SDavid S. Miller } 99076715095SGilad Ben-Yossef break; 99176715095SGilad Ben-Yossef 99276715095SGilad Ben-Yossef case HASH_TEST_FINUP: 99376715095SGilad Ben-Yossef memset(result, 1, digest_size); 99476715095SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_init(req), &wait); 99576715095SGilad Ben-Yossef if (ret) { 99676715095SGilad Ben-Yossef pr_err("alg: hash: init failed on test %d " 99776715095SGilad Ben-Yossef "for %s: ret=%d\n", j, algo, -ret); 99876715095SGilad Ben-Yossef goto out; 99976715095SGilad Ben-Yossef } 100076715095SGilad Ben-Yossef ret = ahash_guard_result(result, 1, digest_size); 100176715095SGilad Ben-Yossef if (ret) { 100276715095SGilad Ben-Yossef pr_err("alg: hash: init failed on test %d " 100376715095SGilad Ben-Yossef "for %s: used req->result\n", j, algo); 100476715095SGilad Ben-Yossef goto out; 100576715095SGilad Ben-Yossef } 100676715095SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_finup(req), &wait); 100776715095SGilad Ben-Yossef if (ret) { 100876715095SGilad Ben-Yossef pr_err("alg: hash: final failed on test %d " 100976715095SGilad Ben-Yossef "for %s: ret=%d\n", j, algo, -ret); 101076715095SGilad Ben-Yossef goto out; 101176715095SGilad Ben-Yossef } 101276715095SGilad Ben-Yossef break; 1013a8f1a052SDavid S. Miller } 1014da7f033dSHerbert Xu 1015da7f033dSHerbert Xu if (memcmp(result, template[i].digest, 1016da7f033dSHerbert Xu crypto_ahash_digestsize(tfm))) { 1017da7f033dSHerbert Xu printk(KERN_ERR "alg: hash: Test %d failed for %s\n", 1018a0cfae59SHerbert Xu j, algo); 1019da7f033dSHerbert Xu hexdump(result, crypto_ahash_digestsize(tfm)); 1020da7f033dSHerbert Xu ret = -EINVAL; 1021da7f033dSHerbert Xu goto out; 1022da7f033dSHerbert Xu } 1023da7f033dSHerbert Xu } 1024da7f033dSHerbert Xu 102576715095SGilad Ben-Yossef if (test_type) 102676715095SGilad Ben-Yossef goto out; 102776715095SGilad Ben-Yossef 1028da7f033dSHerbert Xu j = 0; 1029da7f033dSHerbert Xu for (i = 0; i < tcount; i++) { 1030da5ffe11SJussi Kivilinna /* alignment tests are only done with continuous buffers */ 1031da5ffe11SJussi Kivilinna if (align_offset != 0) 1032da5ffe11SJussi Kivilinna break; 1033da5ffe11SJussi Kivilinna 10345f2b424eSCristian Stoica if (!template[i].np) 10355f2b424eSCristian Stoica continue; 10365f2b424eSCristian Stoica 1037da7f033dSHerbert Xu j++; 1038e93acd6fSAndrew Lutomirski memset(result, 0, digest_size); 1039da7f033dSHerbert Xu 1040da7f033dSHerbert Xu temp = 0; 1041da7f033dSHerbert Xu sg_init_table(sg, template[i].np); 1042fd57f22aSHerbert Xu ret = -EINVAL; 1043da7f033dSHerbert Xu for (k = 0; k < template[i].np; k++) { 1044fd57f22aSHerbert Xu if (WARN_ON(offset_in_page(IDX[k]) + 1045fd57f22aSHerbert Xu template[i].tap[k] > PAGE_SIZE)) 1046fd57f22aSHerbert Xu goto out; 1047da7f033dSHerbert Xu sg_set_buf(&sg[k], 1048da7f033dSHerbert Xu memcpy(xbuf[IDX[k] >> PAGE_SHIFT] + 1049da7f033dSHerbert Xu offset_in_page(IDX[k]), 1050da7f033dSHerbert Xu template[i].plaintext + temp, 1051da7f033dSHerbert Xu template[i].tap[k]), 1052da7f033dSHerbert Xu template[i].tap[k]); 1053da7f033dSHerbert Xu temp += template[i].tap[k]; 1054da7f033dSHerbert Xu } 1055da7f033dSHerbert Xu 1056da7f033dSHerbert Xu if (template[i].ksize) { 105729b77e5dSHoria Geanta if (template[i].ksize > MAX_KEYLEN) { 105829b77e5dSHoria Geanta pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", 10595f2b424eSCristian Stoica j, algo, template[i].ksize, MAX_KEYLEN); 106029b77e5dSHoria Geanta ret = -EINVAL; 106129b77e5dSHoria Geanta goto out; 106229b77e5dSHoria Geanta } 1063da7f033dSHerbert Xu crypto_ahash_clear_flags(tfm, ~0); 106429b77e5dSHoria Geanta memcpy(key, template[i].key, template[i].ksize); 10655f2b424eSCristian Stoica ret = crypto_ahash_setkey(tfm, key, template[i].ksize); 1066da7f033dSHerbert Xu 1067da7f033dSHerbert Xu if (ret) { 1068da7f033dSHerbert Xu printk(KERN_ERR "alg: hash: setkey " 1069da7f033dSHerbert Xu "failed on chunking test %d " 10705f2b424eSCristian Stoica "for %s: ret=%d\n", j, algo, -ret); 1071da7f033dSHerbert Xu goto out; 1072da7f033dSHerbert Xu } 1073da7f033dSHerbert Xu } 1074da7f033dSHerbert Xu 10755f2b424eSCristian Stoica ahash_request_set_crypt(req, sg, result, template[i].psize); 10767f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_digest(req), &wait); 10777f397136SGilad Ben-Yossef if (ret) { 10787f397136SGilad Ben-Yossef pr_err("alg: hash: digest failed on chunking test %d for %s: ret=%d\n", 10797f397136SGilad Ben-Yossef j, algo, -ret); 1080da7f033dSHerbert Xu goto out; 1081da7f033dSHerbert Xu } 1082da7f033dSHerbert Xu 1083da7f033dSHerbert Xu if (memcmp(result, template[i].digest, 1084da7f033dSHerbert Xu crypto_ahash_digestsize(tfm))) { 1085da7f033dSHerbert Xu printk(KERN_ERR "alg: hash: Chunking test %d " 1086da7f033dSHerbert Xu "failed for %s\n", j, algo); 1087da7f033dSHerbert Xu hexdump(result, crypto_ahash_digestsize(tfm)); 1088da7f033dSHerbert Xu ret = -EINVAL; 1089da7f033dSHerbert Xu goto out; 1090da7f033dSHerbert Xu } 1091da7f033dSHerbert Xu } 1092da7f033dSHerbert Xu 1093018ba95cSWang, Rui Y /* partial update exercise */ 1094018ba95cSWang, Rui Y j = 0; 1095018ba95cSWang, Rui Y for (i = 0; i < tcount; i++) { 1096018ba95cSWang, Rui Y /* alignment tests are only done with continuous buffers */ 1097018ba95cSWang, Rui Y if (align_offset != 0) 1098018ba95cSWang, Rui Y break; 1099018ba95cSWang, Rui Y 1100018ba95cSWang, Rui Y if (template[i].np < 2) 1101018ba95cSWang, Rui Y continue; 1102018ba95cSWang, Rui Y 1103018ba95cSWang, Rui Y j++; 1104e93acd6fSAndrew Lutomirski memset(result, 0, digest_size); 1105018ba95cSWang, Rui Y 1106018ba95cSWang, Rui Y ret = -EINVAL; 1107018ba95cSWang, Rui Y hash_buff = xbuf[0]; 1108018ba95cSWang, Rui Y memcpy(hash_buff, template[i].plaintext, 1109018ba95cSWang, Rui Y template[i].tap[0]); 1110018ba95cSWang, Rui Y sg_init_one(&sg[0], hash_buff, template[i].tap[0]); 1111018ba95cSWang, Rui Y 1112018ba95cSWang, Rui Y if (template[i].ksize) { 1113018ba95cSWang, Rui Y crypto_ahash_clear_flags(tfm, ~0); 1114018ba95cSWang, Rui Y if (template[i].ksize > MAX_KEYLEN) { 1115018ba95cSWang, Rui Y pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n", 1116018ba95cSWang, Rui Y j, algo, template[i].ksize, MAX_KEYLEN); 1117018ba95cSWang, Rui Y ret = -EINVAL; 1118018ba95cSWang, Rui Y goto out; 1119018ba95cSWang, Rui Y } 1120018ba95cSWang, Rui Y memcpy(key, template[i].key, template[i].ksize); 1121018ba95cSWang, Rui Y ret = crypto_ahash_setkey(tfm, key, template[i].ksize); 1122018ba95cSWang, Rui Y if (ret) { 1123018ba95cSWang, Rui Y pr_err("alg: hash: setkey failed on test %d for %s: ret=%d\n", 1124018ba95cSWang, Rui Y j, algo, -ret); 1125018ba95cSWang, Rui Y goto out; 1126018ba95cSWang, Rui Y } 1127018ba95cSWang, Rui Y } 1128018ba95cSWang, Rui Y 1129018ba95cSWang, Rui Y ahash_request_set_crypt(req, sg, result, template[i].tap[0]); 11307f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_init(req), &wait); 1131018ba95cSWang, Rui Y if (ret) { 1132cf3f9609SGilad Ben-Yossef pr_err("alg: hash: init failed on test %d for %s: ret=%d\n", 1133018ba95cSWang, Rui Y j, algo, -ret); 1134018ba95cSWang, Rui Y goto out; 1135018ba95cSWang, Rui Y } 11367f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_update(req), &wait); 1137018ba95cSWang, Rui Y if (ret) { 1138cf3f9609SGilad Ben-Yossef pr_err("alg: hash: update failed on test %d for %s: ret=%d\n", 1139018ba95cSWang, Rui Y j, algo, -ret); 1140018ba95cSWang, Rui Y goto out; 1141018ba95cSWang, Rui Y } 1142018ba95cSWang, Rui Y 1143018ba95cSWang, Rui Y temp = template[i].tap[0]; 1144018ba95cSWang, Rui Y for (k = 1; k < template[i].np; k++) { 1145018ba95cSWang, Rui Y ret = ahash_partial_update(&req, tfm, &template[i], 1146018ba95cSWang, Rui Y hash_buff, k, temp, &sg[0], algo, result, 11477f397136SGilad Ben-Yossef &wait); 1148018ba95cSWang, Rui Y if (ret) { 1149cf3f9609SGilad Ben-Yossef pr_err("alg: hash: partial update failed on test %d for %s: ret=%d\n", 1150018ba95cSWang, Rui Y j, algo, -ret); 1151018ba95cSWang, Rui Y goto out_noreq; 1152018ba95cSWang, Rui Y } 1153018ba95cSWang, Rui Y temp += template[i].tap[k]; 1154018ba95cSWang, Rui Y } 11557f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_ahash_final(req), &wait); 1156018ba95cSWang, Rui Y if (ret) { 1157cf3f9609SGilad Ben-Yossef pr_err("alg: hash: final failed on test %d for %s: ret=%d\n", 1158018ba95cSWang, Rui Y j, algo, -ret); 1159018ba95cSWang, Rui Y goto out; 1160018ba95cSWang, Rui Y } 1161018ba95cSWang, Rui Y if (memcmp(result, template[i].digest, 1162018ba95cSWang, Rui Y crypto_ahash_digestsize(tfm))) { 1163018ba95cSWang, Rui Y pr_err("alg: hash: Partial Test %d failed for %s\n", 1164018ba95cSWang, Rui Y j, algo); 1165018ba95cSWang, Rui Y hexdump(result, crypto_ahash_digestsize(tfm)); 1166018ba95cSWang, Rui Y ret = -EINVAL; 1167018ba95cSWang, Rui Y goto out; 1168018ba95cSWang, Rui Y } 1169018ba95cSWang, Rui Y } 1170018ba95cSWang, Rui Y 1171da7f033dSHerbert Xu ret = 0; 1172da7f033dSHerbert Xu 1173da7f033dSHerbert Xu out: 1174da7f033dSHerbert Xu ahash_request_free(req); 1175da7f033dSHerbert Xu out_noreq: 1176f8b0d4d0SHerbert Xu testmgr_free_buf(xbuf); 1177f8b0d4d0SHerbert Xu out_nobuf: 117829b77e5dSHoria Geanta kfree(key); 117929b77e5dSHoria Geanta kfree(result); 1180da7f033dSHerbert Xu return ret; 1181da7f033dSHerbert Xu } 1182da7f033dSHerbert Xu 1183b13b1e0cSEric Biggers static int test_hash(struct crypto_ahash *tfm, 1184b13b1e0cSEric Biggers const struct hash_testvec *template, 118576715095SGilad Ben-Yossef unsigned int tcount, enum hash_test test_type) 1186da5ffe11SJussi Kivilinna { 1187da5ffe11SJussi Kivilinna unsigned int alignmask; 1188da5ffe11SJussi Kivilinna int ret; 1189da5ffe11SJussi Kivilinna 119076715095SGilad Ben-Yossef ret = __test_hash(tfm, template, tcount, test_type, 0); 1191da5ffe11SJussi Kivilinna if (ret) 1192da5ffe11SJussi Kivilinna return ret; 1193da5ffe11SJussi Kivilinna 1194da5ffe11SJussi Kivilinna /* test unaligned buffers, check with one byte offset */ 119576715095SGilad Ben-Yossef ret = __test_hash(tfm, template, tcount, test_type, 1); 1196da5ffe11SJussi Kivilinna if (ret) 1197da5ffe11SJussi Kivilinna return ret; 1198da5ffe11SJussi Kivilinna 1199da5ffe11SJussi Kivilinna alignmask = crypto_tfm_alg_alignmask(&tfm->base); 1200da5ffe11SJussi Kivilinna if (alignmask) { 1201da5ffe11SJussi Kivilinna /* Check if alignment mask for tfm is correctly set. */ 120276715095SGilad Ben-Yossef ret = __test_hash(tfm, template, tcount, test_type, 1203da5ffe11SJussi Kivilinna alignmask + 1); 1204da5ffe11SJussi Kivilinna if (ret) 1205da5ffe11SJussi Kivilinna return ret; 1206da5ffe11SJussi Kivilinna } 1207da5ffe11SJussi Kivilinna 1208da5ffe11SJussi Kivilinna return 0; 1209da5ffe11SJussi Kivilinna } 1210da5ffe11SJussi Kivilinna 1211d8a32ac2SJussi Kivilinna static int __test_aead(struct crypto_aead *tfm, int enc, 1212b13b1e0cSEric Biggers const struct aead_testvec *template, unsigned int tcount, 121358dcf548SJussi Kivilinna const bool diff_dst, const int align_offset) 1214da7f033dSHerbert Xu { 1215da7f033dSHerbert Xu const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); 1216da7f033dSHerbert Xu unsigned int i, j, k, n, temp; 1217f8b0d4d0SHerbert Xu int ret = -ENOMEM; 1218da7f033dSHerbert Xu char *q; 1219da7f033dSHerbert Xu char *key; 1220da7f033dSHerbert Xu struct aead_request *req; 1221d8a32ac2SJussi Kivilinna struct scatterlist *sg; 1222d8a32ac2SJussi Kivilinna struct scatterlist *sgout; 1223d8a32ac2SJussi Kivilinna const char *e, *d; 12247f397136SGilad Ben-Yossef struct crypto_wait wait; 1225424a5da6SCristian Stoica unsigned int authsize, iv_len; 12269bac019dSTadeusz Struk char *iv; 1227f8b0d4d0SHerbert Xu char *xbuf[XBUFSIZE]; 1228d8a32ac2SJussi Kivilinna char *xoutbuf[XBUFSIZE]; 1229f8b0d4d0SHerbert Xu char *axbuf[XBUFSIZE]; 1230f8b0d4d0SHerbert Xu 12319bac019dSTadeusz Struk iv = kzalloc(MAX_IVLEN, GFP_KERNEL); 12329bac019dSTadeusz Struk if (!iv) 12339bac019dSTadeusz Struk return ret; 123429b77e5dSHoria Geanta key = kmalloc(MAX_KEYLEN, GFP_KERNEL); 123529b77e5dSHoria Geanta if (!key) 123629b77e5dSHoria Geanta goto out_noxbuf; 1237f8b0d4d0SHerbert Xu if (testmgr_alloc_buf(xbuf)) 1238f8b0d4d0SHerbert Xu goto out_noxbuf; 1239f8b0d4d0SHerbert Xu if (testmgr_alloc_buf(axbuf)) 1240f8b0d4d0SHerbert Xu goto out_noaxbuf; 1241d8a32ac2SJussi Kivilinna if (diff_dst && testmgr_alloc_buf(xoutbuf)) 1242d8a32ac2SJussi Kivilinna goto out_nooutbuf; 1243d8a32ac2SJussi Kivilinna 1244d8a32ac2SJussi Kivilinna /* avoid "the frame size is larger than 1024 bytes" compiler warning */ 12456da2ec56SKees Cook sg = kmalloc(array3_size(sizeof(*sg), 8, (diff_dst ? 4 : 2)), 12466da2ec56SKees Cook GFP_KERNEL); 1247d8a32ac2SJussi Kivilinna if (!sg) 1248d8a32ac2SJussi Kivilinna goto out_nosg; 12498a525fcdSHerbert Xu sgout = &sg[16]; 1250d8a32ac2SJussi Kivilinna 1251d8a32ac2SJussi Kivilinna if (diff_dst) 1252d8a32ac2SJussi Kivilinna d = "-ddst"; 1253d8a32ac2SJussi Kivilinna else 1254d8a32ac2SJussi Kivilinna d = ""; 1255d8a32ac2SJussi Kivilinna 1256da7f033dSHerbert Xu if (enc == ENCRYPT) 1257da7f033dSHerbert Xu e = "encryption"; 1258da7f033dSHerbert Xu else 1259da7f033dSHerbert Xu e = "decryption"; 1260da7f033dSHerbert Xu 12617f397136SGilad Ben-Yossef crypto_init_wait(&wait); 1262da7f033dSHerbert Xu 1263da7f033dSHerbert Xu req = aead_request_alloc(tfm, GFP_KERNEL); 1264da7f033dSHerbert Xu if (!req) { 1265d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: Failed to allocate request for %s\n", 1266d8a32ac2SJussi Kivilinna d, algo); 1267da7f033dSHerbert Xu goto out; 1268da7f033dSHerbert Xu } 1269da7f033dSHerbert Xu 1270da7f033dSHerbert Xu aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 12717f397136SGilad Ben-Yossef crypto_req_done, &wait); 1272da7f033dSHerbert Xu 1273abfa7f43SJerome Marchand iv_len = crypto_aead_ivsize(tfm); 1274abfa7f43SJerome Marchand 1275da7f033dSHerbert Xu for (i = 0, j = 0; i < tcount; i++) { 1276a0d608eeSEric Biggers const char *input, *expected_output; 1277a0d608eeSEric Biggers unsigned int inlen, outlen; 1278a0d608eeSEric Biggers char *inbuf, *outbuf, *assocbuf; 1279a0d608eeSEric Biggers 128005b1d338SCristian Stoica if (template[i].np) 128105b1d338SCristian Stoica continue; 1282a0d608eeSEric Biggers if (enc) { 1283a0d608eeSEric Biggers if (template[i].novrfy) 12845bc3de58SEric Biggers continue; 1285a0d608eeSEric Biggers input = template[i].ptext; 1286a0d608eeSEric Biggers inlen = template[i].plen; 1287a0d608eeSEric Biggers expected_output = template[i].ctext; 1288a0d608eeSEric Biggers outlen = template[i].clen; 1289a0d608eeSEric Biggers } else { 1290a0d608eeSEric Biggers input = template[i].ctext; 1291a0d608eeSEric Biggers inlen = template[i].clen; 1292a0d608eeSEric Biggers expected_output = template[i].ptext; 1293a0d608eeSEric Biggers outlen = template[i].plen; 1294a0d608eeSEric Biggers } 129505b1d338SCristian Stoica 1296da7f033dSHerbert Xu j++; 1297da7f033dSHerbert Xu 129858dcf548SJussi Kivilinna /* some templates have no input data but they will 1299da7f033dSHerbert Xu * touch input 1300da7f033dSHerbert Xu */ 1301a0d608eeSEric Biggers inbuf = xbuf[0] + align_offset; 1302a0d608eeSEric Biggers assocbuf = axbuf[0]; 1303da7f033dSHerbert Xu 1304fd57f22aSHerbert Xu ret = -EINVAL; 1305a0d608eeSEric Biggers if (WARN_ON(align_offset + template[i].clen > PAGE_SIZE || 1306a0d608eeSEric Biggers template[i].alen > PAGE_SIZE)) 1307fd57f22aSHerbert Xu goto out; 1308fd57f22aSHerbert Xu 1309a0d608eeSEric Biggers memcpy(inbuf, input, inlen); 1310a0d608eeSEric Biggers memcpy(assocbuf, template[i].assoc, template[i].alen); 1311da7f033dSHerbert Xu if (template[i].iv) 1312424a5da6SCristian Stoica memcpy(iv, template[i].iv, iv_len); 1313da7f033dSHerbert Xu else 1314424a5da6SCristian Stoica memset(iv, 0, iv_len); 1315da7f033dSHerbert Xu 1316da7f033dSHerbert Xu crypto_aead_clear_flags(tfm, ~0); 1317da7f033dSHerbert Xu if (template[i].wk) 1318231baecdSEric Biggers crypto_aead_set_flags(tfm, 1319231baecdSEric Biggers CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 1320da7f033dSHerbert Xu 132129b77e5dSHoria Geanta if (template[i].klen > MAX_KEYLEN) { 132229b77e5dSHoria Geanta pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n", 132329b77e5dSHoria Geanta d, j, algo, template[i].klen, 132429b77e5dSHoria Geanta MAX_KEYLEN); 132529b77e5dSHoria Geanta ret = -EINVAL; 132629b77e5dSHoria Geanta goto out; 132729b77e5dSHoria Geanta } 132829b77e5dSHoria Geanta memcpy(key, template[i].key, template[i].klen); 1329da7f033dSHerbert Xu 133005b1d338SCristian Stoica ret = crypto_aead_setkey(tfm, key, template[i].klen); 13310fae0c1eSYanjiang Jin if (template[i].fail == !ret) { 1332d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n", 1333d8a32ac2SJussi Kivilinna d, j, algo, crypto_aead_get_flags(tfm)); 1334da7f033dSHerbert Xu goto out; 1335da7f033dSHerbert Xu } else if (ret) 1336da7f033dSHerbert Xu continue; 1337da7f033dSHerbert Xu 1338a0d608eeSEric Biggers authsize = template[i].clen - template[i].plen; 1339da7f033dSHerbert Xu ret = crypto_aead_setauthsize(tfm, authsize); 1340da7f033dSHerbert Xu if (ret) { 1341d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n", 1342d8a32ac2SJussi Kivilinna d, authsize, j, algo); 1343da7f033dSHerbert Xu goto out; 1344da7f033dSHerbert Xu } 1345da7f033dSHerbert Xu 13468a525fcdSHerbert Xu k = !!template[i].alen; 13478a525fcdSHerbert Xu sg_init_table(sg, k + 1); 1348a0d608eeSEric Biggers sg_set_buf(&sg[0], assocbuf, template[i].alen); 1349a0d608eeSEric Biggers sg_set_buf(&sg[k], inbuf, template[i].clen); 1350a0d608eeSEric Biggers outbuf = inbuf; 1351d8a32ac2SJussi Kivilinna 13528a525fcdSHerbert Xu if (diff_dst) { 13538a525fcdSHerbert Xu sg_init_table(sgout, k + 1); 1354a0d608eeSEric Biggers sg_set_buf(&sgout[0], assocbuf, template[i].alen); 13558a525fcdSHerbert Xu 1356a0d608eeSEric Biggers outbuf = xoutbuf[0] + align_offset; 1357a0d608eeSEric Biggers sg_set_buf(&sgout[k], outbuf, template[i].clen); 13588a525fcdSHerbert Xu } 1359da7f033dSHerbert Xu 1360a0d608eeSEric Biggers aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg, inlen, 1361a0d608eeSEric Biggers iv); 1362da7f033dSHerbert Xu 13638a525fcdSHerbert Xu aead_request_set_ad(req, template[i].alen); 1364da7f033dSHerbert Xu 13657f397136SGilad Ben-Yossef ret = crypto_wait_req(enc ? crypto_aead_encrypt(req) 13667f397136SGilad Ben-Yossef : crypto_aead_decrypt(req), &wait); 1367da7f033dSHerbert Xu 1368da7f033dSHerbert Xu switch (ret) { 1369da7f033dSHerbert Xu case 0: 1370e44a1b44SJarod Wilson if (template[i].novrfy) { 1371e44a1b44SJarod Wilson /* verification was supposed to fail */ 1372d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n", 1373d8a32ac2SJussi Kivilinna d, e, j, algo); 1374e44a1b44SJarod Wilson /* so really, we got a bad message */ 1375e44a1b44SJarod Wilson ret = -EBADMSG; 1376e44a1b44SJarod Wilson goto out; 1377e44a1b44SJarod Wilson } 1378da7f033dSHerbert Xu break; 1379e44a1b44SJarod Wilson case -EBADMSG: 1380e44a1b44SJarod Wilson if (template[i].novrfy) 1381e44a1b44SJarod Wilson /* verification failure was expected */ 1382e44a1b44SJarod Wilson continue; 1383da7f033dSHerbert Xu /* fall through */ 1384da7f033dSHerbert Xu default: 1385d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n", 1386d8a32ac2SJussi Kivilinna d, e, j, algo, -ret); 1387da7f033dSHerbert Xu goto out; 1388da7f033dSHerbert Xu } 1389da7f033dSHerbert Xu 1390a0d608eeSEric Biggers if (memcmp(outbuf, expected_output, outlen)) { 1391d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: Test %d failed on %s for %s\n", 1392d8a32ac2SJussi Kivilinna d, j, e, algo); 1393a0d608eeSEric Biggers hexdump(outbuf, outlen); 1394da7f033dSHerbert Xu ret = -EINVAL; 1395da7f033dSHerbert Xu goto out; 1396da7f033dSHerbert Xu } 1397da7f033dSHerbert Xu } 1398da7f033dSHerbert Xu 1399da7f033dSHerbert Xu for (i = 0, j = 0; i < tcount; i++) { 1400a0d608eeSEric Biggers const char *input, *expected_output; 1401a0d608eeSEric Biggers unsigned int inlen, outlen; 1402a0d608eeSEric Biggers 140358dcf548SJussi Kivilinna /* alignment tests are only done with continuous buffers */ 140458dcf548SJussi Kivilinna if (align_offset != 0) 140558dcf548SJussi Kivilinna break; 140658dcf548SJussi Kivilinna 140705b1d338SCristian Stoica if (!template[i].np) 140805b1d338SCristian Stoica continue; 140905b1d338SCristian Stoica 1410a0d608eeSEric Biggers if (enc) { 1411a0d608eeSEric Biggers if (template[i].novrfy) 14125bc3de58SEric Biggers continue; 1413a0d608eeSEric Biggers input = template[i].ptext; 1414a0d608eeSEric Biggers inlen = template[i].plen; 1415a0d608eeSEric Biggers expected_output = template[i].ctext; 1416a0d608eeSEric Biggers outlen = template[i].clen; 1417a0d608eeSEric Biggers } else { 1418a0d608eeSEric Biggers input = template[i].ctext; 1419a0d608eeSEric Biggers inlen = template[i].clen; 1420a0d608eeSEric Biggers expected_output = template[i].ptext; 1421a0d608eeSEric Biggers outlen = template[i].plen; 1422a0d608eeSEric Biggers } 14235bc3de58SEric Biggers 1424da7f033dSHerbert Xu j++; 1425da7f033dSHerbert Xu 1426da7f033dSHerbert Xu if (template[i].iv) 1427abfa7f43SJerome Marchand memcpy(iv, template[i].iv, iv_len); 1428da7f033dSHerbert Xu else 1429da7f033dSHerbert Xu memset(iv, 0, MAX_IVLEN); 1430da7f033dSHerbert Xu 1431da7f033dSHerbert Xu crypto_aead_clear_flags(tfm, ~0); 1432da7f033dSHerbert Xu if (template[i].wk) 1433231baecdSEric Biggers crypto_aead_set_flags(tfm, 1434231baecdSEric Biggers CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 143529b77e5dSHoria Geanta if (template[i].klen > MAX_KEYLEN) { 143629b77e5dSHoria Geanta pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n", 143705b1d338SCristian Stoica d, j, algo, template[i].klen, MAX_KEYLEN); 143829b77e5dSHoria Geanta ret = -EINVAL; 143929b77e5dSHoria Geanta goto out; 144029b77e5dSHoria Geanta } 144129b77e5dSHoria Geanta memcpy(key, template[i].key, template[i].klen); 1442da7f033dSHerbert Xu 1443da7f033dSHerbert Xu ret = crypto_aead_setkey(tfm, key, template[i].klen); 14440fae0c1eSYanjiang Jin if (template[i].fail == !ret) { 1445d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n", 1446d8a32ac2SJussi Kivilinna d, j, algo, crypto_aead_get_flags(tfm)); 1447da7f033dSHerbert Xu goto out; 1448da7f033dSHerbert Xu } else if (ret) 1449da7f033dSHerbert Xu continue; 1450da7f033dSHerbert Xu 1451a0d608eeSEric Biggers authsize = template[i].clen - template[i].plen; 1452da7f033dSHerbert Xu 1453da7f033dSHerbert Xu ret = -EINVAL; 14548a525fcdSHerbert Xu sg_init_table(sg, template[i].anp + template[i].np); 1455d8a32ac2SJussi Kivilinna if (diff_dst) 14568a525fcdSHerbert Xu sg_init_table(sgout, template[i].anp + template[i].np); 14578a525fcdSHerbert Xu 14588a525fcdSHerbert Xu ret = -EINVAL; 14598a525fcdSHerbert Xu for (k = 0, temp = 0; k < template[i].anp; k++) { 14608a525fcdSHerbert Xu if (WARN_ON(offset_in_page(IDX[k]) + 14618a525fcdSHerbert Xu template[i].atap[k] > PAGE_SIZE)) 14628a525fcdSHerbert Xu goto out; 14638a525fcdSHerbert Xu sg_set_buf(&sg[k], 14648a525fcdSHerbert Xu memcpy(axbuf[IDX[k] >> PAGE_SHIFT] + 14658a525fcdSHerbert Xu offset_in_page(IDX[k]), 14668a525fcdSHerbert Xu template[i].assoc + temp, 14678a525fcdSHerbert Xu template[i].atap[k]), 14688a525fcdSHerbert Xu template[i].atap[k]); 14698a525fcdSHerbert Xu if (diff_dst) 14708a525fcdSHerbert Xu sg_set_buf(&sgout[k], 14718a525fcdSHerbert Xu axbuf[IDX[k] >> PAGE_SHIFT] + 14728a525fcdSHerbert Xu offset_in_page(IDX[k]), 14738a525fcdSHerbert Xu template[i].atap[k]); 14748a525fcdSHerbert Xu temp += template[i].atap[k]; 14758a525fcdSHerbert Xu } 14768a525fcdSHerbert Xu 1477da7f033dSHerbert Xu for (k = 0, temp = 0; k < template[i].np; k++) { 1478a0d608eeSEric Biggers n = template[i].tap[k]; 1479a0d608eeSEric Biggers if (k == template[i].np - 1 && !enc) 1480a0d608eeSEric Biggers n += authsize; 1481a0d608eeSEric Biggers 1482a0d608eeSEric Biggers if (WARN_ON(offset_in_page(IDX[k]) + n > PAGE_SIZE)) 1483da7f033dSHerbert Xu goto out; 1484da7f033dSHerbert Xu 148505b1d338SCristian Stoica q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]); 1486a0d608eeSEric Biggers memcpy(q, input + temp, n); 1487a0d608eeSEric Biggers sg_set_buf(&sg[template[i].anp + k], q, n); 1488d8a32ac2SJussi Kivilinna 1489d8a32ac2SJussi Kivilinna if (diff_dst) { 1490d8a32ac2SJussi Kivilinna q = xoutbuf[IDX[k] >> PAGE_SHIFT] + 1491d8a32ac2SJussi Kivilinna offset_in_page(IDX[k]); 1492d8a32ac2SJussi Kivilinna 1493a0d608eeSEric Biggers memset(q, 0, n); 1494d8a32ac2SJussi Kivilinna 1495a0d608eeSEric Biggers sg_set_buf(&sgout[template[i].anp + k], q, n); 1496d8a32ac2SJussi Kivilinna } 1497d8a32ac2SJussi Kivilinna 14988ec25c51SHoria Geanta if (k == template[i].np - 1 && enc) 14998ec25c51SHoria Geanta n += authsize; 15008ec25c51SHoria Geanta if (offset_in_page(q) + n < PAGE_SIZE) 15018ec25c51SHoria Geanta q[n] = 0; 15028ec25c51SHoria Geanta 1503a0d608eeSEric Biggers temp += n; 1504da7f033dSHerbert Xu } 1505da7f033dSHerbert Xu 1506da7f033dSHerbert Xu ret = crypto_aead_setauthsize(tfm, authsize); 1507da7f033dSHerbert Xu if (ret) { 1508d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n", 1509d8a32ac2SJussi Kivilinna d, authsize, j, algo); 1510da7f033dSHerbert Xu goto out; 1511da7f033dSHerbert Xu } 1512da7f033dSHerbert Xu 1513da7f033dSHerbert Xu if (enc) { 15148a525fcdSHerbert Xu if (WARN_ON(sg[template[i].anp + k - 1].offset + 15158a525fcdSHerbert Xu sg[template[i].anp + k - 1].length + 15168a525fcdSHerbert Xu authsize > PAGE_SIZE)) { 1517da7f033dSHerbert Xu ret = -EINVAL; 1518da7f033dSHerbert Xu goto out; 1519da7f033dSHerbert Xu } 1520da7f033dSHerbert Xu 1521d8a32ac2SJussi Kivilinna if (diff_dst) 15228a525fcdSHerbert Xu sgout[template[i].anp + k - 1].length += 15238a525fcdSHerbert Xu authsize; 15248a525fcdSHerbert Xu sg[template[i].anp + k - 1].length += authsize; 1525da7f033dSHerbert Xu } 1526da7f033dSHerbert Xu 1527d8a32ac2SJussi Kivilinna aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg, 1528a0d608eeSEric Biggers inlen, iv); 1529da7f033dSHerbert Xu 15308a525fcdSHerbert Xu aead_request_set_ad(req, template[i].alen); 1531da7f033dSHerbert Xu 15327f397136SGilad Ben-Yossef ret = crypto_wait_req(enc ? crypto_aead_encrypt(req) 15337f397136SGilad Ben-Yossef : crypto_aead_decrypt(req), &wait); 1534da7f033dSHerbert Xu 1535da7f033dSHerbert Xu switch (ret) { 1536da7f033dSHerbert Xu case 0: 1537e44a1b44SJarod Wilson if (template[i].novrfy) { 1538e44a1b44SJarod Wilson /* verification was supposed to fail */ 1539d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret was 0, expected -EBADMSG\n", 1540d8a32ac2SJussi Kivilinna d, e, j, algo); 1541e44a1b44SJarod Wilson /* so really, we got a bad message */ 1542e44a1b44SJarod Wilson ret = -EBADMSG; 1543e44a1b44SJarod Wilson goto out; 1544e44a1b44SJarod Wilson } 1545da7f033dSHerbert Xu break; 1546e44a1b44SJarod Wilson case -EBADMSG: 1547e44a1b44SJarod Wilson if (template[i].novrfy) 1548e44a1b44SJarod Wilson /* verification failure was expected */ 1549e44a1b44SJarod Wilson continue; 1550da7f033dSHerbert Xu /* fall through */ 1551da7f033dSHerbert Xu default: 1552d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n", 1553d8a32ac2SJussi Kivilinna d, e, j, algo, -ret); 1554da7f033dSHerbert Xu goto out; 1555da7f033dSHerbert Xu } 1556da7f033dSHerbert Xu 1557da7f033dSHerbert Xu ret = -EINVAL; 1558da7f033dSHerbert Xu for (k = 0, temp = 0; k < template[i].np; k++) { 1559d8a32ac2SJussi Kivilinna if (diff_dst) 1560d8a32ac2SJussi Kivilinna q = xoutbuf[IDX[k] >> PAGE_SHIFT] + 1561d8a32ac2SJussi Kivilinna offset_in_page(IDX[k]); 1562d8a32ac2SJussi Kivilinna else 1563da7f033dSHerbert Xu q = xbuf[IDX[k] >> PAGE_SHIFT] + 1564da7f033dSHerbert Xu offset_in_page(IDX[k]); 1565da7f033dSHerbert Xu 1566da7f033dSHerbert Xu n = template[i].tap[k]; 1567a0d608eeSEric Biggers if (k == template[i].np - 1 && enc) 1568a0d608eeSEric Biggers n += authsize; 1569da7f033dSHerbert Xu 1570a0d608eeSEric Biggers if (memcmp(q, expected_output + temp, n)) { 1571d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n", 1572d8a32ac2SJussi Kivilinna d, j, e, k, algo); 1573da7f033dSHerbert Xu hexdump(q, n); 1574da7f033dSHerbert Xu goto out; 1575da7f033dSHerbert Xu } 1576da7f033dSHerbert Xu 1577da7f033dSHerbert Xu q += n; 1578da7f033dSHerbert Xu if (k == template[i].np - 1 && !enc) { 1579a0d608eeSEric Biggers if (!diff_dst && memcmp(q, input + temp + n, 1580a0d608eeSEric Biggers authsize)) 1581da7f033dSHerbert Xu n = authsize; 1582da7f033dSHerbert Xu else 1583da7f033dSHerbert Xu n = 0; 1584da7f033dSHerbert Xu } else { 158505b1d338SCristian Stoica for (n = 0; offset_in_page(q + n) && q[n]; n++) 1586da7f033dSHerbert Xu ; 1587da7f033dSHerbert Xu } 1588da7f033dSHerbert Xu if (n) { 1589d8a32ac2SJussi Kivilinna pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n", 1590d8a32ac2SJussi Kivilinna d, j, e, k, algo, n); 1591da7f033dSHerbert Xu hexdump(q, n); 1592da7f033dSHerbert Xu goto out; 1593da7f033dSHerbert Xu } 1594da7f033dSHerbert Xu 1595da7f033dSHerbert Xu temp += template[i].tap[k]; 1596da7f033dSHerbert Xu } 1597da7f033dSHerbert Xu } 1598da7f033dSHerbert Xu 1599da7f033dSHerbert Xu ret = 0; 1600da7f033dSHerbert Xu 1601da7f033dSHerbert Xu out: 1602da7f033dSHerbert Xu aead_request_free(req); 1603d8a32ac2SJussi Kivilinna kfree(sg); 1604d8a32ac2SJussi Kivilinna out_nosg: 1605d8a32ac2SJussi Kivilinna if (diff_dst) 1606d8a32ac2SJussi Kivilinna testmgr_free_buf(xoutbuf); 1607d8a32ac2SJussi Kivilinna out_nooutbuf: 1608f8b0d4d0SHerbert Xu testmgr_free_buf(axbuf); 1609f8b0d4d0SHerbert Xu out_noaxbuf: 1610f8b0d4d0SHerbert Xu testmgr_free_buf(xbuf); 1611f8b0d4d0SHerbert Xu out_noxbuf: 161229b77e5dSHoria Geanta kfree(key); 16139bac019dSTadeusz Struk kfree(iv); 1614da7f033dSHerbert Xu return ret; 1615da7f033dSHerbert Xu } 1616da7f033dSHerbert Xu 1617d8a32ac2SJussi Kivilinna static int test_aead(struct crypto_aead *tfm, int enc, 1618b13b1e0cSEric Biggers const struct aead_testvec *template, unsigned int tcount) 1619d8a32ac2SJussi Kivilinna { 162058dcf548SJussi Kivilinna unsigned int alignmask; 1621d8a32ac2SJussi Kivilinna int ret; 1622d8a32ac2SJussi Kivilinna 1623d8a32ac2SJussi Kivilinna /* test 'dst == src' case */ 162458dcf548SJussi Kivilinna ret = __test_aead(tfm, enc, template, tcount, false, 0); 1625d8a32ac2SJussi Kivilinna if (ret) 1626d8a32ac2SJussi Kivilinna return ret; 1627d8a32ac2SJussi Kivilinna 1628d8a32ac2SJussi Kivilinna /* test 'dst != src' case */ 162958dcf548SJussi Kivilinna ret = __test_aead(tfm, enc, template, tcount, true, 0); 163058dcf548SJussi Kivilinna if (ret) 163158dcf548SJussi Kivilinna return ret; 163258dcf548SJussi Kivilinna 163358dcf548SJussi Kivilinna /* test unaligned buffers, check with one byte offset */ 163458dcf548SJussi Kivilinna ret = __test_aead(tfm, enc, template, tcount, true, 1); 163558dcf548SJussi Kivilinna if (ret) 163658dcf548SJussi Kivilinna return ret; 163758dcf548SJussi Kivilinna 163858dcf548SJussi Kivilinna alignmask = crypto_tfm_alg_alignmask(&tfm->base); 163958dcf548SJussi Kivilinna if (alignmask) { 164058dcf548SJussi Kivilinna /* Check if alignment mask for tfm is correctly set. */ 164158dcf548SJussi Kivilinna ret = __test_aead(tfm, enc, template, tcount, true, 164258dcf548SJussi Kivilinna alignmask + 1); 164358dcf548SJussi Kivilinna if (ret) 164458dcf548SJussi Kivilinna return ret; 164558dcf548SJussi Kivilinna } 164658dcf548SJussi Kivilinna 164758dcf548SJussi Kivilinna return 0; 1648d8a32ac2SJussi Kivilinna } 1649d8a32ac2SJussi Kivilinna 16501aa4ecd9SHerbert Xu static int test_cipher(struct crypto_cipher *tfm, int enc, 1651b13b1e0cSEric Biggers const struct cipher_testvec *template, 1652b13b1e0cSEric Biggers unsigned int tcount) 16531aa4ecd9SHerbert Xu { 16541aa4ecd9SHerbert Xu const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); 16551aa4ecd9SHerbert Xu unsigned int i, j, k; 16561aa4ecd9SHerbert Xu char *q; 16571aa4ecd9SHerbert Xu const char *e; 165892a4c9feSEric Biggers const char *input, *result; 16591aa4ecd9SHerbert Xu void *data; 1660f8b0d4d0SHerbert Xu char *xbuf[XBUFSIZE]; 1661f8b0d4d0SHerbert Xu int ret = -ENOMEM; 1662f8b0d4d0SHerbert Xu 1663f8b0d4d0SHerbert Xu if (testmgr_alloc_buf(xbuf)) 1664f8b0d4d0SHerbert Xu goto out_nobuf; 16651aa4ecd9SHerbert Xu 16661aa4ecd9SHerbert Xu if (enc == ENCRYPT) 16671aa4ecd9SHerbert Xu e = "encryption"; 16681aa4ecd9SHerbert Xu else 16691aa4ecd9SHerbert Xu e = "decryption"; 16701aa4ecd9SHerbert Xu 16711aa4ecd9SHerbert Xu j = 0; 16721aa4ecd9SHerbert Xu for (i = 0; i < tcount; i++) { 16731aa4ecd9SHerbert Xu 167410faa8c0SStephan Mueller if (fips_enabled && template[i].fips_skip) 167510faa8c0SStephan Mueller continue; 167610faa8c0SStephan Mueller 167792a4c9feSEric Biggers input = enc ? template[i].ptext : template[i].ctext; 167892a4c9feSEric Biggers result = enc ? template[i].ctext : template[i].ptext; 16791aa4ecd9SHerbert Xu j++; 16801aa4ecd9SHerbert Xu 1681fd57f22aSHerbert Xu ret = -EINVAL; 168292a4c9feSEric Biggers if (WARN_ON(template[i].len > PAGE_SIZE)) 1683fd57f22aSHerbert Xu goto out; 1684fd57f22aSHerbert Xu 16851aa4ecd9SHerbert Xu data = xbuf[0]; 168692a4c9feSEric Biggers memcpy(data, input, template[i].len); 16871aa4ecd9SHerbert Xu 16881aa4ecd9SHerbert Xu crypto_cipher_clear_flags(tfm, ~0); 16891aa4ecd9SHerbert Xu if (template[i].wk) 1690231baecdSEric Biggers crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 16911aa4ecd9SHerbert Xu 16921aa4ecd9SHerbert Xu ret = crypto_cipher_setkey(tfm, template[i].key, 16931aa4ecd9SHerbert Xu template[i].klen); 16940fae0c1eSYanjiang Jin if (template[i].fail == !ret) { 16951aa4ecd9SHerbert Xu printk(KERN_ERR "alg: cipher: setkey failed " 16961aa4ecd9SHerbert Xu "on test %d for %s: flags=%x\n", j, 16971aa4ecd9SHerbert Xu algo, crypto_cipher_get_flags(tfm)); 16981aa4ecd9SHerbert Xu goto out; 16991aa4ecd9SHerbert Xu } else if (ret) 17001aa4ecd9SHerbert Xu continue; 17011aa4ecd9SHerbert Xu 170292a4c9feSEric Biggers for (k = 0; k < template[i].len; 17031aa4ecd9SHerbert Xu k += crypto_cipher_blocksize(tfm)) { 17041aa4ecd9SHerbert Xu if (enc) 17051aa4ecd9SHerbert Xu crypto_cipher_encrypt_one(tfm, data + k, 17061aa4ecd9SHerbert Xu data + k); 17071aa4ecd9SHerbert Xu else 17081aa4ecd9SHerbert Xu crypto_cipher_decrypt_one(tfm, data + k, 17091aa4ecd9SHerbert Xu data + k); 17101aa4ecd9SHerbert Xu } 17111aa4ecd9SHerbert Xu 17121aa4ecd9SHerbert Xu q = data; 171392a4c9feSEric Biggers if (memcmp(q, result, template[i].len)) { 17141aa4ecd9SHerbert Xu printk(KERN_ERR "alg: cipher: Test %d failed " 17151aa4ecd9SHerbert Xu "on %s for %s\n", j, e, algo); 171692a4c9feSEric Biggers hexdump(q, template[i].len); 17171aa4ecd9SHerbert Xu ret = -EINVAL; 17181aa4ecd9SHerbert Xu goto out; 17191aa4ecd9SHerbert Xu } 17201aa4ecd9SHerbert Xu } 17211aa4ecd9SHerbert Xu 17221aa4ecd9SHerbert Xu ret = 0; 17231aa4ecd9SHerbert Xu 17241aa4ecd9SHerbert Xu out: 1725f8b0d4d0SHerbert Xu testmgr_free_buf(xbuf); 1726f8b0d4d0SHerbert Xu out_nobuf: 17271aa4ecd9SHerbert Xu return ret; 17281aa4ecd9SHerbert Xu } 17291aa4ecd9SHerbert Xu 17304e7babbaSEric Biggers static int test_skcipher_vec_cfg(const char *driver, int enc, 17314e7babbaSEric Biggers const struct cipher_testvec *vec, 17324e7babbaSEric Biggers unsigned int vec_num, 17334e7babbaSEric Biggers const struct testvec_config *cfg, 17344e7babbaSEric Biggers struct skcipher_request *req, 17354e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 1736da7f033dSHerbert Xu { 17374e7babbaSEric Biggers struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 17384e7babbaSEric Biggers const unsigned int alignmask = crypto_skcipher_alignmask(tfm); 17394e7babbaSEric Biggers const unsigned int ivsize = crypto_skcipher_ivsize(tfm); 17404e7babbaSEric Biggers const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 17414e7babbaSEric Biggers const char *op = enc ? "encryption" : "decryption"; 17424e7babbaSEric Biggers DECLARE_CRYPTO_WAIT(wait); 17434e7babbaSEric Biggers u8 _iv[3 * (MAX_ALGAPI_ALIGNMASK + 1) + MAX_IVLEN]; 17444e7babbaSEric Biggers u8 *iv = PTR_ALIGN(&_iv[0], 2 * (MAX_ALGAPI_ALIGNMASK + 1)) + 17454e7babbaSEric Biggers cfg->iv_offset + 17464e7babbaSEric Biggers (cfg->iv_offset_relative_to_alignmask ? alignmask : 0); 17474e7babbaSEric Biggers struct kvec input; 17484e7babbaSEric Biggers int err; 1749f8b0d4d0SHerbert Xu 17504e7babbaSEric Biggers /* Set the key */ 17514e7babbaSEric Biggers if (vec->wk) 1752231baecdSEric Biggers crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 1753da7f033dSHerbert Xu else 17544e7babbaSEric Biggers crypto_skcipher_clear_flags(tfm, 17554e7babbaSEric Biggers CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 17564e7babbaSEric Biggers err = crypto_skcipher_setkey(tfm, vec->key, vec->klen); 17574e7babbaSEric Biggers if (err) { 17584e7babbaSEric Biggers if (vec->fail) /* expectedly failed to set key? */ 17594e7babbaSEric Biggers return 0; 17604e7babbaSEric Biggers pr_err("alg: skcipher: %s setkey failed with err %d on test vector %u; flags=%#x\n", 17614e7babbaSEric Biggers driver, err, vec_num, crypto_skcipher_get_flags(tfm)); 17624e7babbaSEric Biggers return err; 17634e7babbaSEric Biggers } 17644e7babbaSEric Biggers if (vec->fail) { 17654e7babbaSEric Biggers pr_err("alg: skcipher: %s setkey unexpectedly succeeded on test vector %u\n", 17664e7babbaSEric Biggers driver, vec_num); 17674e7babbaSEric Biggers return -EINVAL; 176808d6af8cSJussi Kivilinna } 1769da7f033dSHerbert Xu 17704e7babbaSEric Biggers /* The IV must be copied to a buffer, as the algorithm may modify it */ 17714e7babbaSEric Biggers if (ivsize) { 17724e7babbaSEric Biggers if (WARN_ON(ivsize > MAX_IVLEN)) 17734e7babbaSEric Biggers return -EINVAL; 17744e7babbaSEric Biggers if (vec->iv && !(vec->generates_iv && enc)) 17754e7babbaSEric Biggers memcpy(iv, vec->iv, ivsize); 177608d6af8cSJussi Kivilinna else 17774e7babbaSEric Biggers memset(iv, 0, ivsize); 17784e7babbaSEric Biggers } else { 17794e7babbaSEric Biggers if (vec->generates_iv) { 17804e7babbaSEric Biggers pr_err("alg: skcipher: %s has ivsize=0 but test vector %u generates IV!\n", 17814e7babbaSEric Biggers driver, vec_num); 17824e7babbaSEric Biggers return -EINVAL; 17834e7babbaSEric Biggers } 17844e7babbaSEric Biggers iv = NULL; 1785da7f033dSHerbert Xu } 1786da7f033dSHerbert Xu 17874e7babbaSEric Biggers /* Build the src/dst scatterlists */ 17884e7babbaSEric Biggers input.iov_base = enc ? (void *)vec->ptext : (void *)vec->ctext; 17894e7babbaSEric Biggers input.iov_len = vec->len; 17904e7babbaSEric Biggers err = build_cipher_test_sglists(tsgls, cfg, alignmask, 17914e7babbaSEric Biggers vec->len, vec->len, &input, 1); 17924e7babbaSEric Biggers if (err) { 17934e7babbaSEric Biggers pr_err("alg: skcipher: %s %s: error preparing scatterlists for test vector %u, cfg=\"%s\"\n", 17944e7babbaSEric Biggers driver, op, vec_num, cfg->name); 17954e7babbaSEric Biggers return err; 1796da7f033dSHerbert Xu } 1797da7f033dSHerbert Xu 17984e7babbaSEric Biggers /* Do the actual encryption or decryption */ 17994e7babbaSEric Biggers testmgr_poison(req->__ctx, crypto_skcipher_reqsize(tfm)); 18004e7babbaSEric Biggers skcipher_request_set_callback(req, req_flags, crypto_req_done, &wait); 18014e7babbaSEric Biggers skcipher_request_set_crypt(req, tsgls->src.sgl_ptr, tsgls->dst.sgl_ptr, 18024e7babbaSEric Biggers vec->len, iv); 18034e7babbaSEric Biggers err = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) : 18044e7babbaSEric Biggers crypto_skcipher_decrypt(req), &wait); 18054e7babbaSEric Biggers if (err) { 18064e7babbaSEric Biggers pr_err("alg: skcipher: %s %s failed with err %d on test vector %u, cfg=\"%s\"\n", 18074e7babbaSEric Biggers driver, op, err, vec_num, cfg->name); 18084e7babbaSEric Biggers return err; 1809da7f033dSHerbert Xu } 1810da7f033dSHerbert Xu 18114e7babbaSEric Biggers /* Check for the correct output (ciphertext or plaintext) */ 18124e7babbaSEric Biggers err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext, 18134e7babbaSEric Biggers vec->len, 0, true); 18144e7babbaSEric Biggers if (err == -EOVERFLOW) { 18154e7babbaSEric Biggers pr_err("alg: skcipher: %s %s overran dst buffer on test vector %u, cfg=\"%s\"\n", 18164e7babbaSEric Biggers driver, op, vec_num, cfg->name); 18174e7babbaSEric Biggers return err; 18184e7babbaSEric Biggers } 18194e7babbaSEric Biggers if (err) { 18204e7babbaSEric Biggers pr_err("alg: skcipher: %s %s test failed (wrong result) on test vector %u, cfg=\"%s\"\n", 18214e7babbaSEric Biggers driver, op, vec_num, cfg->name); 18224e7babbaSEric Biggers return err; 18234e7babbaSEric Biggers } 182408d6af8cSJussi Kivilinna 18254e7babbaSEric Biggers /* If applicable, check that the algorithm generated the correct IV */ 18264e7babbaSEric Biggers if (vec->generates_iv && enc && memcmp(iv, vec->iv, ivsize) != 0) { 18274e7babbaSEric Biggers pr_err("alg: skcipher: %s %s test failed (wrong output IV) on test vector %u, cfg=\"%s\"\n", 18284e7babbaSEric Biggers driver, op, vec_num, cfg->name); 18294e7babbaSEric Biggers hexdump(iv, ivsize); 18304e7babbaSEric Biggers return -EINVAL; 18313a338f20SJussi Kivilinna } 18323a338f20SJussi Kivilinna 18333a338f20SJussi Kivilinna return 0; 183408d6af8cSJussi Kivilinna } 183508d6af8cSJussi Kivilinna 18364e7babbaSEric Biggers static int test_skcipher_vec(const char *driver, int enc, 18374e7babbaSEric Biggers const struct cipher_testvec *vec, 18384e7babbaSEric Biggers unsigned int vec_num, 18394e7babbaSEric Biggers struct skcipher_request *req, 18404e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 18414e7babbaSEric Biggers { 18424e7babbaSEric Biggers unsigned int i; 18434e7babbaSEric Biggers int err; 18444e7babbaSEric Biggers 18454e7babbaSEric Biggers if (fips_enabled && vec->fips_skip) 18464e7babbaSEric Biggers return 0; 18474e7babbaSEric Biggers 18484e7babbaSEric Biggers for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) { 18494e7babbaSEric Biggers err = test_skcipher_vec_cfg(driver, enc, vec, vec_num, 18504e7babbaSEric Biggers &default_cipher_testvec_configs[i], 18514e7babbaSEric Biggers req, tsgls); 18524e7babbaSEric Biggers if (err) 18534e7babbaSEric Biggers return err; 18544e7babbaSEric Biggers } 18554e7babbaSEric Biggers 18564e7babbaSEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 18574e7babbaSEric Biggers if (!noextratests) { 18584e7babbaSEric Biggers struct testvec_config cfg; 18594e7babbaSEric Biggers char cfgname[TESTVEC_CONFIG_NAMELEN]; 18604e7babbaSEric Biggers 18614e7babbaSEric Biggers for (i = 0; i < fuzz_iterations; i++) { 18624e7babbaSEric Biggers generate_random_testvec_config(&cfg, cfgname, 18634e7babbaSEric Biggers sizeof(cfgname)); 18644e7babbaSEric Biggers err = test_skcipher_vec_cfg(driver, enc, vec, vec_num, 18654e7babbaSEric Biggers &cfg, req, tsgls); 18664e7babbaSEric Biggers if (err) 18674e7babbaSEric Biggers return err; 18684e7babbaSEric Biggers } 18694e7babbaSEric Biggers } 18704e7babbaSEric Biggers #endif 18714e7babbaSEric Biggers return 0; 18724e7babbaSEric Biggers } 18734e7babbaSEric Biggers 18744e7babbaSEric Biggers static int test_skcipher(const char *driver, int enc, 18754e7babbaSEric Biggers const struct cipher_test_suite *suite, 18764e7babbaSEric Biggers struct skcipher_request *req, 18774e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 18784e7babbaSEric Biggers { 18794e7babbaSEric Biggers unsigned int i; 18804e7babbaSEric Biggers int err; 18814e7babbaSEric Biggers 18824e7babbaSEric Biggers for (i = 0; i < suite->count; i++) { 18834e7babbaSEric Biggers err = test_skcipher_vec(driver, enc, &suite->vecs[i], i, req, 18844e7babbaSEric Biggers tsgls); 18854e7babbaSEric Biggers if (err) 18864e7babbaSEric Biggers return err; 18874e7babbaSEric Biggers } 18884e7babbaSEric Biggers return 0; 18894e7babbaSEric Biggers } 18904e7babbaSEric Biggers 18914e7babbaSEric Biggers static int alg_test_skcipher(const struct alg_test_desc *desc, 18924e7babbaSEric Biggers const char *driver, u32 type, u32 mask) 18934e7babbaSEric Biggers { 18944e7babbaSEric Biggers const struct cipher_test_suite *suite = &desc->suite.cipher; 18954e7babbaSEric Biggers struct crypto_skcipher *tfm; 18964e7babbaSEric Biggers struct skcipher_request *req = NULL; 18974e7babbaSEric Biggers struct cipher_test_sglists *tsgls = NULL; 18984e7babbaSEric Biggers int err; 18994e7babbaSEric Biggers 19004e7babbaSEric Biggers if (suite->count <= 0) { 19014e7babbaSEric Biggers pr_err("alg: skcipher: empty test suite for %s\n", driver); 19024e7babbaSEric Biggers return -EINVAL; 19034e7babbaSEric Biggers } 19044e7babbaSEric Biggers 19054e7babbaSEric Biggers tfm = crypto_alloc_skcipher(driver, type, mask); 19064e7babbaSEric Biggers if (IS_ERR(tfm)) { 19074e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", 19084e7babbaSEric Biggers driver, PTR_ERR(tfm)); 19094e7babbaSEric Biggers return PTR_ERR(tfm); 19104e7babbaSEric Biggers } 19114e7babbaSEric Biggers 19124e7babbaSEric Biggers req = skcipher_request_alloc(tfm, GFP_KERNEL); 19134e7babbaSEric Biggers if (!req) { 19144e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate request for %s\n", 19154e7babbaSEric Biggers driver); 19164e7babbaSEric Biggers err = -ENOMEM; 19174e7babbaSEric Biggers goto out; 19184e7babbaSEric Biggers } 19194e7babbaSEric Biggers 19204e7babbaSEric Biggers tsgls = alloc_cipher_test_sglists(); 19214e7babbaSEric Biggers if (!tsgls) { 19224e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate test buffers for %s\n", 19234e7babbaSEric Biggers driver); 19244e7babbaSEric Biggers err = -ENOMEM; 19254e7babbaSEric Biggers goto out; 19264e7babbaSEric Biggers } 19274e7babbaSEric Biggers 19284e7babbaSEric Biggers err = test_skcipher(driver, ENCRYPT, suite, req, tsgls); 19294e7babbaSEric Biggers if (err) 19304e7babbaSEric Biggers goto out; 19314e7babbaSEric Biggers 19324e7babbaSEric Biggers err = test_skcipher(driver, DECRYPT, suite, req, tsgls); 19334e7babbaSEric Biggers out: 19344e7babbaSEric Biggers free_cipher_test_sglists(tsgls); 19354e7babbaSEric Biggers skcipher_request_free(req); 19364e7babbaSEric Biggers crypto_free_skcipher(tfm); 19374e7babbaSEric Biggers return err; 19384e7babbaSEric Biggers } 19394e7babbaSEric Biggers 1940b13b1e0cSEric Biggers static int test_comp(struct crypto_comp *tfm, 1941b13b1e0cSEric Biggers const struct comp_testvec *ctemplate, 1942b13b1e0cSEric Biggers const struct comp_testvec *dtemplate, 1943b13b1e0cSEric Biggers int ctcount, int dtcount) 1944da7f033dSHerbert Xu { 1945da7f033dSHerbert Xu const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm)); 194633607384SMahipal Challa char *output, *decomp_output; 1947da7f033dSHerbert Xu unsigned int i; 1948da7f033dSHerbert Xu int ret; 1949da7f033dSHerbert Xu 195033607384SMahipal Challa output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 195133607384SMahipal Challa if (!output) 195233607384SMahipal Challa return -ENOMEM; 195333607384SMahipal Challa 195433607384SMahipal Challa decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 195533607384SMahipal Challa if (!decomp_output) { 195633607384SMahipal Challa kfree(output); 195733607384SMahipal Challa return -ENOMEM; 195833607384SMahipal Challa } 195933607384SMahipal Challa 1960da7f033dSHerbert Xu for (i = 0; i < ctcount; i++) { 1961c79cf910SGeert Uytterhoeven int ilen; 1962c79cf910SGeert Uytterhoeven unsigned int dlen = COMP_BUF_SIZE; 1963da7f033dSHerbert Xu 196422a8118dSMichael Schupikov memset(output, 0, COMP_BUF_SIZE); 196522a8118dSMichael Schupikov memset(decomp_output, 0, COMP_BUF_SIZE); 1966da7f033dSHerbert Xu 1967da7f033dSHerbert Xu ilen = ctemplate[i].inlen; 1968da7f033dSHerbert Xu ret = crypto_comp_compress(tfm, ctemplate[i].input, 196933607384SMahipal Challa ilen, output, &dlen); 1970da7f033dSHerbert Xu if (ret) { 1971da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: compression failed " 1972da7f033dSHerbert Xu "on test %d for %s: ret=%d\n", i + 1, algo, 1973da7f033dSHerbert Xu -ret); 1974da7f033dSHerbert Xu goto out; 1975da7f033dSHerbert Xu } 1976da7f033dSHerbert Xu 197733607384SMahipal Challa ilen = dlen; 197833607384SMahipal Challa dlen = COMP_BUF_SIZE; 197933607384SMahipal Challa ret = crypto_comp_decompress(tfm, output, 198033607384SMahipal Challa ilen, decomp_output, &dlen); 198133607384SMahipal Challa if (ret) { 198233607384SMahipal Challa pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n", 198333607384SMahipal Challa i + 1, algo, -ret); 198433607384SMahipal Challa goto out; 198533607384SMahipal Challa } 198633607384SMahipal Challa 198733607384SMahipal Challa if (dlen != ctemplate[i].inlen) { 1988b812eb00SGeert Uytterhoeven printk(KERN_ERR "alg: comp: Compression test %d " 1989b812eb00SGeert Uytterhoeven "failed for %s: output len = %d\n", i + 1, algo, 1990b812eb00SGeert Uytterhoeven dlen); 1991b812eb00SGeert Uytterhoeven ret = -EINVAL; 1992b812eb00SGeert Uytterhoeven goto out; 1993b812eb00SGeert Uytterhoeven } 1994b812eb00SGeert Uytterhoeven 199533607384SMahipal Challa if (memcmp(decomp_output, ctemplate[i].input, 199633607384SMahipal Challa ctemplate[i].inlen)) { 199733607384SMahipal Challa pr_err("alg: comp: compression failed: output differs: on test %d for %s\n", 199833607384SMahipal Challa i + 1, algo); 199933607384SMahipal Challa hexdump(decomp_output, dlen); 2000da7f033dSHerbert Xu ret = -EINVAL; 2001da7f033dSHerbert Xu goto out; 2002da7f033dSHerbert Xu } 2003da7f033dSHerbert Xu } 2004da7f033dSHerbert Xu 2005da7f033dSHerbert Xu for (i = 0; i < dtcount; i++) { 2006c79cf910SGeert Uytterhoeven int ilen; 2007c79cf910SGeert Uytterhoeven unsigned int dlen = COMP_BUF_SIZE; 2008da7f033dSHerbert Xu 200922a8118dSMichael Schupikov memset(decomp_output, 0, COMP_BUF_SIZE); 2010da7f033dSHerbert Xu 2011da7f033dSHerbert Xu ilen = dtemplate[i].inlen; 2012da7f033dSHerbert Xu ret = crypto_comp_decompress(tfm, dtemplate[i].input, 201333607384SMahipal Challa ilen, decomp_output, &dlen); 2014da7f033dSHerbert Xu if (ret) { 2015da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: decompression failed " 2016da7f033dSHerbert Xu "on test %d for %s: ret=%d\n", i + 1, algo, 2017da7f033dSHerbert Xu -ret); 2018da7f033dSHerbert Xu goto out; 2019da7f033dSHerbert Xu } 2020da7f033dSHerbert Xu 2021b812eb00SGeert Uytterhoeven if (dlen != dtemplate[i].outlen) { 2022b812eb00SGeert Uytterhoeven printk(KERN_ERR "alg: comp: Decompression test %d " 2023b812eb00SGeert Uytterhoeven "failed for %s: output len = %d\n", i + 1, algo, 2024b812eb00SGeert Uytterhoeven dlen); 2025b812eb00SGeert Uytterhoeven ret = -EINVAL; 2026b812eb00SGeert Uytterhoeven goto out; 2027b812eb00SGeert Uytterhoeven } 2028b812eb00SGeert Uytterhoeven 202933607384SMahipal Challa if (memcmp(decomp_output, dtemplate[i].output, dlen)) { 2030da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: Decompression test %d " 2031da7f033dSHerbert Xu "failed for %s\n", i + 1, algo); 203233607384SMahipal Challa hexdump(decomp_output, dlen); 2033da7f033dSHerbert Xu ret = -EINVAL; 2034da7f033dSHerbert Xu goto out; 2035da7f033dSHerbert Xu } 2036da7f033dSHerbert Xu } 2037da7f033dSHerbert Xu 2038da7f033dSHerbert Xu ret = 0; 2039da7f033dSHerbert Xu 2040da7f033dSHerbert Xu out: 204133607384SMahipal Challa kfree(decomp_output); 204233607384SMahipal Challa kfree(output); 2043da7f033dSHerbert Xu return ret; 2044da7f033dSHerbert Xu } 2045da7f033dSHerbert Xu 2046b13b1e0cSEric Biggers static int test_acomp(struct crypto_acomp *tfm, 2047b13b1e0cSEric Biggers const struct comp_testvec *ctemplate, 2048b13b1e0cSEric Biggers const struct comp_testvec *dtemplate, 2049b13b1e0cSEric Biggers int ctcount, int dtcount) 2050d7db7a88SGiovanni Cabiddu { 2051d7db7a88SGiovanni Cabiddu const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); 2052d7db7a88SGiovanni Cabiddu unsigned int i; 2053a9943a0aSGiovanni Cabiddu char *output, *decomp_out; 2054d7db7a88SGiovanni Cabiddu int ret; 2055d7db7a88SGiovanni Cabiddu struct scatterlist src, dst; 2056d7db7a88SGiovanni Cabiddu struct acomp_req *req; 20577f397136SGilad Ben-Yossef struct crypto_wait wait; 2058d7db7a88SGiovanni Cabiddu 2059eb095593SEric Biggers output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 2060eb095593SEric Biggers if (!output) 2061eb095593SEric Biggers return -ENOMEM; 2062eb095593SEric Biggers 2063a9943a0aSGiovanni Cabiddu decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 2064a9943a0aSGiovanni Cabiddu if (!decomp_out) { 2065a9943a0aSGiovanni Cabiddu kfree(output); 2066a9943a0aSGiovanni Cabiddu return -ENOMEM; 2067a9943a0aSGiovanni Cabiddu } 2068a9943a0aSGiovanni Cabiddu 2069d7db7a88SGiovanni Cabiddu for (i = 0; i < ctcount; i++) { 2070d7db7a88SGiovanni Cabiddu unsigned int dlen = COMP_BUF_SIZE; 2071d7db7a88SGiovanni Cabiddu int ilen = ctemplate[i].inlen; 207202608e02SLaura Abbott void *input_vec; 2073d7db7a88SGiovanni Cabiddu 2074d2110224SEric Biggers input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); 207502608e02SLaura Abbott if (!input_vec) { 207602608e02SLaura Abbott ret = -ENOMEM; 207702608e02SLaura Abbott goto out; 207802608e02SLaura Abbott } 207902608e02SLaura Abbott 2080eb095593SEric Biggers memset(output, 0, dlen); 20817f397136SGilad Ben-Yossef crypto_init_wait(&wait); 208202608e02SLaura Abbott sg_init_one(&src, input_vec, ilen); 2083d7db7a88SGiovanni Cabiddu sg_init_one(&dst, output, dlen); 2084d7db7a88SGiovanni Cabiddu 2085d7db7a88SGiovanni Cabiddu req = acomp_request_alloc(tfm); 2086d7db7a88SGiovanni Cabiddu if (!req) { 2087d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: request alloc failed for %s\n", 2088d7db7a88SGiovanni Cabiddu algo); 208902608e02SLaura Abbott kfree(input_vec); 2090d7db7a88SGiovanni Cabiddu ret = -ENOMEM; 2091d7db7a88SGiovanni Cabiddu goto out; 2092d7db7a88SGiovanni Cabiddu } 2093d7db7a88SGiovanni Cabiddu 2094d7db7a88SGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 2095d7db7a88SGiovanni Cabiddu acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 20967f397136SGilad Ben-Yossef crypto_req_done, &wait); 2097d7db7a88SGiovanni Cabiddu 20987f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_compress(req), &wait); 2099d7db7a88SGiovanni Cabiddu if (ret) { 2100d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 2101d7db7a88SGiovanni Cabiddu i + 1, algo, -ret); 210202608e02SLaura Abbott kfree(input_vec); 2103d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2104d7db7a88SGiovanni Cabiddu goto out; 2105d7db7a88SGiovanni Cabiddu } 2106d7db7a88SGiovanni Cabiddu 2107a9943a0aSGiovanni Cabiddu ilen = req->dlen; 2108a9943a0aSGiovanni Cabiddu dlen = COMP_BUF_SIZE; 2109a9943a0aSGiovanni Cabiddu sg_init_one(&src, output, ilen); 2110a9943a0aSGiovanni Cabiddu sg_init_one(&dst, decomp_out, dlen); 21117f397136SGilad Ben-Yossef crypto_init_wait(&wait); 2112a9943a0aSGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 2113a9943a0aSGiovanni Cabiddu 21147f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 2115a9943a0aSGiovanni Cabiddu if (ret) { 2116a9943a0aSGiovanni Cabiddu pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 2117a9943a0aSGiovanni Cabiddu i + 1, algo, -ret); 2118a9943a0aSGiovanni Cabiddu kfree(input_vec); 2119a9943a0aSGiovanni Cabiddu acomp_request_free(req); 2120a9943a0aSGiovanni Cabiddu goto out; 2121a9943a0aSGiovanni Cabiddu } 2122a9943a0aSGiovanni Cabiddu 2123a9943a0aSGiovanni Cabiddu if (req->dlen != ctemplate[i].inlen) { 2124d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", 2125d7db7a88SGiovanni Cabiddu i + 1, algo, req->dlen); 2126d7db7a88SGiovanni Cabiddu ret = -EINVAL; 212702608e02SLaura Abbott kfree(input_vec); 2128d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2129d7db7a88SGiovanni Cabiddu goto out; 2130d7db7a88SGiovanni Cabiddu } 2131d7db7a88SGiovanni Cabiddu 2132a9943a0aSGiovanni Cabiddu if (memcmp(input_vec, decomp_out, req->dlen)) { 2133d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Compression test %d failed for %s\n", 2134d7db7a88SGiovanni Cabiddu i + 1, algo); 2135d7db7a88SGiovanni Cabiddu hexdump(output, req->dlen); 2136d7db7a88SGiovanni Cabiddu ret = -EINVAL; 213702608e02SLaura Abbott kfree(input_vec); 2138d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2139d7db7a88SGiovanni Cabiddu goto out; 2140d7db7a88SGiovanni Cabiddu } 2141d7db7a88SGiovanni Cabiddu 214202608e02SLaura Abbott kfree(input_vec); 2143d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2144d7db7a88SGiovanni Cabiddu } 2145d7db7a88SGiovanni Cabiddu 2146d7db7a88SGiovanni Cabiddu for (i = 0; i < dtcount; i++) { 2147d7db7a88SGiovanni Cabiddu unsigned int dlen = COMP_BUF_SIZE; 2148d7db7a88SGiovanni Cabiddu int ilen = dtemplate[i].inlen; 214902608e02SLaura Abbott void *input_vec; 2150d7db7a88SGiovanni Cabiddu 2151d2110224SEric Biggers input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL); 215202608e02SLaura Abbott if (!input_vec) { 215302608e02SLaura Abbott ret = -ENOMEM; 215402608e02SLaura Abbott goto out; 215502608e02SLaura Abbott } 215602608e02SLaura Abbott 2157eb095593SEric Biggers memset(output, 0, dlen); 21587f397136SGilad Ben-Yossef crypto_init_wait(&wait); 215902608e02SLaura Abbott sg_init_one(&src, input_vec, ilen); 2160d7db7a88SGiovanni Cabiddu sg_init_one(&dst, output, dlen); 2161d7db7a88SGiovanni Cabiddu 2162d7db7a88SGiovanni Cabiddu req = acomp_request_alloc(tfm); 2163d7db7a88SGiovanni Cabiddu if (!req) { 2164d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: request alloc failed for %s\n", 2165d7db7a88SGiovanni Cabiddu algo); 216602608e02SLaura Abbott kfree(input_vec); 2167d7db7a88SGiovanni Cabiddu ret = -ENOMEM; 2168d7db7a88SGiovanni Cabiddu goto out; 2169d7db7a88SGiovanni Cabiddu } 2170d7db7a88SGiovanni Cabiddu 2171d7db7a88SGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 2172d7db7a88SGiovanni Cabiddu acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 21737f397136SGilad Ben-Yossef crypto_req_done, &wait); 2174d7db7a88SGiovanni Cabiddu 21757f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 2176d7db7a88SGiovanni Cabiddu if (ret) { 2177d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n", 2178d7db7a88SGiovanni Cabiddu i + 1, algo, -ret); 217902608e02SLaura Abbott kfree(input_vec); 2180d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2181d7db7a88SGiovanni Cabiddu goto out; 2182d7db7a88SGiovanni Cabiddu } 2183d7db7a88SGiovanni Cabiddu 2184d7db7a88SGiovanni Cabiddu if (req->dlen != dtemplate[i].outlen) { 2185d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n", 2186d7db7a88SGiovanni Cabiddu i + 1, algo, req->dlen); 2187d7db7a88SGiovanni Cabiddu ret = -EINVAL; 218802608e02SLaura Abbott kfree(input_vec); 2189d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2190d7db7a88SGiovanni Cabiddu goto out; 2191d7db7a88SGiovanni Cabiddu } 2192d7db7a88SGiovanni Cabiddu 2193d7db7a88SGiovanni Cabiddu if (memcmp(output, dtemplate[i].output, req->dlen)) { 2194d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Decompression test %d failed for %s\n", 2195d7db7a88SGiovanni Cabiddu i + 1, algo); 2196d7db7a88SGiovanni Cabiddu hexdump(output, req->dlen); 2197d7db7a88SGiovanni Cabiddu ret = -EINVAL; 219802608e02SLaura Abbott kfree(input_vec); 2199d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2200d7db7a88SGiovanni Cabiddu goto out; 2201d7db7a88SGiovanni Cabiddu } 2202d7db7a88SGiovanni Cabiddu 220302608e02SLaura Abbott kfree(input_vec); 2204d7db7a88SGiovanni Cabiddu acomp_request_free(req); 2205d7db7a88SGiovanni Cabiddu } 2206d7db7a88SGiovanni Cabiddu 2207d7db7a88SGiovanni Cabiddu ret = 0; 2208d7db7a88SGiovanni Cabiddu 2209d7db7a88SGiovanni Cabiddu out: 2210a9943a0aSGiovanni Cabiddu kfree(decomp_out); 2211eb095593SEric Biggers kfree(output); 2212d7db7a88SGiovanni Cabiddu return ret; 2213d7db7a88SGiovanni Cabiddu } 2214d7db7a88SGiovanni Cabiddu 2215b13b1e0cSEric Biggers static int test_cprng(struct crypto_rng *tfm, 2216b13b1e0cSEric Biggers const struct cprng_testvec *template, 22177647d6ceSJarod Wilson unsigned int tcount) 22187647d6ceSJarod Wilson { 22197647d6ceSJarod Wilson const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); 2220fa4ef8a6SFelipe Contreras int err = 0, i, j, seedsize; 22217647d6ceSJarod Wilson u8 *seed; 22227647d6ceSJarod Wilson char result[32]; 22237647d6ceSJarod Wilson 22247647d6ceSJarod Wilson seedsize = crypto_rng_seedsize(tfm); 22257647d6ceSJarod Wilson 22267647d6ceSJarod Wilson seed = kmalloc(seedsize, GFP_KERNEL); 22277647d6ceSJarod Wilson if (!seed) { 22287647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to allocate seed space " 22297647d6ceSJarod Wilson "for %s\n", algo); 22307647d6ceSJarod Wilson return -ENOMEM; 22317647d6ceSJarod Wilson } 22327647d6ceSJarod Wilson 22337647d6ceSJarod Wilson for (i = 0; i < tcount; i++) { 22347647d6ceSJarod Wilson memset(result, 0, 32); 22357647d6ceSJarod Wilson 22367647d6ceSJarod Wilson memcpy(seed, template[i].v, template[i].vlen); 22377647d6ceSJarod Wilson memcpy(seed + template[i].vlen, template[i].key, 22387647d6ceSJarod Wilson template[i].klen); 22397647d6ceSJarod Wilson memcpy(seed + template[i].vlen + template[i].klen, 22407647d6ceSJarod Wilson template[i].dt, template[i].dtlen); 22417647d6ceSJarod Wilson 22427647d6ceSJarod Wilson err = crypto_rng_reset(tfm, seed, seedsize); 22437647d6ceSJarod Wilson if (err) { 22447647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to reset rng " 22457647d6ceSJarod Wilson "for %s\n", algo); 22467647d6ceSJarod Wilson goto out; 22477647d6ceSJarod Wilson } 22487647d6ceSJarod Wilson 22497647d6ceSJarod Wilson for (j = 0; j < template[i].loops; j++) { 22507647d6ceSJarod Wilson err = crypto_rng_get_bytes(tfm, result, 22517647d6ceSJarod Wilson template[i].rlen); 225219e60e13SStephan Mueller if (err < 0) { 22537647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to obtain " 22547647d6ceSJarod Wilson "the correct amount of random data for " 225519e60e13SStephan Mueller "%s (requested %d)\n", algo, 225619e60e13SStephan Mueller template[i].rlen); 22577647d6ceSJarod Wilson goto out; 22587647d6ceSJarod Wilson } 22597647d6ceSJarod Wilson } 22607647d6ceSJarod Wilson 22617647d6ceSJarod Wilson err = memcmp(result, template[i].result, 22627647d6ceSJarod Wilson template[i].rlen); 22637647d6ceSJarod Wilson if (err) { 22647647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Test %d failed for %s\n", 22657647d6ceSJarod Wilson i, algo); 22667647d6ceSJarod Wilson hexdump(result, template[i].rlen); 22677647d6ceSJarod Wilson err = -EINVAL; 22687647d6ceSJarod Wilson goto out; 22697647d6ceSJarod Wilson } 22707647d6ceSJarod Wilson } 22717647d6ceSJarod Wilson 22727647d6ceSJarod Wilson out: 22737647d6ceSJarod Wilson kfree(seed); 22747647d6ceSJarod Wilson return err; 22757647d6ceSJarod Wilson } 22767647d6ceSJarod Wilson 2277da7f033dSHerbert Xu static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, 2278da7f033dSHerbert Xu u32 type, u32 mask) 2279da7f033dSHerbert Xu { 2280a0d608eeSEric Biggers const struct aead_test_suite *suite = &desc->suite.aead; 2281da7f033dSHerbert Xu struct crypto_aead *tfm; 2282a0d608eeSEric Biggers int err; 2283da7f033dSHerbert Xu 2284eed93e0cSHerbert Xu tfm = crypto_alloc_aead(driver, type, mask); 2285da7f033dSHerbert Xu if (IS_ERR(tfm)) { 2286da7f033dSHerbert Xu printk(KERN_ERR "alg: aead: Failed to load transform for %s: " 2287da7f033dSHerbert Xu "%ld\n", driver, PTR_ERR(tfm)); 2288da7f033dSHerbert Xu return PTR_ERR(tfm); 2289da7f033dSHerbert Xu } 2290da7f033dSHerbert Xu 2291a0d608eeSEric Biggers err = test_aead(tfm, ENCRYPT, suite->vecs, suite->count); 2292a0d608eeSEric Biggers if (!err) 2293a0d608eeSEric Biggers err = test_aead(tfm, DECRYPT, suite->vecs, suite->count); 2294da7f033dSHerbert Xu 2295da7f033dSHerbert Xu crypto_free_aead(tfm); 2296da7f033dSHerbert Xu return err; 2297da7f033dSHerbert Xu } 2298da7f033dSHerbert Xu 2299da7f033dSHerbert Xu static int alg_test_cipher(const struct alg_test_desc *desc, 2300da7f033dSHerbert Xu const char *driver, u32 type, u32 mask) 2301da7f033dSHerbert Xu { 230292a4c9feSEric Biggers const struct cipher_test_suite *suite = &desc->suite.cipher; 23031aa4ecd9SHerbert Xu struct crypto_cipher *tfm; 230492a4c9feSEric Biggers int err; 2305da7f033dSHerbert Xu 2306eed93e0cSHerbert Xu tfm = crypto_alloc_cipher(driver, type, mask); 2307da7f033dSHerbert Xu if (IS_ERR(tfm)) { 2308da7f033dSHerbert Xu printk(KERN_ERR "alg: cipher: Failed to load transform for " 2309da7f033dSHerbert Xu "%s: %ld\n", driver, PTR_ERR(tfm)); 2310da7f033dSHerbert Xu return PTR_ERR(tfm); 2311da7f033dSHerbert Xu } 2312da7f033dSHerbert Xu 231392a4c9feSEric Biggers err = test_cipher(tfm, ENCRYPT, suite->vecs, suite->count); 231492a4c9feSEric Biggers if (!err) 231592a4c9feSEric Biggers err = test_cipher(tfm, DECRYPT, suite->vecs, suite->count); 2316da7f033dSHerbert Xu 23171aa4ecd9SHerbert Xu crypto_free_cipher(tfm); 23181aa4ecd9SHerbert Xu return err; 23191aa4ecd9SHerbert Xu } 23201aa4ecd9SHerbert Xu 2321da7f033dSHerbert Xu static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, 2322da7f033dSHerbert Xu u32 type, u32 mask) 2323da7f033dSHerbert Xu { 2324d7db7a88SGiovanni Cabiddu struct crypto_comp *comp; 2325d7db7a88SGiovanni Cabiddu struct crypto_acomp *acomp; 2326da7f033dSHerbert Xu int err; 2327d7db7a88SGiovanni Cabiddu u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK; 2328da7f033dSHerbert Xu 2329d7db7a88SGiovanni Cabiddu if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) { 2330d7db7a88SGiovanni Cabiddu acomp = crypto_alloc_acomp(driver, type, mask); 2331d7db7a88SGiovanni Cabiddu if (IS_ERR(acomp)) { 2332d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Failed to load transform for %s: %ld\n", 2333d7db7a88SGiovanni Cabiddu driver, PTR_ERR(acomp)); 2334d7db7a88SGiovanni Cabiddu return PTR_ERR(acomp); 2335d7db7a88SGiovanni Cabiddu } 2336d7db7a88SGiovanni Cabiddu err = test_acomp(acomp, desc->suite.comp.comp.vecs, 2337d7db7a88SGiovanni Cabiddu desc->suite.comp.decomp.vecs, 2338d7db7a88SGiovanni Cabiddu desc->suite.comp.comp.count, 2339d7db7a88SGiovanni Cabiddu desc->suite.comp.decomp.count); 2340d7db7a88SGiovanni Cabiddu crypto_free_acomp(acomp); 2341d7db7a88SGiovanni Cabiddu } else { 2342d7db7a88SGiovanni Cabiddu comp = crypto_alloc_comp(driver, type, mask); 2343d7db7a88SGiovanni Cabiddu if (IS_ERR(comp)) { 2344d7db7a88SGiovanni Cabiddu pr_err("alg: comp: Failed to load transform for %s: %ld\n", 2345d7db7a88SGiovanni Cabiddu driver, PTR_ERR(comp)); 2346d7db7a88SGiovanni Cabiddu return PTR_ERR(comp); 2347da7f033dSHerbert Xu } 2348da7f033dSHerbert Xu 2349d7db7a88SGiovanni Cabiddu err = test_comp(comp, desc->suite.comp.comp.vecs, 2350da7f033dSHerbert Xu desc->suite.comp.decomp.vecs, 2351da7f033dSHerbert Xu desc->suite.comp.comp.count, 2352da7f033dSHerbert Xu desc->suite.comp.decomp.count); 2353da7f033dSHerbert Xu 2354d7db7a88SGiovanni Cabiddu crypto_free_comp(comp); 2355d7db7a88SGiovanni Cabiddu } 2356da7f033dSHerbert Xu return err; 2357da7f033dSHerbert Xu } 2358da7f033dSHerbert Xu 23599b3abc01SEric Biggers static int __alg_test_hash(const struct hash_testvec *template, 23609b3abc01SEric Biggers unsigned int tcount, const char *driver, 2361da7f033dSHerbert Xu u32 type, u32 mask) 2362da7f033dSHerbert Xu { 2363da7f033dSHerbert Xu struct crypto_ahash *tfm; 2364da7f033dSHerbert Xu int err; 2365da7f033dSHerbert Xu 2366eed93e0cSHerbert Xu tfm = crypto_alloc_ahash(driver, type, mask); 2367da7f033dSHerbert Xu if (IS_ERR(tfm)) { 2368da7f033dSHerbert Xu printk(KERN_ERR "alg: hash: Failed to load transform for %s: " 2369da7f033dSHerbert Xu "%ld\n", driver, PTR_ERR(tfm)); 2370da7f033dSHerbert Xu return PTR_ERR(tfm); 2371da7f033dSHerbert Xu } 2372da7f033dSHerbert Xu 237376715095SGilad Ben-Yossef err = test_hash(tfm, template, tcount, HASH_TEST_DIGEST); 2374a8f1a052SDavid S. Miller if (!err) 237576715095SGilad Ben-Yossef err = test_hash(tfm, template, tcount, HASH_TEST_FINAL); 237676715095SGilad Ben-Yossef if (!err) 237776715095SGilad Ben-Yossef err = test_hash(tfm, template, tcount, HASH_TEST_FINUP); 2378da7f033dSHerbert Xu crypto_free_ahash(tfm); 2379da7f033dSHerbert Xu return err; 2380da7f033dSHerbert Xu } 2381da7f033dSHerbert Xu 23829b3abc01SEric Biggers static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, 23839b3abc01SEric Biggers u32 type, u32 mask) 23849b3abc01SEric Biggers { 23859b3abc01SEric Biggers const struct hash_testvec *template = desc->suite.hash.vecs; 23869b3abc01SEric Biggers unsigned int tcount = desc->suite.hash.count; 23879b3abc01SEric Biggers unsigned int nr_unkeyed, nr_keyed; 23889b3abc01SEric Biggers int err; 23899b3abc01SEric Biggers 23909b3abc01SEric Biggers /* 23919b3abc01SEric Biggers * For OPTIONAL_KEY algorithms, we have to do all the unkeyed tests 23929b3abc01SEric Biggers * first, before setting a key on the tfm. To make this easier, we 23939b3abc01SEric Biggers * require that the unkeyed test vectors (if any) are listed first. 23949b3abc01SEric Biggers */ 23959b3abc01SEric Biggers 23969b3abc01SEric Biggers for (nr_unkeyed = 0; nr_unkeyed < tcount; nr_unkeyed++) { 23979b3abc01SEric Biggers if (template[nr_unkeyed].ksize) 23989b3abc01SEric Biggers break; 23999b3abc01SEric Biggers } 24009b3abc01SEric Biggers for (nr_keyed = 0; nr_unkeyed + nr_keyed < tcount; nr_keyed++) { 24019b3abc01SEric Biggers if (!template[nr_unkeyed + nr_keyed].ksize) { 24029b3abc01SEric Biggers pr_err("alg: hash: test vectors for %s out of order, " 24039b3abc01SEric Biggers "unkeyed ones must come first\n", desc->alg); 24049b3abc01SEric Biggers return -EINVAL; 24059b3abc01SEric Biggers } 24069b3abc01SEric Biggers } 24079b3abc01SEric Biggers 24089b3abc01SEric Biggers err = 0; 24099b3abc01SEric Biggers if (nr_unkeyed) { 24109b3abc01SEric Biggers err = __alg_test_hash(template, nr_unkeyed, driver, type, mask); 24119b3abc01SEric Biggers template += nr_unkeyed; 24129b3abc01SEric Biggers } 24139b3abc01SEric Biggers 24149b3abc01SEric Biggers if (!err && nr_keyed) 24159b3abc01SEric Biggers err = __alg_test_hash(template, nr_keyed, driver, type, mask); 24169b3abc01SEric Biggers 24179b3abc01SEric Biggers return err; 24189b3abc01SEric Biggers } 24199b3abc01SEric Biggers 24208e3ee85eSHerbert Xu static int alg_test_crc32c(const struct alg_test_desc *desc, 24218e3ee85eSHerbert Xu const char *driver, u32 type, u32 mask) 24228e3ee85eSHerbert Xu { 24238e3ee85eSHerbert Xu struct crypto_shash *tfm; 2424cb9dde88SEric Biggers __le32 val; 24258e3ee85eSHerbert Xu int err; 24268e3ee85eSHerbert Xu 24278e3ee85eSHerbert Xu err = alg_test_hash(desc, driver, type, mask); 24288e3ee85eSHerbert Xu if (err) 2429eb5e6730SEric Biggers return err; 24308e3ee85eSHerbert Xu 2431eed93e0cSHerbert Xu tfm = crypto_alloc_shash(driver, type, mask); 24328e3ee85eSHerbert Xu if (IS_ERR(tfm)) { 2433eb5e6730SEric Biggers if (PTR_ERR(tfm) == -ENOENT) { 2434eb5e6730SEric Biggers /* 2435eb5e6730SEric Biggers * This crc32c implementation is only available through 2436eb5e6730SEric Biggers * ahash API, not the shash API, so the remaining part 2437eb5e6730SEric Biggers * of the test is not applicable to it. 2438eb5e6730SEric Biggers */ 2439eb5e6730SEric Biggers return 0; 2440eb5e6730SEric Biggers } 24418e3ee85eSHerbert Xu printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: " 24428e3ee85eSHerbert Xu "%ld\n", driver, PTR_ERR(tfm)); 2443eb5e6730SEric Biggers return PTR_ERR(tfm); 24448e3ee85eSHerbert Xu } 24458e3ee85eSHerbert Xu 24468e3ee85eSHerbert Xu do { 24474c5c3024SJan-Simon Möller SHASH_DESC_ON_STACK(shash, tfm); 24484c5c3024SJan-Simon Möller u32 *ctx = (u32 *)shash_desc_ctx(shash); 24498e3ee85eSHerbert Xu 24504c5c3024SJan-Simon Möller shash->tfm = tfm; 24514c5c3024SJan-Simon Möller shash->flags = 0; 24528e3ee85eSHerbert Xu 2453cb9dde88SEric Biggers *ctx = 420553207; 24544c5c3024SJan-Simon Möller err = crypto_shash_final(shash, (u8 *)&val); 24558e3ee85eSHerbert Xu if (err) { 24568e3ee85eSHerbert Xu printk(KERN_ERR "alg: crc32c: Operation failed for " 24578e3ee85eSHerbert Xu "%s: %d\n", driver, err); 24588e3ee85eSHerbert Xu break; 24598e3ee85eSHerbert Xu } 24608e3ee85eSHerbert Xu 2461cb9dde88SEric Biggers if (val != cpu_to_le32(~420553207)) { 2462cb9dde88SEric Biggers pr_err("alg: crc32c: Test failed for %s: %u\n", 2463cb9dde88SEric Biggers driver, le32_to_cpu(val)); 24648e3ee85eSHerbert Xu err = -EINVAL; 24658e3ee85eSHerbert Xu } 24668e3ee85eSHerbert Xu } while (0); 24678e3ee85eSHerbert Xu 24688e3ee85eSHerbert Xu crypto_free_shash(tfm); 24698e3ee85eSHerbert Xu 24708e3ee85eSHerbert Xu return err; 24718e3ee85eSHerbert Xu } 24728e3ee85eSHerbert Xu 24737647d6ceSJarod Wilson static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, 24747647d6ceSJarod Wilson u32 type, u32 mask) 24757647d6ceSJarod Wilson { 24767647d6ceSJarod Wilson struct crypto_rng *rng; 24777647d6ceSJarod Wilson int err; 24787647d6ceSJarod Wilson 2479eed93e0cSHerbert Xu rng = crypto_alloc_rng(driver, type, mask); 24807647d6ceSJarod Wilson if (IS_ERR(rng)) { 24817647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " 24827647d6ceSJarod Wilson "%ld\n", driver, PTR_ERR(rng)); 24837647d6ceSJarod Wilson return PTR_ERR(rng); 24847647d6ceSJarod Wilson } 24857647d6ceSJarod Wilson 24867647d6ceSJarod Wilson err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count); 24877647d6ceSJarod Wilson 24887647d6ceSJarod Wilson crypto_free_rng(rng); 24897647d6ceSJarod Wilson 24907647d6ceSJarod Wilson return err; 24917647d6ceSJarod Wilson } 24927647d6ceSJarod Wilson 249364d1cdfbSStephan Mueller 2494b13b1e0cSEric Biggers static int drbg_cavs_test(const struct drbg_testvec *test, int pr, 249564d1cdfbSStephan Mueller const char *driver, u32 type, u32 mask) 249664d1cdfbSStephan Mueller { 249764d1cdfbSStephan Mueller int ret = -EAGAIN; 249864d1cdfbSStephan Mueller struct crypto_rng *drng; 249964d1cdfbSStephan Mueller struct drbg_test_data test_data; 250064d1cdfbSStephan Mueller struct drbg_string addtl, pers, testentropy; 250164d1cdfbSStephan Mueller unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL); 250264d1cdfbSStephan Mueller 250364d1cdfbSStephan Mueller if (!buf) 250464d1cdfbSStephan Mueller return -ENOMEM; 250564d1cdfbSStephan Mueller 2506eed93e0cSHerbert Xu drng = crypto_alloc_rng(driver, type, mask); 250764d1cdfbSStephan Mueller if (IS_ERR(drng)) { 250864d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " 250964d1cdfbSStephan Mueller "%s\n", driver); 251064d1cdfbSStephan Mueller kzfree(buf); 251164d1cdfbSStephan Mueller return -ENOMEM; 251264d1cdfbSStephan Mueller } 251364d1cdfbSStephan Mueller 251464d1cdfbSStephan Mueller test_data.testentropy = &testentropy; 251564d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entropy, test->entropylen); 251664d1cdfbSStephan Mueller drbg_string_fill(&pers, test->pers, test->perslen); 251764d1cdfbSStephan Mueller ret = crypto_drbg_reset_test(drng, &pers, &test_data); 251864d1cdfbSStephan Mueller if (ret) { 251964d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: Failed to reset rng\n"); 252064d1cdfbSStephan Mueller goto outbuf; 252164d1cdfbSStephan Mueller } 252264d1cdfbSStephan Mueller 252364d1cdfbSStephan Mueller drbg_string_fill(&addtl, test->addtla, test->addtllen); 252464d1cdfbSStephan Mueller if (pr) { 252564d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entpra, test->entprlen); 252664d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl_test(drng, 252764d1cdfbSStephan Mueller buf, test->expectedlen, &addtl, &test_data); 252864d1cdfbSStephan Mueller } else { 252964d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl(drng, 253064d1cdfbSStephan Mueller buf, test->expectedlen, &addtl); 253164d1cdfbSStephan Mueller } 253219e60e13SStephan Mueller if (ret < 0) { 253364d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not obtain random data for " 253464d1cdfbSStephan Mueller "driver %s\n", driver); 253564d1cdfbSStephan Mueller goto outbuf; 253664d1cdfbSStephan Mueller } 253764d1cdfbSStephan Mueller 253864d1cdfbSStephan Mueller drbg_string_fill(&addtl, test->addtlb, test->addtllen); 253964d1cdfbSStephan Mueller if (pr) { 254064d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entprb, test->entprlen); 254164d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl_test(drng, 254264d1cdfbSStephan Mueller buf, test->expectedlen, &addtl, &test_data); 254364d1cdfbSStephan Mueller } else { 254464d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl(drng, 254564d1cdfbSStephan Mueller buf, test->expectedlen, &addtl); 254664d1cdfbSStephan Mueller } 254719e60e13SStephan Mueller if (ret < 0) { 254864d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not obtain random data for " 254964d1cdfbSStephan Mueller "driver %s\n", driver); 255064d1cdfbSStephan Mueller goto outbuf; 255164d1cdfbSStephan Mueller } 255264d1cdfbSStephan Mueller 255364d1cdfbSStephan Mueller ret = memcmp(test->expected, buf, test->expectedlen); 255464d1cdfbSStephan Mueller 255564d1cdfbSStephan Mueller outbuf: 255664d1cdfbSStephan Mueller crypto_free_rng(drng); 255764d1cdfbSStephan Mueller kzfree(buf); 255864d1cdfbSStephan Mueller return ret; 255964d1cdfbSStephan Mueller } 256064d1cdfbSStephan Mueller 256164d1cdfbSStephan Mueller 256264d1cdfbSStephan Mueller static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, 256364d1cdfbSStephan Mueller u32 type, u32 mask) 256464d1cdfbSStephan Mueller { 256564d1cdfbSStephan Mueller int err = 0; 256664d1cdfbSStephan Mueller int pr = 0; 256764d1cdfbSStephan Mueller int i = 0; 2568b13b1e0cSEric Biggers const struct drbg_testvec *template = desc->suite.drbg.vecs; 256964d1cdfbSStephan Mueller unsigned int tcount = desc->suite.drbg.count; 257064d1cdfbSStephan Mueller 257164d1cdfbSStephan Mueller if (0 == memcmp(driver, "drbg_pr_", 8)) 257264d1cdfbSStephan Mueller pr = 1; 257364d1cdfbSStephan Mueller 257464d1cdfbSStephan Mueller for (i = 0; i < tcount; i++) { 257564d1cdfbSStephan Mueller err = drbg_cavs_test(&template[i], pr, driver, type, mask); 257664d1cdfbSStephan Mueller if (err) { 257764d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: Test %d failed for %s\n", 257864d1cdfbSStephan Mueller i, driver); 257964d1cdfbSStephan Mueller err = -EINVAL; 258064d1cdfbSStephan Mueller break; 258164d1cdfbSStephan Mueller } 258264d1cdfbSStephan Mueller } 258364d1cdfbSStephan Mueller return err; 258464d1cdfbSStephan Mueller 258564d1cdfbSStephan Mueller } 258664d1cdfbSStephan Mueller 2587b13b1e0cSEric Biggers static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, 2588802c7f1cSSalvatore Benedetto const char *alg) 2589802c7f1cSSalvatore Benedetto { 2590802c7f1cSSalvatore Benedetto struct kpp_request *req; 2591802c7f1cSSalvatore Benedetto void *input_buf = NULL; 2592802c7f1cSSalvatore Benedetto void *output_buf = NULL; 259347d3fd39STudor-Dan Ambarus void *a_public = NULL; 259447d3fd39STudor-Dan Ambarus void *a_ss = NULL; 259547d3fd39STudor-Dan Ambarus void *shared_secret = NULL; 25967f397136SGilad Ben-Yossef struct crypto_wait wait; 2597802c7f1cSSalvatore Benedetto unsigned int out_len_max; 2598802c7f1cSSalvatore Benedetto int err = -ENOMEM; 2599802c7f1cSSalvatore Benedetto struct scatterlist src, dst; 2600802c7f1cSSalvatore Benedetto 2601802c7f1cSSalvatore Benedetto req = kpp_request_alloc(tfm, GFP_KERNEL); 2602802c7f1cSSalvatore Benedetto if (!req) 2603802c7f1cSSalvatore Benedetto return err; 2604802c7f1cSSalvatore Benedetto 26057f397136SGilad Ben-Yossef crypto_init_wait(&wait); 2606802c7f1cSSalvatore Benedetto 2607802c7f1cSSalvatore Benedetto err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size); 2608802c7f1cSSalvatore Benedetto if (err < 0) 2609802c7f1cSSalvatore Benedetto goto free_req; 2610802c7f1cSSalvatore Benedetto 2611802c7f1cSSalvatore Benedetto out_len_max = crypto_kpp_maxsize(tfm); 2612802c7f1cSSalvatore Benedetto output_buf = kzalloc(out_len_max, GFP_KERNEL); 2613802c7f1cSSalvatore Benedetto if (!output_buf) { 2614802c7f1cSSalvatore Benedetto err = -ENOMEM; 2615802c7f1cSSalvatore Benedetto goto free_req; 2616802c7f1cSSalvatore Benedetto } 2617802c7f1cSSalvatore Benedetto 2618802c7f1cSSalvatore Benedetto /* Use appropriate parameter as base */ 2619802c7f1cSSalvatore Benedetto kpp_request_set_input(req, NULL, 0); 2620802c7f1cSSalvatore Benedetto sg_init_one(&dst, output_buf, out_len_max); 2621802c7f1cSSalvatore Benedetto kpp_request_set_output(req, &dst, out_len_max); 2622802c7f1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 26237f397136SGilad Ben-Yossef crypto_req_done, &wait); 2624802c7f1cSSalvatore Benedetto 262547d3fd39STudor-Dan Ambarus /* Compute party A's public key */ 26267f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait); 2627802c7f1cSSalvatore Benedetto if (err) { 262847d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: generate public key test failed. err %d\n", 2629802c7f1cSSalvatore Benedetto alg, err); 2630802c7f1cSSalvatore Benedetto goto free_output; 2631802c7f1cSSalvatore Benedetto } 263247d3fd39STudor-Dan Ambarus 263347d3fd39STudor-Dan Ambarus if (vec->genkey) { 263447d3fd39STudor-Dan Ambarus /* Save party A's public key */ 2635e3d90e52SChristopher Diaz Riveros a_public = kmemdup(sg_virt(req->dst), out_len_max, GFP_KERNEL); 263647d3fd39STudor-Dan Ambarus if (!a_public) { 263747d3fd39STudor-Dan Ambarus err = -ENOMEM; 263847d3fd39STudor-Dan Ambarus goto free_output; 263947d3fd39STudor-Dan Ambarus } 264047d3fd39STudor-Dan Ambarus } else { 2641802c7f1cSSalvatore Benedetto /* Verify calculated public key */ 2642802c7f1cSSalvatore Benedetto if (memcmp(vec->expected_a_public, sg_virt(req->dst), 2643802c7f1cSSalvatore Benedetto vec->expected_a_public_size)) { 264447d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n", 2645802c7f1cSSalvatore Benedetto alg); 2646802c7f1cSSalvatore Benedetto err = -EINVAL; 2647802c7f1cSSalvatore Benedetto goto free_output; 2648802c7f1cSSalvatore Benedetto } 264947d3fd39STudor-Dan Ambarus } 2650802c7f1cSSalvatore Benedetto 2651802c7f1cSSalvatore Benedetto /* Calculate shared secret key by using counter part (b) public key. */ 2652e3d90e52SChristopher Diaz Riveros input_buf = kmemdup(vec->b_public, vec->b_public_size, GFP_KERNEL); 2653802c7f1cSSalvatore Benedetto if (!input_buf) { 2654802c7f1cSSalvatore Benedetto err = -ENOMEM; 2655802c7f1cSSalvatore Benedetto goto free_output; 2656802c7f1cSSalvatore Benedetto } 2657802c7f1cSSalvatore Benedetto 2658802c7f1cSSalvatore Benedetto sg_init_one(&src, input_buf, vec->b_public_size); 2659802c7f1cSSalvatore Benedetto sg_init_one(&dst, output_buf, out_len_max); 2660802c7f1cSSalvatore Benedetto kpp_request_set_input(req, &src, vec->b_public_size); 2661802c7f1cSSalvatore Benedetto kpp_request_set_output(req, &dst, out_len_max); 2662802c7f1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 26637f397136SGilad Ben-Yossef crypto_req_done, &wait); 26647f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait); 2665802c7f1cSSalvatore Benedetto if (err) { 266647d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n", 2667802c7f1cSSalvatore Benedetto alg, err); 2668802c7f1cSSalvatore Benedetto goto free_all; 2669802c7f1cSSalvatore Benedetto } 267047d3fd39STudor-Dan Ambarus 267147d3fd39STudor-Dan Ambarus if (vec->genkey) { 267247d3fd39STudor-Dan Ambarus /* Save the shared secret obtained by party A */ 2673e3d90e52SChristopher Diaz Riveros a_ss = kmemdup(sg_virt(req->dst), vec->expected_ss_size, GFP_KERNEL); 267447d3fd39STudor-Dan Ambarus if (!a_ss) { 267547d3fd39STudor-Dan Ambarus err = -ENOMEM; 267647d3fd39STudor-Dan Ambarus goto free_all; 267747d3fd39STudor-Dan Ambarus } 267847d3fd39STudor-Dan Ambarus 267947d3fd39STudor-Dan Ambarus /* 268047d3fd39STudor-Dan Ambarus * Calculate party B's shared secret by using party A's 268147d3fd39STudor-Dan Ambarus * public key. 268247d3fd39STudor-Dan Ambarus */ 268347d3fd39STudor-Dan Ambarus err = crypto_kpp_set_secret(tfm, vec->b_secret, 268447d3fd39STudor-Dan Ambarus vec->b_secret_size); 268547d3fd39STudor-Dan Ambarus if (err < 0) 268647d3fd39STudor-Dan Ambarus goto free_all; 268747d3fd39STudor-Dan Ambarus 268847d3fd39STudor-Dan Ambarus sg_init_one(&src, a_public, vec->expected_a_public_size); 268947d3fd39STudor-Dan Ambarus sg_init_one(&dst, output_buf, out_len_max); 269047d3fd39STudor-Dan Ambarus kpp_request_set_input(req, &src, vec->expected_a_public_size); 269147d3fd39STudor-Dan Ambarus kpp_request_set_output(req, &dst, out_len_max); 269247d3fd39STudor-Dan Ambarus kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 26937f397136SGilad Ben-Yossef crypto_req_done, &wait); 26947f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), 26957f397136SGilad Ben-Yossef &wait); 269647d3fd39STudor-Dan Ambarus if (err) { 269747d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", 269847d3fd39STudor-Dan Ambarus alg, err); 269947d3fd39STudor-Dan Ambarus goto free_all; 270047d3fd39STudor-Dan Ambarus } 270147d3fd39STudor-Dan Ambarus 270247d3fd39STudor-Dan Ambarus shared_secret = a_ss; 270347d3fd39STudor-Dan Ambarus } else { 270447d3fd39STudor-Dan Ambarus shared_secret = (void *)vec->expected_ss; 270547d3fd39STudor-Dan Ambarus } 270647d3fd39STudor-Dan Ambarus 2707802c7f1cSSalvatore Benedetto /* 2708802c7f1cSSalvatore Benedetto * verify shared secret from which the user will derive 2709802c7f1cSSalvatore Benedetto * secret key by executing whatever hash it has chosen 2710802c7f1cSSalvatore Benedetto */ 271147d3fd39STudor-Dan Ambarus if (memcmp(shared_secret, sg_virt(req->dst), 2712802c7f1cSSalvatore Benedetto vec->expected_ss_size)) { 2713802c7f1cSSalvatore Benedetto pr_err("alg: %s: compute shared secret test failed. Invalid output\n", 2714802c7f1cSSalvatore Benedetto alg); 2715802c7f1cSSalvatore Benedetto err = -EINVAL; 2716802c7f1cSSalvatore Benedetto } 2717802c7f1cSSalvatore Benedetto 2718802c7f1cSSalvatore Benedetto free_all: 271947d3fd39STudor-Dan Ambarus kfree(a_ss); 2720802c7f1cSSalvatore Benedetto kfree(input_buf); 2721802c7f1cSSalvatore Benedetto free_output: 272247d3fd39STudor-Dan Ambarus kfree(a_public); 2723802c7f1cSSalvatore Benedetto kfree(output_buf); 2724802c7f1cSSalvatore Benedetto free_req: 2725802c7f1cSSalvatore Benedetto kpp_request_free(req); 2726802c7f1cSSalvatore Benedetto return err; 2727802c7f1cSSalvatore Benedetto } 2728802c7f1cSSalvatore Benedetto 2729802c7f1cSSalvatore Benedetto static int test_kpp(struct crypto_kpp *tfm, const char *alg, 2730b13b1e0cSEric Biggers const struct kpp_testvec *vecs, unsigned int tcount) 2731802c7f1cSSalvatore Benedetto { 2732802c7f1cSSalvatore Benedetto int ret, i; 2733802c7f1cSSalvatore Benedetto 2734802c7f1cSSalvatore Benedetto for (i = 0; i < tcount; i++) { 2735802c7f1cSSalvatore Benedetto ret = do_test_kpp(tfm, vecs++, alg); 2736802c7f1cSSalvatore Benedetto if (ret) { 2737802c7f1cSSalvatore Benedetto pr_err("alg: %s: test failed on vector %d, err=%d\n", 2738802c7f1cSSalvatore Benedetto alg, i + 1, ret); 2739802c7f1cSSalvatore Benedetto return ret; 2740802c7f1cSSalvatore Benedetto } 2741802c7f1cSSalvatore Benedetto } 2742802c7f1cSSalvatore Benedetto return 0; 2743802c7f1cSSalvatore Benedetto } 2744802c7f1cSSalvatore Benedetto 2745802c7f1cSSalvatore Benedetto static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, 2746802c7f1cSSalvatore Benedetto u32 type, u32 mask) 2747802c7f1cSSalvatore Benedetto { 2748802c7f1cSSalvatore Benedetto struct crypto_kpp *tfm; 2749802c7f1cSSalvatore Benedetto int err = 0; 2750802c7f1cSSalvatore Benedetto 2751eed93e0cSHerbert Xu tfm = crypto_alloc_kpp(driver, type, mask); 2752802c7f1cSSalvatore Benedetto if (IS_ERR(tfm)) { 2753802c7f1cSSalvatore Benedetto pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", 2754802c7f1cSSalvatore Benedetto driver, PTR_ERR(tfm)); 2755802c7f1cSSalvatore Benedetto return PTR_ERR(tfm); 2756802c7f1cSSalvatore Benedetto } 2757802c7f1cSSalvatore Benedetto if (desc->suite.kpp.vecs) 2758802c7f1cSSalvatore Benedetto err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs, 2759802c7f1cSSalvatore Benedetto desc->suite.kpp.count); 2760802c7f1cSSalvatore Benedetto 2761802c7f1cSSalvatore Benedetto crypto_free_kpp(tfm); 2762802c7f1cSSalvatore Benedetto return err; 2763802c7f1cSSalvatore Benedetto } 2764802c7f1cSSalvatore Benedetto 276550d2b643SHerbert Xu static int test_akcipher_one(struct crypto_akcipher *tfm, 2766b13b1e0cSEric Biggers const struct akcipher_testvec *vecs) 2767946cc463STadeusz Struk { 2768df27b26fSHerbert Xu char *xbuf[XBUFSIZE]; 2769946cc463STadeusz Struk struct akcipher_request *req; 2770946cc463STadeusz Struk void *outbuf_enc = NULL; 2771946cc463STadeusz Struk void *outbuf_dec = NULL; 27727f397136SGilad Ben-Yossef struct crypto_wait wait; 2773946cc463STadeusz Struk unsigned int out_len_max, out_len = 0; 2774946cc463STadeusz Struk int err = -ENOMEM; 277522287b0bSTadeusz Struk struct scatterlist src, dst, src_tab[2]; 27760507de94SVitaly Chikunov const char *m, *c; 27770507de94SVitaly Chikunov unsigned int m_size, c_size; 27780507de94SVitaly Chikunov const char *op; 2779946cc463STadeusz Struk 2780df27b26fSHerbert Xu if (testmgr_alloc_buf(xbuf)) 2781df27b26fSHerbert Xu return err; 2782df27b26fSHerbert Xu 2783946cc463STadeusz Struk req = akcipher_request_alloc(tfm, GFP_KERNEL); 2784946cc463STadeusz Struk if (!req) 2785df27b26fSHerbert Xu goto free_xbuf; 2786946cc463STadeusz Struk 27877f397136SGilad Ben-Yossef crypto_init_wait(&wait); 278822287b0bSTadeusz Struk 278922287b0bSTadeusz Struk if (vecs->public_key_vec) 279022287b0bSTadeusz Struk err = crypto_akcipher_set_pub_key(tfm, vecs->key, 279122287b0bSTadeusz Struk vecs->key_len); 279222287b0bSTadeusz Struk else 279322287b0bSTadeusz Struk err = crypto_akcipher_set_priv_key(tfm, vecs->key, 279422287b0bSTadeusz Struk vecs->key_len); 2795946cc463STadeusz Struk if (err) 2796946cc463STadeusz Struk goto free_req; 2797946cc463STadeusz Struk 279857763f5eSSalvatore Benedetto err = -ENOMEM; 279922287b0bSTadeusz Struk out_len_max = crypto_akcipher_maxsize(tfm); 28000507de94SVitaly Chikunov 28010507de94SVitaly Chikunov /* 28020507de94SVitaly Chikunov * First run test which do not require a private key, such as 28030507de94SVitaly Chikunov * encrypt or verify. 28040507de94SVitaly Chikunov */ 2805946cc463STadeusz Struk outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); 2806946cc463STadeusz Struk if (!outbuf_enc) 2807946cc463STadeusz Struk goto free_req; 2808946cc463STadeusz Struk 28090507de94SVitaly Chikunov if (!vecs->siggen_sigver_test) { 28100507de94SVitaly Chikunov m = vecs->m; 28110507de94SVitaly Chikunov m_size = vecs->m_size; 28120507de94SVitaly Chikunov c = vecs->c; 28130507de94SVitaly Chikunov c_size = vecs->c_size; 28140507de94SVitaly Chikunov op = "encrypt"; 28150507de94SVitaly Chikunov } else { 28160507de94SVitaly Chikunov /* Swap args so we could keep plaintext (digest) 28170507de94SVitaly Chikunov * in vecs->m, and cooked signature in vecs->c. 28180507de94SVitaly Chikunov */ 28190507de94SVitaly Chikunov m = vecs->c; /* signature */ 28200507de94SVitaly Chikunov m_size = vecs->c_size; 28210507de94SVitaly Chikunov c = vecs->m; /* digest */ 28220507de94SVitaly Chikunov c_size = vecs->m_size; 28230507de94SVitaly Chikunov op = "verify"; 28240507de94SVitaly Chikunov } 2825df27b26fSHerbert Xu 28260507de94SVitaly Chikunov if (WARN_ON(m_size > PAGE_SIZE)) 28270507de94SVitaly Chikunov goto free_all; 28280507de94SVitaly Chikunov memcpy(xbuf[0], m, m_size); 2829df27b26fSHerbert Xu 283022287b0bSTadeusz Struk sg_init_table(src_tab, 2); 2831df27b26fSHerbert Xu sg_set_buf(&src_tab[0], xbuf[0], 8); 28320507de94SVitaly Chikunov sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8); 283322287b0bSTadeusz Struk sg_init_one(&dst, outbuf_enc, out_len_max); 28340507de94SVitaly Chikunov akcipher_request_set_crypt(req, src_tab, &dst, m_size, 283522287b0bSTadeusz Struk out_len_max); 2836946cc463STadeusz Struk akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 28377f397136SGilad Ben-Yossef crypto_req_done, &wait); 2838946cc463STadeusz Struk 28397f397136SGilad Ben-Yossef err = crypto_wait_req(vecs->siggen_sigver_test ? 28400507de94SVitaly Chikunov /* Run asymmetric signature verification */ 28410507de94SVitaly Chikunov crypto_akcipher_verify(req) : 28421207107cSStephan Mueller /* Run asymmetric encrypt */ 28437f397136SGilad Ben-Yossef crypto_akcipher_encrypt(req), &wait); 2844946cc463STadeusz Struk if (err) { 28450507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 2846946cc463STadeusz Struk goto free_all; 2847946cc463STadeusz Struk } 28480507de94SVitaly Chikunov if (req->dst_len != c_size) { 28490507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output len\n", 28500507de94SVitaly Chikunov op); 2851946cc463STadeusz Struk err = -EINVAL; 2852946cc463STadeusz Struk goto free_all; 2853946cc463STadeusz Struk } 2854946cc463STadeusz Struk /* verify that encrypted message is equal to expected */ 28550507de94SVitaly Chikunov if (memcmp(c, outbuf_enc, c_size)) { 28560507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 28570507de94SVitaly Chikunov hexdump(outbuf_enc, c_size); 2858946cc463STadeusz Struk err = -EINVAL; 2859946cc463STadeusz Struk goto free_all; 2860946cc463STadeusz Struk } 28610507de94SVitaly Chikunov 28620507de94SVitaly Chikunov /* 28630507de94SVitaly Chikunov * Don't invoke (decrypt or sign) test which require a private key 28640507de94SVitaly Chikunov * for vectors with only a public key. 28650507de94SVitaly Chikunov */ 2866946cc463STadeusz Struk if (vecs->public_key_vec) { 2867946cc463STadeusz Struk err = 0; 2868946cc463STadeusz Struk goto free_all; 2869946cc463STadeusz Struk } 2870946cc463STadeusz Struk outbuf_dec = kzalloc(out_len_max, GFP_KERNEL); 2871946cc463STadeusz Struk if (!outbuf_dec) { 2872946cc463STadeusz Struk err = -ENOMEM; 2873946cc463STadeusz Struk goto free_all; 2874946cc463STadeusz Struk } 2875df27b26fSHerbert Xu 28760507de94SVitaly Chikunov op = vecs->siggen_sigver_test ? "sign" : "decrypt"; 28770507de94SVitaly Chikunov if (WARN_ON(c_size > PAGE_SIZE)) 2878df27b26fSHerbert Xu goto free_all; 28790507de94SVitaly Chikunov memcpy(xbuf[0], c, c_size); 2880df27b26fSHerbert Xu 28810507de94SVitaly Chikunov sg_init_one(&src, xbuf[0], c_size); 288222287b0bSTadeusz Struk sg_init_one(&dst, outbuf_dec, out_len_max); 28837f397136SGilad Ben-Yossef crypto_init_wait(&wait); 28840507de94SVitaly Chikunov akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max); 2885946cc463STadeusz Struk 28867f397136SGilad Ben-Yossef err = crypto_wait_req(vecs->siggen_sigver_test ? 28870507de94SVitaly Chikunov /* Run asymmetric signature generation */ 28880507de94SVitaly Chikunov crypto_akcipher_sign(req) : 28891207107cSStephan Mueller /* Run asymmetric decrypt */ 28907f397136SGilad Ben-Yossef crypto_akcipher_decrypt(req), &wait); 2891946cc463STadeusz Struk if (err) { 28920507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 2893946cc463STadeusz Struk goto free_all; 2894946cc463STadeusz Struk } 2895946cc463STadeusz Struk out_len = req->dst_len; 28960507de94SVitaly Chikunov if (out_len < m_size) { 28970507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output len %u\n", 28980507de94SVitaly Chikunov op, out_len); 2899946cc463STadeusz Struk err = -EINVAL; 2900946cc463STadeusz Struk goto free_all; 2901946cc463STadeusz Struk } 2902946cc463STadeusz Struk /* verify that decrypted message is equal to the original msg */ 29030507de94SVitaly Chikunov if (memchr_inv(outbuf_dec, 0, out_len - m_size) || 29040507de94SVitaly Chikunov memcmp(m, outbuf_dec + out_len - m_size, m_size)) { 29050507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 290650d2b643SHerbert Xu hexdump(outbuf_dec, out_len); 2907946cc463STadeusz Struk err = -EINVAL; 2908946cc463STadeusz Struk } 2909946cc463STadeusz Struk free_all: 2910946cc463STadeusz Struk kfree(outbuf_dec); 2911946cc463STadeusz Struk kfree(outbuf_enc); 2912946cc463STadeusz Struk free_req: 2913946cc463STadeusz Struk akcipher_request_free(req); 2914df27b26fSHerbert Xu free_xbuf: 2915df27b26fSHerbert Xu testmgr_free_buf(xbuf); 2916946cc463STadeusz Struk return err; 2917946cc463STadeusz Struk } 2918946cc463STadeusz Struk 291950d2b643SHerbert Xu static int test_akcipher(struct crypto_akcipher *tfm, const char *alg, 2920b13b1e0cSEric Biggers const struct akcipher_testvec *vecs, 2921b13b1e0cSEric Biggers unsigned int tcount) 2922946cc463STadeusz Struk { 292315226e48SHerbert Xu const char *algo = 292415226e48SHerbert Xu crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm)); 2925946cc463STadeusz Struk int ret, i; 2926946cc463STadeusz Struk 2927946cc463STadeusz Struk for (i = 0; i < tcount; i++) { 292850d2b643SHerbert Xu ret = test_akcipher_one(tfm, vecs++); 292950d2b643SHerbert Xu if (!ret) 293050d2b643SHerbert Xu continue; 293150d2b643SHerbert Xu 293215226e48SHerbert Xu pr_err("alg: akcipher: test %d failed for %s, err=%d\n", 293315226e48SHerbert Xu i + 1, algo, ret); 2934946cc463STadeusz Struk return ret; 2935946cc463STadeusz Struk } 2936946cc463STadeusz Struk return 0; 2937946cc463STadeusz Struk } 2938946cc463STadeusz Struk 2939946cc463STadeusz Struk static int alg_test_akcipher(const struct alg_test_desc *desc, 2940946cc463STadeusz Struk const char *driver, u32 type, u32 mask) 2941946cc463STadeusz Struk { 2942946cc463STadeusz Struk struct crypto_akcipher *tfm; 2943946cc463STadeusz Struk int err = 0; 2944946cc463STadeusz Struk 2945eed93e0cSHerbert Xu tfm = crypto_alloc_akcipher(driver, type, mask); 2946946cc463STadeusz Struk if (IS_ERR(tfm)) { 2947946cc463STadeusz Struk pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", 2948946cc463STadeusz Struk driver, PTR_ERR(tfm)); 2949946cc463STadeusz Struk return PTR_ERR(tfm); 2950946cc463STadeusz Struk } 2951946cc463STadeusz Struk if (desc->suite.akcipher.vecs) 2952946cc463STadeusz Struk err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs, 2953946cc463STadeusz Struk desc->suite.akcipher.count); 2954946cc463STadeusz Struk 2955946cc463STadeusz Struk crypto_free_akcipher(tfm); 2956946cc463STadeusz Struk return err; 2957946cc463STadeusz Struk } 2958946cc463STadeusz Struk 2959863b557aSYouquan, Song static int alg_test_null(const struct alg_test_desc *desc, 2960863b557aSYouquan, Song const char *driver, u32 type, u32 mask) 2961863b557aSYouquan, Song { 2962863b557aSYouquan, Song return 0; 2963863b557aSYouquan, Song } 2964863b557aSYouquan, Song 296521c8e720SArd Biesheuvel #define __VECS(tv) { .vecs = tv, .count = ARRAY_SIZE(tv) } 296621c8e720SArd Biesheuvel 2967da7f033dSHerbert Xu /* Please keep this list sorted by algorithm name. */ 2968da7f033dSHerbert Xu static const struct alg_test_desc alg_test_descs[] = { 2969da7f033dSHerbert Xu { 2970059c2a4dSEric Biggers .alg = "adiantum(xchacha12,aes)", 2971059c2a4dSEric Biggers .test = alg_test_skcipher, 2972059c2a4dSEric Biggers .suite = { 2973059c2a4dSEric Biggers .cipher = __VECS(adiantum_xchacha12_aes_tv_template) 2974059c2a4dSEric Biggers }, 2975059c2a4dSEric Biggers }, { 2976059c2a4dSEric Biggers .alg = "adiantum(xchacha20,aes)", 2977059c2a4dSEric Biggers .test = alg_test_skcipher, 2978059c2a4dSEric Biggers .suite = { 2979059c2a4dSEric Biggers .cipher = __VECS(adiantum_xchacha20_aes_tv_template) 2980059c2a4dSEric Biggers }, 2981059c2a4dSEric Biggers }, { 2982b87dc203SOndrej Mosnacek .alg = "aegis128", 2983b87dc203SOndrej Mosnacek .test = alg_test_aead, 2984b87dc203SOndrej Mosnacek .suite = { 2985a0d608eeSEric Biggers .aead = __VECS(aegis128_tv_template) 2986b87dc203SOndrej Mosnacek } 2987b87dc203SOndrej Mosnacek }, { 2988b87dc203SOndrej Mosnacek .alg = "aegis128l", 2989b87dc203SOndrej Mosnacek .test = alg_test_aead, 2990b87dc203SOndrej Mosnacek .suite = { 2991a0d608eeSEric Biggers .aead = __VECS(aegis128l_tv_template) 2992b87dc203SOndrej Mosnacek } 2993b87dc203SOndrej Mosnacek }, { 2994b87dc203SOndrej Mosnacek .alg = "aegis256", 2995b87dc203SOndrej Mosnacek .test = alg_test_aead, 2996b87dc203SOndrej Mosnacek .suite = { 2997a0d608eeSEric Biggers .aead = __VECS(aegis256_tv_template) 2998b87dc203SOndrej Mosnacek } 2999b87dc203SOndrej Mosnacek }, { 3000e08ca2daSJarod Wilson .alg = "ansi_cprng", 3001e08ca2daSJarod Wilson .test = alg_test_cprng, 3002e08ca2daSJarod Wilson .suite = { 300321c8e720SArd Biesheuvel .cprng = __VECS(ansi_cprng_aes_tv_template) 3004e08ca2daSJarod Wilson } 3005e08ca2daSJarod Wilson }, { 3006bca4feb0SHoria Geanta .alg = "authenc(hmac(md5),ecb(cipher_null))", 3007bca4feb0SHoria Geanta .test = alg_test_aead, 3008bca4feb0SHoria Geanta .suite = { 3009a0d608eeSEric Biggers .aead = __VECS(hmac_md5_ecb_cipher_null_tv_template) 3010bca4feb0SHoria Geanta } 3011bca4feb0SHoria Geanta }, { 3012a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(aes))", 3013e46e9a46SHoria Geanta .test = alg_test_aead, 3014bcf741cbSHerbert Xu .fips_allowed = 1, 3015e46e9a46SHoria Geanta .suite = { 3016a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_aes_cbc_tv_temp) 30175208ed2cSNitesh Lal } 30185208ed2cSNitesh Lal }, { 3019a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(des))", 30205208ed2cSNitesh Lal .test = alg_test_aead, 30215208ed2cSNitesh Lal .suite = { 3022a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_des_cbc_tv_temp) 30235208ed2cSNitesh Lal } 30245208ed2cSNitesh Lal }, { 3025a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(des3_ede))", 30265208ed2cSNitesh Lal .test = alg_test_aead, 3027ed1afac9SMarcus Meissner .fips_allowed = 1, 30285208ed2cSNitesh Lal .suite = { 3029a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp) 3030e46e9a46SHoria Geanta } 3031e46e9a46SHoria Geanta }, { 3032fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha1),ctr(aes))", 3033fb16abc2SMarcus Meissner .test = alg_test_null, 3034fb16abc2SMarcus Meissner .fips_allowed = 1, 3035fb16abc2SMarcus Meissner }, { 3036bca4feb0SHoria Geanta .alg = "authenc(hmac(sha1),ecb(cipher_null))", 3037bca4feb0SHoria Geanta .test = alg_test_aead, 3038bca4feb0SHoria Geanta .suite = { 3039a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_ecb_cipher_null_tv_temp) 30405208ed2cSNitesh Lal } 30415208ed2cSNitesh Lal }, { 30428888690eSMarcus Meissner .alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 30438888690eSMarcus Meissner .test = alg_test_null, 30448888690eSMarcus Meissner .fips_allowed = 1, 30458888690eSMarcus Meissner }, { 3046a4198fd4SHerbert Xu .alg = "authenc(hmac(sha224),cbc(des))", 30475208ed2cSNitesh Lal .test = alg_test_aead, 30485208ed2cSNitesh Lal .suite = { 3049a0d608eeSEric Biggers .aead = __VECS(hmac_sha224_des_cbc_tv_temp) 30505208ed2cSNitesh Lal } 30515208ed2cSNitesh Lal }, { 3052a4198fd4SHerbert Xu .alg = "authenc(hmac(sha224),cbc(des3_ede))", 30535208ed2cSNitesh Lal .test = alg_test_aead, 3054ed1afac9SMarcus Meissner .fips_allowed = 1, 30555208ed2cSNitesh Lal .suite = { 3056a0d608eeSEric Biggers .aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp) 3057bca4feb0SHoria Geanta } 3058bca4feb0SHoria Geanta }, { 3059a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(aes))", 3060e46e9a46SHoria Geanta .test = alg_test_aead, 3061ed1afac9SMarcus Meissner .fips_allowed = 1, 3062e46e9a46SHoria Geanta .suite = { 3063a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_aes_cbc_tv_temp) 30645208ed2cSNitesh Lal } 30655208ed2cSNitesh Lal }, { 3066a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(des))", 30675208ed2cSNitesh Lal .test = alg_test_aead, 30685208ed2cSNitesh Lal .suite = { 3069a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_des_cbc_tv_temp) 30705208ed2cSNitesh Lal } 30715208ed2cSNitesh Lal }, { 3072a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(des3_ede))", 30735208ed2cSNitesh Lal .test = alg_test_aead, 3074ed1afac9SMarcus Meissner .fips_allowed = 1, 30755208ed2cSNitesh Lal .suite = { 3076a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp) 30775208ed2cSNitesh Lal } 30785208ed2cSNitesh Lal }, { 3079fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha256),ctr(aes))", 3080fb16abc2SMarcus Meissner .test = alg_test_null, 3081fb16abc2SMarcus Meissner .fips_allowed = 1, 3082fb16abc2SMarcus Meissner }, { 30838888690eSMarcus Meissner .alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 30848888690eSMarcus Meissner .test = alg_test_null, 30858888690eSMarcus Meissner .fips_allowed = 1, 30868888690eSMarcus Meissner }, { 3087a4198fd4SHerbert Xu .alg = "authenc(hmac(sha384),cbc(des))", 30885208ed2cSNitesh Lal .test = alg_test_aead, 30895208ed2cSNitesh Lal .suite = { 3090a0d608eeSEric Biggers .aead = __VECS(hmac_sha384_des_cbc_tv_temp) 30915208ed2cSNitesh Lal } 30925208ed2cSNitesh Lal }, { 3093a4198fd4SHerbert Xu .alg = "authenc(hmac(sha384),cbc(des3_ede))", 30945208ed2cSNitesh Lal .test = alg_test_aead, 3095ed1afac9SMarcus Meissner .fips_allowed = 1, 30965208ed2cSNitesh Lal .suite = { 3097a0d608eeSEric Biggers .aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp) 3098e46e9a46SHoria Geanta } 3099e46e9a46SHoria Geanta }, { 3100fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha384),ctr(aes))", 3101fb16abc2SMarcus Meissner .test = alg_test_null, 3102fb16abc2SMarcus Meissner .fips_allowed = 1, 3103fb16abc2SMarcus Meissner }, { 31048888690eSMarcus Meissner .alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 31058888690eSMarcus Meissner .test = alg_test_null, 31068888690eSMarcus Meissner .fips_allowed = 1, 31078888690eSMarcus Meissner }, { 3108a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(aes))", 3109ed1afac9SMarcus Meissner .fips_allowed = 1, 3110e46e9a46SHoria Geanta .test = alg_test_aead, 3111e46e9a46SHoria Geanta .suite = { 3112a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_aes_cbc_tv_temp) 31135208ed2cSNitesh Lal } 31145208ed2cSNitesh Lal }, { 3115a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(des))", 31165208ed2cSNitesh Lal .test = alg_test_aead, 31175208ed2cSNitesh Lal .suite = { 3118a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_des_cbc_tv_temp) 31195208ed2cSNitesh Lal } 31205208ed2cSNitesh Lal }, { 3121a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(des3_ede))", 31225208ed2cSNitesh Lal .test = alg_test_aead, 3123ed1afac9SMarcus Meissner .fips_allowed = 1, 31245208ed2cSNitesh Lal .suite = { 3125a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp) 3126e46e9a46SHoria Geanta } 3127e46e9a46SHoria Geanta }, { 3128fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha512),ctr(aes))", 3129fb16abc2SMarcus Meissner .test = alg_test_null, 3130fb16abc2SMarcus Meissner .fips_allowed = 1, 3131fb16abc2SMarcus Meissner }, { 31328888690eSMarcus Meissner .alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 31338888690eSMarcus Meissner .test = alg_test_null, 31348888690eSMarcus Meissner .fips_allowed = 1, 31358888690eSMarcus Meissner }, { 3136da7f033dSHerbert Xu .alg = "cbc(aes)", 31371aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3138a1915d51SJarod Wilson .fips_allowed = 1, 3139da7f033dSHerbert Xu .suite = { 314092a4c9feSEric Biggers .cipher = __VECS(aes_cbc_tv_template) 314192a4c9feSEric Biggers }, 3142da7f033dSHerbert Xu }, { 3143da7f033dSHerbert Xu .alg = "cbc(anubis)", 31441aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3145da7f033dSHerbert Xu .suite = { 314692a4c9feSEric Biggers .cipher = __VECS(anubis_cbc_tv_template) 314792a4c9feSEric Biggers }, 3148da7f033dSHerbert Xu }, { 3149da7f033dSHerbert Xu .alg = "cbc(blowfish)", 31501aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3151da7f033dSHerbert Xu .suite = { 315292a4c9feSEric Biggers .cipher = __VECS(bf_cbc_tv_template) 315392a4c9feSEric Biggers }, 3154da7f033dSHerbert Xu }, { 3155da7f033dSHerbert Xu .alg = "cbc(camellia)", 31561aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3157da7f033dSHerbert Xu .suite = { 315892a4c9feSEric Biggers .cipher = __VECS(camellia_cbc_tv_template) 315992a4c9feSEric Biggers }, 3160da7f033dSHerbert Xu }, { 3161a2c58260SJohannes Goetzfried .alg = "cbc(cast5)", 3162a2c58260SJohannes Goetzfried .test = alg_test_skcipher, 3163a2c58260SJohannes Goetzfried .suite = { 316492a4c9feSEric Biggers .cipher = __VECS(cast5_cbc_tv_template) 316592a4c9feSEric Biggers }, 3166a2c58260SJohannes Goetzfried }, { 31679b8b0405SJohannes Goetzfried .alg = "cbc(cast6)", 31689b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 31699b8b0405SJohannes Goetzfried .suite = { 317092a4c9feSEric Biggers .cipher = __VECS(cast6_cbc_tv_template) 317192a4c9feSEric Biggers }, 31729b8b0405SJohannes Goetzfried }, { 3173da7f033dSHerbert Xu .alg = "cbc(des)", 31741aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3175da7f033dSHerbert Xu .suite = { 317692a4c9feSEric Biggers .cipher = __VECS(des_cbc_tv_template) 317792a4c9feSEric Biggers }, 3178da7f033dSHerbert Xu }, { 3179da7f033dSHerbert Xu .alg = "cbc(des3_ede)", 31801aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3181a1915d51SJarod Wilson .fips_allowed = 1, 3182da7f033dSHerbert Xu .suite = { 318392a4c9feSEric Biggers .cipher = __VECS(des3_ede_cbc_tv_template) 318492a4c9feSEric Biggers }, 3185da7f033dSHerbert Xu }, { 3186a794d8d8SGilad Ben-Yossef /* Same as cbc(aes) except the key is stored in 3187a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 3188a794d8d8SGilad Ben-Yossef */ 3189a794d8d8SGilad Ben-Yossef .alg = "cbc(paes)", 3190a794d8d8SGilad Ben-Yossef .test = alg_test_null, 3191a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 3192a794d8d8SGilad Ben-Yossef }, { 31939d25917dSJussi Kivilinna .alg = "cbc(serpent)", 31949d25917dSJussi Kivilinna .test = alg_test_skcipher, 31959d25917dSJussi Kivilinna .suite = { 319692a4c9feSEric Biggers .cipher = __VECS(serpent_cbc_tv_template) 319792a4c9feSEric Biggers }, 31989d25917dSJussi Kivilinna }, { 319995ba5973SGilad Ben-Yossef .alg = "cbc(sm4)", 320095ba5973SGilad Ben-Yossef .test = alg_test_skcipher, 320195ba5973SGilad Ben-Yossef .suite = { 320295ba5973SGilad Ben-Yossef .cipher = __VECS(sm4_cbc_tv_template) 320395ba5973SGilad Ben-Yossef } 320495ba5973SGilad Ben-Yossef }, { 3205da7f033dSHerbert Xu .alg = "cbc(twofish)", 32061aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3207da7f033dSHerbert Xu .suite = { 320892a4c9feSEric Biggers .cipher = __VECS(tf_cbc_tv_template) 320992a4c9feSEric Biggers }, 3210da7f033dSHerbert Xu }, { 3211092acf06SArd Biesheuvel .alg = "cbcmac(aes)", 3212092acf06SArd Biesheuvel .fips_allowed = 1, 3213092acf06SArd Biesheuvel .test = alg_test_hash, 3214092acf06SArd Biesheuvel .suite = { 3215092acf06SArd Biesheuvel .hash = __VECS(aes_cbcmac_tv_template) 3216092acf06SArd Biesheuvel } 3217092acf06SArd Biesheuvel }, { 3218da7f033dSHerbert Xu .alg = "ccm(aes)", 3219da7f033dSHerbert Xu .test = alg_test_aead, 3220a1915d51SJarod Wilson .fips_allowed = 1, 3221da7f033dSHerbert Xu .suite = { 3222a0d608eeSEric Biggers .aead = __VECS(aes_ccm_tv_template) 3223da7f033dSHerbert Xu } 3224da7f033dSHerbert Xu }, { 32257da66670SDmitry Eremin-Solenikov .alg = "cfb(aes)", 32267da66670SDmitry Eremin-Solenikov .test = alg_test_skcipher, 32277da66670SDmitry Eremin-Solenikov .fips_allowed = 1, 32287da66670SDmitry Eremin-Solenikov .suite = { 32297da66670SDmitry Eremin-Solenikov .cipher = __VECS(aes_cfb_tv_template) 32307da66670SDmitry Eremin-Solenikov }, 32317da66670SDmitry Eremin-Solenikov }, { 32323590ebf2SMartin Willi .alg = "chacha20", 32333590ebf2SMartin Willi .test = alg_test_skcipher, 32343590ebf2SMartin Willi .suite = { 323592a4c9feSEric Biggers .cipher = __VECS(chacha20_tv_template) 323692a4c9feSEric Biggers }, 32373590ebf2SMartin Willi }, { 323893b5e86aSJussi Kivilinna .alg = "cmac(aes)", 32398f183751SStephan Mueller .fips_allowed = 1, 324093b5e86aSJussi Kivilinna .test = alg_test_hash, 324193b5e86aSJussi Kivilinna .suite = { 324221c8e720SArd Biesheuvel .hash = __VECS(aes_cmac128_tv_template) 324393b5e86aSJussi Kivilinna } 324493b5e86aSJussi Kivilinna }, { 324593b5e86aSJussi Kivilinna .alg = "cmac(des3_ede)", 32468f183751SStephan Mueller .fips_allowed = 1, 324793b5e86aSJussi Kivilinna .test = alg_test_hash, 324893b5e86aSJussi Kivilinna .suite = { 324921c8e720SArd Biesheuvel .hash = __VECS(des3_ede_cmac64_tv_template) 325093b5e86aSJussi Kivilinna } 325193b5e86aSJussi Kivilinna }, { 3252e448370dSJussi Kivilinna .alg = "compress_null", 3253e448370dSJussi Kivilinna .test = alg_test_null, 3254e448370dSJussi Kivilinna }, { 3255ebb3472fSArd Biesheuvel .alg = "crc32", 3256ebb3472fSArd Biesheuvel .test = alg_test_hash, 3257a8a34416SMilan Broz .fips_allowed = 1, 3258ebb3472fSArd Biesheuvel .suite = { 325921c8e720SArd Biesheuvel .hash = __VECS(crc32_tv_template) 3260ebb3472fSArd Biesheuvel } 3261ebb3472fSArd Biesheuvel }, { 3262da7f033dSHerbert Xu .alg = "crc32c", 32638e3ee85eSHerbert Xu .test = alg_test_crc32c, 3264a1915d51SJarod Wilson .fips_allowed = 1, 3265da7f033dSHerbert Xu .suite = { 326621c8e720SArd Biesheuvel .hash = __VECS(crc32c_tv_template) 3267da7f033dSHerbert Xu } 3268da7f033dSHerbert Xu }, { 326968411521SHerbert Xu .alg = "crct10dif", 327068411521SHerbert Xu .test = alg_test_hash, 327168411521SHerbert Xu .fips_allowed = 1, 327268411521SHerbert Xu .suite = { 327321c8e720SArd Biesheuvel .hash = __VECS(crct10dif_tv_template) 327468411521SHerbert Xu } 327568411521SHerbert Xu }, { 3276f7cb80f2SJarod Wilson .alg = "ctr(aes)", 3277f7cb80f2SJarod Wilson .test = alg_test_skcipher, 3278a1915d51SJarod Wilson .fips_allowed = 1, 3279f7cb80f2SJarod Wilson .suite = { 328092a4c9feSEric Biggers .cipher = __VECS(aes_ctr_tv_template) 3281f7cb80f2SJarod Wilson } 3282f7cb80f2SJarod Wilson }, { 328385b63e34SJussi Kivilinna .alg = "ctr(blowfish)", 328485b63e34SJussi Kivilinna .test = alg_test_skcipher, 328585b63e34SJussi Kivilinna .suite = { 328692a4c9feSEric Biggers .cipher = __VECS(bf_ctr_tv_template) 328785b63e34SJussi Kivilinna } 328885b63e34SJussi Kivilinna }, { 32890840605eSJussi Kivilinna .alg = "ctr(camellia)", 32900840605eSJussi Kivilinna .test = alg_test_skcipher, 32910840605eSJussi Kivilinna .suite = { 329292a4c9feSEric Biggers .cipher = __VECS(camellia_ctr_tv_template) 32930840605eSJussi Kivilinna } 32940840605eSJussi Kivilinna }, { 3295a2c58260SJohannes Goetzfried .alg = "ctr(cast5)", 3296a2c58260SJohannes Goetzfried .test = alg_test_skcipher, 3297a2c58260SJohannes Goetzfried .suite = { 329892a4c9feSEric Biggers .cipher = __VECS(cast5_ctr_tv_template) 3299a2c58260SJohannes Goetzfried } 3300a2c58260SJohannes Goetzfried }, { 33019b8b0405SJohannes Goetzfried .alg = "ctr(cast6)", 33029b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 33039b8b0405SJohannes Goetzfried .suite = { 330492a4c9feSEric Biggers .cipher = __VECS(cast6_ctr_tv_template) 33059b8b0405SJohannes Goetzfried } 33069b8b0405SJohannes Goetzfried }, { 33078163fc30SJussi Kivilinna .alg = "ctr(des)", 33088163fc30SJussi Kivilinna .test = alg_test_skcipher, 33098163fc30SJussi Kivilinna .suite = { 331092a4c9feSEric Biggers .cipher = __VECS(des_ctr_tv_template) 33118163fc30SJussi Kivilinna } 33128163fc30SJussi Kivilinna }, { 3313e080b17aSJussi Kivilinna .alg = "ctr(des3_ede)", 3314e080b17aSJussi Kivilinna .test = alg_test_skcipher, 33150d8da104SMarcelo Cerri .fips_allowed = 1, 3316e080b17aSJussi Kivilinna .suite = { 331792a4c9feSEric Biggers .cipher = __VECS(des3_ede_ctr_tv_template) 3318e080b17aSJussi Kivilinna } 3319e080b17aSJussi Kivilinna }, { 3320a794d8d8SGilad Ben-Yossef /* Same as ctr(aes) except the key is stored in 3321a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 3322a794d8d8SGilad Ben-Yossef */ 3323a794d8d8SGilad Ben-Yossef .alg = "ctr(paes)", 3324a794d8d8SGilad Ben-Yossef .test = alg_test_null, 3325a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 3326a794d8d8SGilad Ben-Yossef }, { 33279d25917dSJussi Kivilinna .alg = "ctr(serpent)", 33289d25917dSJussi Kivilinna .test = alg_test_skcipher, 33299d25917dSJussi Kivilinna .suite = { 333092a4c9feSEric Biggers .cipher = __VECS(serpent_ctr_tv_template) 33319d25917dSJussi Kivilinna } 33329d25917dSJussi Kivilinna }, { 333395ba5973SGilad Ben-Yossef .alg = "ctr(sm4)", 333495ba5973SGilad Ben-Yossef .test = alg_test_skcipher, 333595ba5973SGilad Ben-Yossef .suite = { 333695ba5973SGilad Ben-Yossef .cipher = __VECS(sm4_ctr_tv_template) 333795ba5973SGilad Ben-Yossef } 333895ba5973SGilad Ben-Yossef }, { 3339573da620SJussi Kivilinna .alg = "ctr(twofish)", 3340573da620SJussi Kivilinna .test = alg_test_skcipher, 3341573da620SJussi Kivilinna .suite = { 334292a4c9feSEric Biggers .cipher = __VECS(tf_ctr_tv_template) 3343573da620SJussi Kivilinna } 3344573da620SJussi Kivilinna }, { 3345da7f033dSHerbert Xu .alg = "cts(cbc(aes))", 33461aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3347196ad604SGilad Ben-Yossef .fips_allowed = 1, 3348da7f033dSHerbert Xu .suite = { 334992a4c9feSEric Biggers .cipher = __VECS(cts_mode_tv_template) 3350da7f033dSHerbert Xu } 3351da7f033dSHerbert Xu }, { 3352da7f033dSHerbert Xu .alg = "deflate", 3353da7f033dSHerbert Xu .test = alg_test_comp, 33540818904dSMilan Broz .fips_allowed = 1, 3355da7f033dSHerbert Xu .suite = { 3356da7f033dSHerbert Xu .comp = { 335721c8e720SArd Biesheuvel .comp = __VECS(deflate_comp_tv_template), 335821c8e720SArd Biesheuvel .decomp = __VECS(deflate_decomp_tv_template) 3359da7f033dSHerbert Xu } 3360da7f033dSHerbert Xu } 3361da7f033dSHerbert Xu }, { 3362802c7f1cSSalvatore Benedetto .alg = "dh", 3363802c7f1cSSalvatore Benedetto .test = alg_test_kpp, 3364802c7f1cSSalvatore Benedetto .fips_allowed = 1, 3365802c7f1cSSalvatore Benedetto .suite = { 336621c8e720SArd Biesheuvel .kpp = __VECS(dh_tv_template) 3367802c7f1cSSalvatore Benedetto } 3368802c7f1cSSalvatore Benedetto }, { 3369e448370dSJussi Kivilinna .alg = "digest_null", 3370e448370dSJussi Kivilinna .test = alg_test_null, 3371e448370dSJussi Kivilinna }, { 337264d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes128", 337364d1cdfbSStephan Mueller .test = alg_test_drbg, 337464d1cdfbSStephan Mueller .fips_allowed = 1, 337564d1cdfbSStephan Mueller .suite = { 337621c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes128_tv_template) 337764d1cdfbSStephan Mueller } 337864d1cdfbSStephan Mueller }, { 337964d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes192", 338064d1cdfbSStephan Mueller .test = alg_test_drbg, 338164d1cdfbSStephan Mueller .fips_allowed = 1, 338264d1cdfbSStephan Mueller .suite = { 338321c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes192_tv_template) 338464d1cdfbSStephan Mueller } 338564d1cdfbSStephan Mueller }, { 338664d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes256", 338764d1cdfbSStephan Mueller .test = alg_test_drbg, 338864d1cdfbSStephan Mueller .fips_allowed = 1, 338964d1cdfbSStephan Mueller .suite = { 339021c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes256_tv_template) 339164d1cdfbSStephan Mueller } 339264d1cdfbSStephan Mueller }, { 339364d1cdfbSStephan Mueller /* 339464d1cdfbSStephan Mueller * There is no need to specifically test the DRBG with every 339564d1cdfbSStephan Mueller * backend cipher -- covered by drbg_nopr_hmac_sha256 test 339664d1cdfbSStephan Mueller */ 339764d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha1", 339864d1cdfbSStephan Mueller .fips_allowed = 1, 339964d1cdfbSStephan Mueller .test = alg_test_null, 340064d1cdfbSStephan Mueller }, { 340164d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha256", 340264d1cdfbSStephan Mueller .test = alg_test_drbg, 340364d1cdfbSStephan Mueller .fips_allowed = 1, 340464d1cdfbSStephan Mueller .suite = { 340521c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_hmac_sha256_tv_template) 340664d1cdfbSStephan Mueller } 340764d1cdfbSStephan Mueller }, { 340864d1cdfbSStephan Mueller /* covered by drbg_nopr_hmac_sha256 test */ 340964d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha384", 341064d1cdfbSStephan Mueller .fips_allowed = 1, 341164d1cdfbSStephan Mueller .test = alg_test_null, 341264d1cdfbSStephan Mueller }, { 341364d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha512", 341464d1cdfbSStephan Mueller .test = alg_test_null, 341564d1cdfbSStephan Mueller .fips_allowed = 1, 341664d1cdfbSStephan Mueller }, { 341764d1cdfbSStephan Mueller .alg = "drbg_nopr_sha1", 341864d1cdfbSStephan Mueller .fips_allowed = 1, 341964d1cdfbSStephan Mueller .test = alg_test_null, 342064d1cdfbSStephan Mueller }, { 342164d1cdfbSStephan Mueller .alg = "drbg_nopr_sha256", 342264d1cdfbSStephan Mueller .test = alg_test_drbg, 342364d1cdfbSStephan Mueller .fips_allowed = 1, 342464d1cdfbSStephan Mueller .suite = { 342521c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_sha256_tv_template) 342664d1cdfbSStephan Mueller } 342764d1cdfbSStephan Mueller }, { 342864d1cdfbSStephan Mueller /* covered by drbg_nopr_sha256 test */ 342964d1cdfbSStephan Mueller .alg = "drbg_nopr_sha384", 343064d1cdfbSStephan Mueller .fips_allowed = 1, 343164d1cdfbSStephan Mueller .test = alg_test_null, 343264d1cdfbSStephan Mueller }, { 343364d1cdfbSStephan Mueller .alg = "drbg_nopr_sha512", 343464d1cdfbSStephan Mueller .fips_allowed = 1, 343564d1cdfbSStephan Mueller .test = alg_test_null, 343664d1cdfbSStephan Mueller }, { 343764d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes128", 343864d1cdfbSStephan Mueller .test = alg_test_drbg, 343964d1cdfbSStephan Mueller .fips_allowed = 1, 344064d1cdfbSStephan Mueller .suite = { 344121c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_ctr_aes128_tv_template) 344264d1cdfbSStephan Mueller } 344364d1cdfbSStephan Mueller }, { 344464d1cdfbSStephan Mueller /* covered by drbg_pr_ctr_aes128 test */ 344564d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes192", 344664d1cdfbSStephan Mueller .fips_allowed = 1, 344764d1cdfbSStephan Mueller .test = alg_test_null, 344864d1cdfbSStephan Mueller }, { 344964d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes256", 345064d1cdfbSStephan Mueller .fips_allowed = 1, 345164d1cdfbSStephan Mueller .test = alg_test_null, 345264d1cdfbSStephan Mueller }, { 345364d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha1", 345464d1cdfbSStephan Mueller .fips_allowed = 1, 345564d1cdfbSStephan Mueller .test = alg_test_null, 345664d1cdfbSStephan Mueller }, { 345764d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha256", 345864d1cdfbSStephan Mueller .test = alg_test_drbg, 345964d1cdfbSStephan Mueller .fips_allowed = 1, 346064d1cdfbSStephan Mueller .suite = { 346121c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_hmac_sha256_tv_template) 346264d1cdfbSStephan Mueller } 346364d1cdfbSStephan Mueller }, { 346464d1cdfbSStephan Mueller /* covered by drbg_pr_hmac_sha256 test */ 346564d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha384", 346664d1cdfbSStephan Mueller .fips_allowed = 1, 346764d1cdfbSStephan Mueller .test = alg_test_null, 346864d1cdfbSStephan Mueller }, { 346964d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha512", 347064d1cdfbSStephan Mueller .test = alg_test_null, 347164d1cdfbSStephan Mueller .fips_allowed = 1, 347264d1cdfbSStephan Mueller }, { 347364d1cdfbSStephan Mueller .alg = "drbg_pr_sha1", 347464d1cdfbSStephan Mueller .fips_allowed = 1, 347564d1cdfbSStephan Mueller .test = alg_test_null, 347664d1cdfbSStephan Mueller }, { 347764d1cdfbSStephan Mueller .alg = "drbg_pr_sha256", 347864d1cdfbSStephan Mueller .test = alg_test_drbg, 347964d1cdfbSStephan Mueller .fips_allowed = 1, 348064d1cdfbSStephan Mueller .suite = { 348121c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_sha256_tv_template) 348264d1cdfbSStephan Mueller } 348364d1cdfbSStephan Mueller }, { 348464d1cdfbSStephan Mueller /* covered by drbg_pr_sha256 test */ 348564d1cdfbSStephan Mueller .alg = "drbg_pr_sha384", 348664d1cdfbSStephan Mueller .fips_allowed = 1, 348764d1cdfbSStephan Mueller .test = alg_test_null, 348864d1cdfbSStephan Mueller }, { 348964d1cdfbSStephan Mueller .alg = "drbg_pr_sha512", 349064d1cdfbSStephan Mueller .fips_allowed = 1, 349164d1cdfbSStephan Mueller .test = alg_test_null, 349264d1cdfbSStephan Mueller }, { 3493da7f033dSHerbert Xu .alg = "ecb(aes)", 34941aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3495a1915d51SJarod Wilson .fips_allowed = 1, 3496da7f033dSHerbert Xu .suite = { 349792a4c9feSEric Biggers .cipher = __VECS(aes_tv_template) 3498da7f033dSHerbert Xu } 3499da7f033dSHerbert Xu }, { 3500da7f033dSHerbert Xu .alg = "ecb(anubis)", 35011aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3502da7f033dSHerbert Xu .suite = { 350392a4c9feSEric Biggers .cipher = __VECS(anubis_tv_template) 3504da7f033dSHerbert Xu } 3505da7f033dSHerbert Xu }, { 3506da7f033dSHerbert Xu .alg = "ecb(arc4)", 35071aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3508da7f033dSHerbert Xu .suite = { 350992a4c9feSEric Biggers .cipher = __VECS(arc4_tv_template) 3510da7f033dSHerbert Xu } 3511da7f033dSHerbert Xu }, { 3512da7f033dSHerbert Xu .alg = "ecb(blowfish)", 35131aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3514da7f033dSHerbert Xu .suite = { 351592a4c9feSEric Biggers .cipher = __VECS(bf_tv_template) 3516da7f033dSHerbert Xu } 3517da7f033dSHerbert Xu }, { 3518da7f033dSHerbert Xu .alg = "ecb(camellia)", 35191aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3520da7f033dSHerbert Xu .suite = { 352192a4c9feSEric Biggers .cipher = __VECS(camellia_tv_template) 3522da7f033dSHerbert Xu } 3523da7f033dSHerbert Xu }, { 3524da7f033dSHerbert Xu .alg = "ecb(cast5)", 35251aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3526da7f033dSHerbert Xu .suite = { 352792a4c9feSEric Biggers .cipher = __VECS(cast5_tv_template) 3528da7f033dSHerbert Xu } 3529da7f033dSHerbert Xu }, { 3530da7f033dSHerbert Xu .alg = "ecb(cast6)", 35311aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3532da7f033dSHerbert Xu .suite = { 353392a4c9feSEric Biggers .cipher = __VECS(cast6_tv_template) 3534da7f033dSHerbert Xu } 3535da7f033dSHerbert Xu }, { 3536e448370dSJussi Kivilinna .alg = "ecb(cipher_null)", 3537e448370dSJussi Kivilinna .test = alg_test_null, 35386175ca2bSMilan Broz .fips_allowed = 1, 3539e448370dSJussi Kivilinna }, { 3540da7f033dSHerbert Xu .alg = "ecb(des)", 35411aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3542da7f033dSHerbert Xu .suite = { 354392a4c9feSEric Biggers .cipher = __VECS(des_tv_template) 3544da7f033dSHerbert Xu } 3545da7f033dSHerbert Xu }, { 3546da7f033dSHerbert Xu .alg = "ecb(des3_ede)", 35471aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3548a1915d51SJarod Wilson .fips_allowed = 1, 3549da7f033dSHerbert Xu .suite = { 355092a4c9feSEric Biggers .cipher = __VECS(des3_ede_tv_template) 3551da7f033dSHerbert Xu } 3552da7f033dSHerbert Xu }, { 355366e5bd00SJussi Kivilinna .alg = "ecb(fcrypt)", 355466e5bd00SJussi Kivilinna .test = alg_test_skcipher, 355566e5bd00SJussi Kivilinna .suite = { 355666e5bd00SJussi Kivilinna .cipher = { 355792a4c9feSEric Biggers .vecs = fcrypt_pcbc_tv_template, 355866e5bd00SJussi Kivilinna .count = 1 355966e5bd00SJussi Kivilinna } 356066e5bd00SJussi Kivilinna } 356166e5bd00SJussi Kivilinna }, { 3562da7f033dSHerbert Xu .alg = "ecb(khazad)", 35631aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3564da7f033dSHerbert Xu .suite = { 356592a4c9feSEric Biggers .cipher = __VECS(khazad_tv_template) 3566da7f033dSHerbert Xu } 3567da7f033dSHerbert Xu }, { 356815f47ce5SGilad Ben-Yossef /* Same as ecb(aes) except the key is stored in 356915f47ce5SGilad Ben-Yossef * hardware secure memory which we reference by index 357015f47ce5SGilad Ben-Yossef */ 357115f47ce5SGilad Ben-Yossef .alg = "ecb(paes)", 357215f47ce5SGilad Ben-Yossef .test = alg_test_null, 357315f47ce5SGilad Ben-Yossef .fips_allowed = 1, 357415f47ce5SGilad Ben-Yossef }, { 3575da7f033dSHerbert Xu .alg = "ecb(seed)", 35761aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3577da7f033dSHerbert Xu .suite = { 357892a4c9feSEric Biggers .cipher = __VECS(seed_tv_template) 3579da7f033dSHerbert Xu } 3580da7f033dSHerbert Xu }, { 3581da7f033dSHerbert Xu .alg = "ecb(serpent)", 35821aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3583da7f033dSHerbert Xu .suite = { 358492a4c9feSEric Biggers .cipher = __VECS(serpent_tv_template) 3585da7f033dSHerbert Xu } 3586da7f033dSHerbert Xu }, { 3587cd83a8a7SGilad Ben-Yossef .alg = "ecb(sm4)", 3588cd83a8a7SGilad Ben-Yossef .test = alg_test_skcipher, 3589cd83a8a7SGilad Ben-Yossef .suite = { 359092a4c9feSEric Biggers .cipher = __VECS(sm4_tv_template) 3591cd83a8a7SGilad Ben-Yossef } 3592cd83a8a7SGilad Ben-Yossef }, { 3593da7f033dSHerbert Xu .alg = "ecb(tea)", 35941aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3595da7f033dSHerbert Xu .suite = { 359692a4c9feSEric Biggers .cipher = __VECS(tea_tv_template) 3597da7f033dSHerbert Xu } 3598da7f033dSHerbert Xu }, { 3599da7f033dSHerbert Xu .alg = "ecb(tnepres)", 36001aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3601da7f033dSHerbert Xu .suite = { 360292a4c9feSEric Biggers .cipher = __VECS(tnepres_tv_template) 3603da7f033dSHerbert Xu } 3604da7f033dSHerbert Xu }, { 3605da7f033dSHerbert Xu .alg = "ecb(twofish)", 36061aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3607da7f033dSHerbert Xu .suite = { 360892a4c9feSEric Biggers .cipher = __VECS(tf_tv_template) 3609da7f033dSHerbert Xu } 3610da7f033dSHerbert Xu }, { 3611da7f033dSHerbert Xu .alg = "ecb(xeta)", 36121aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3613da7f033dSHerbert Xu .suite = { 361492a4c9feSEric Biggers .cipher = __VECS(xeta_tv_template) 3615da7f033dSHerbert Xu } 3616da7f033dSHerbert Xu }, { 3617da7f033dSHerbert Xu .alg = "ecb(xtea)", 36181aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3619da7f033dSHerbert Xu .suite = { 362092a4c9feSEric Biggers .cipher = __VECS(xtea_tv_template) 3621da7f033dSHerbert Xu } 3622da7f033dSHerbert Xu }, { 36233c4b2390SSalvatore Benedetto .alg = "ecdh", 36243c4b2390SSalvatore Benedetto .test = alg_test_kpp, 36253c4b2390SSalvatore Benedetto .fips_allowed = 1, 36263c4b2390SSalvatore Benedetto .suite = { 362721c8e720SArd Biesheuvel .kpp = __VECS(ecdh_tv_template) 36283c4b2390SSalvatore Benedetto } 36293c4b2390SSalvatore Benedetto }, { 3630da7f033dSHerbert Xu .alg = "gcm(aes)", 3631da7f033dSHerbert Xu .test = alg_test_aead, 3632a1915d51SJarod Wilson .fips_allowed = 1, 3633da7f033dSHerbert Xu .suite = { 3634a0d608eeSEric Biggers .aead = __VECS(aes_gcm_tv_template) 3635da7f033dSHerbert Xu } 3636da7f033dSHerbert Xu }, { 3637507069c9SYouquan, Song .alg = "ghash", 3638507069c9SYouquan, Song .test = alg_test_hash, 363918c0ebd2SJarod Wilson .fips_allowed = 1, 3640507069c9SYouquan, Song .suite = { 364121c8e720SArd Biesheuvel .hash = __VECS(ghash_tv_template) 3642507069c9SYouquan, Song } 3643507069c9SYouquan, Song }, { 3644da7f033dSHerbert Xu .alg = "hmac(md5)", 3645da7f033dSHerbert Xu .test = alg_test_hash, 3646da7f033dSHerbert Xu .suite = { 364721c8e720SArd Biesheuvel .hash = __VECS(hmac_md5_tv_template) 3648da7f033dSHerbert Xu } 3649da7f033dSHerbert Xu }, { 3650da7f033dSHerbert Xu .alg = "hmac(rmd128)", 3651da7f033dSHerbert Xu .test = alg_test_hash, 3652da7f033dSHerbert Xu .suite = { 365321c8e720SArd Biesheuvel .hash = __VECS(hmac_rmd128_tv_template) 3654da7f033dSHerbert Xu } 3655da7f033dSHerbert Xu }, { 3656da7f033dSHerbert Xu .alg = "hmac(rmd160)", 3657da7f033dSHerbert Xu .test = alg_test_hash, 3658da7f033dSHerbert Xu .suite = { 365921c8e720SArd Biesheuvel .hash = __VECS(hmac_rmd160_tv_template) 3660da7f033dSHerbert Xu } 3661da7f033dSHerbert Xu }, { 3662da7f033dSHerbert Xu .alg = "hmac(sha1)", 3663da7f033dSHerbert Xu .test = alg_test_hash, 3664a1915d51SJarod Wilson .fips_allowed = 1, 3665da7f033dSHerbert Xu .suite = { 366621c8e720SArd Biesheuvel .hash = __VECS(hmac_sha1_tv_template) 3667da7f033dSHerbert Xu } 3668da7f033dSHerbert Xu }, { 3669da7f033dSHerbert Xu .alg = "hmac(sha224)", 3670da7f033dSHerbert Xu .test = alg_test_hash, 3671a1915d51SJarod Wilson .fips_allowed = 1, 3672da7f033dSHerbert Xu .suite = { 367321c8e720SArd Biesheuvel .hash = __VECS(hmac_sha224_tv_template) 3674da7f033dSHerbert Xu } 3675da7f033dSHerbert Xu }, { 3676da7f033dSHerbert Xu .alg = "hmac(sha256)", 3677da7f033dSHerbert Xu .test = alg_test_hash, 3678a1915d51SJarod Wilson .fips_allowed = 1, 3679da7f033dSHerbert Xu .suite = { 368021c8e720SArd Biesheuvel .hash = __VECS(hmac_sha256_tv_template) 3681da7f033dSHerbert Xu } 3682da7f033dSHerbert Xu }, { 368398eca72fSraveendra padasalagi .alg = "hmac(sha3-224)", 368498eca72fSraveendra padasalagi .test = alg_test_hash, 368598eca72fSraveendra padasalagi .fips_allowed = 1, 368698eca72fSraveendra padasalagi .suite = { 368721c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_224_tv_template) 368898eca72fSraveendra padasalagi } 368998eca72fSraveendra padasalagi }, { 369098eca72fSraveendra padasalagi .alg = "hmac(sha3-256)", 369198eca72fSraveendra padasalagi .test = alg_test_hash, 369298eca72fSraveendra padasalagi .fips_allowed = 1, 369398eca72fSraveendra padasalagi .suite = { 369421c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_256_tv_template) 369598eca72fSraveendra padasalagi } 369698eca72fSraveendra padasalagi }, { 369798eca72fSraveendra padasalagi .alg = "hmac(sha3-384)", 369898eca72fSraveendra padasalagi .test = alg_test_hash, 369998eca72fSraveendra padasalagi .fips_allowed = 1, 370098eca72fSraveendra padasalagi .suite = { 370121c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_384_tv_template) 370298eca72fSraveendra padasalagi } 370398eca72fSraveendra padasalagi }, { 370498eca72fSraveendra padasalagi .alg = "hmac(sha3-512)", 370598eca72fSraveendra padasalagi .test = alg_test_hash, 370698eca72fSraveendra padasalagi .fips_allowed = 1, 370798eca72fSraveendra padasalagi .suite = { 370821c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_512_tv_template) 370998eca72fSraveendra padasalagi } 371098eca72fSraveendra padasalagi }, { 3711da7f033dSHerbert Xu .alg = "hmac(sha384)", 3712da7f033dSHerbert Xu .test = alg_test_hash, 3713a1915d51SJarod Wilson .fips_allowed = 1, 3714da7f033dSHerbert Xu .suite = { 371521c8e720SArd Biesheuvel .hash = __VECS(hmac_sha384_tv_template) 3716da7f033dSHerbert Xu } 3717da7f033dSHerbert Xu }, { 3718da7f033dSHerbert Xu .alg = "hmac(sha512)", 3719da7f033dSHerbert Xu .test = alg_test_hash, 3720a1915d51SJarod Wilson .fips_allowed = 1, 3721da7f033dSHerbert Xu .suite = { 372221c8e720SArd Biesheuvel .hash = __VECS(hmac_sha512_tv_template) 3723da7f033dSHerbert Xu } 3724da7f033dSHerbert Xu }, { 372525a0b9d4SVitaly Chikunov .alg = "hmac(streebog256)", 372625a0b9d4SVitaly Chikunov .test = alg_test_hash, 372725a0b9d4SVitaly Chikunov .suite = { 372825a0b9d4SVitaly Chikunov .hash = __VECS(hmac_streebog256_tv_template) 372925a0b9d4SVitaly Chikunov } 373025a0b9d4SVitaly Chikunov }, { 373125a0b9d4SVitaly Chikunov .alg = "hmac(streebog512)", 373225a0b9d4SVitaly Chikunov .test = alg_test_hash, 373325a0b9d4SVitaly Chikunov .suite = { 373425a0b9d4SVitaly Chikunov .hash = __VECS(hmac_streebog512_tv_template) 373525a0b9d4SVitaly Chikunov } 373625a0b9d4SVitaly Chikunov }, { 3737bb5530e4SStephan Mueller .alg = "jitterentropy_rng", 3738bb5530e4SStephan Mueller .fips_allowed = 1, 3739bb5530e4SStephan Mueller .test = alg_test_null, 3740bb5530e4SStephan Mueller }, { 374135351988SStephan Mueller .alg = "kw(aes)", 374235351988SStephan Mueller .test = alg_test_skcipher, 374335351988SStephan Mueller .fips_allowed = 1, 374435351988SStephan Mueller .suite = { 374592a4c9feSEric Biggers .cipher = __VECS(aes_kw_tv_template) 374635351988SStephan Mueller } 374735351988SStephan Mueller }, { 3748da7f033dSHerbert Xu .alg = "lrw(aes)", 37491aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3750da7f033dSHerbert Xu .suite = { 375192a4c9feSEric Biggers .cipher = __VECS(aes_lrw_tv_template) 3752da7f033dSHerbert Xu } 3753da7f033dSHerbert Xu }, { 37540840605eSJussi Kivilinna .alg = "lrw(camellia)", 37550840605eSJussi Kivilinna .test = alg_test_skcipher, 37560840605eSJussi Kivilinna .suite = { 375792a4c9feSEric Biggers .cipher = __VECS(camellia_lrw_tv_template) 37580840605eSJussi Kivilinna } 37590840605eSJussi Kivilinna }, { 37609b8b0405SJohannes Goetzfried .alg = "lrw(cast6)", 37619b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 37629b8b0405SJohannes Goetzfried .suite = { 376392a4c9feSEric Biggers .cipher = __VECS(cast6_lrw_tv_template) 37649b8b0405SJohannes Goetzfried } 37659b8b0405SJohannes Goetzfried }, { 3766d7bfc0faSJussi Kivilinna .alg = "lrw(serpent)", 3767d7bfc0faSJussi Kivilinna .test = alg_test_skcipher, 3768d7bfc0faSJussi Kivilinna .suite = { 376992a4c9feSEric Biggers .cipher = __VECS(serpent_lrw_tv_template) 3770d7bfc0faSJussi Kivilinna } 3771d7bfc0faSJussi Kivilinna }, { 37720b2a1551SJussi Kivilinna .alg = "lrw(twofish)", 37730b2a1551SJussi Kivilinna .test = alg_test_skcipher, 37740b2a1551SJussi Kivilinna .suite = { 377592a4c9feSEric Biggers .cipher = __VECS(tf_lrw_tv_template) 37760b2a1551SJussi Kivilinna } 37770b2a1551SJussi Kivilinna }, { 37781443cc9bSKOVACS Krisztian .alg = "lz4", 37791443cc9bSKOVACS Krisztian .test = alg_test_comp, 37801443cc9bSKOVACS Krisztian .fips_allowed = 1, 37811443cc9bSKOVACS Krisztian .suite = { 37821443cc9bSKOVACS Krisztian .comp = { 378321c8e720SArd Biesheuvel .comp = __VECS(lz4_comp_tv_template), 378421c8e720SArd Biesheuvel .decomp = __VECS(lz4_decomp_tv_template) 37851443cc9bSKOVACS Krisztian } 37861443cc9bSKOVACS Krisztian } 37871443cc9bSKOVACS Krisztian }, { 37881443cc9bSKOVACS Krisztian .alg = "lz4hc", 37891443cc9bSKOVACS Krisztian .test = alg_test_comp, 37901443cc9bSKOVACS Krisztian .fips_allowed = 1, 37911443cc9bSKOVACS Krisztian .suite = { 37921443cc9bSKOVACS Krisztian .comp = { 379321c8e720SArd Biesheuvel .comp = __VECS(lz4hc_comp_tv_template), 379421c8e720SArd Biesheuvel .decomp = __VECS(lz4hc_decomp_tv_template) 37951443cc9bSKOVACS Krisztian } 37961443cc9bSKOVACS Krisztian } 37971443cc9bSKOVACS Krisztian }, { 3798da7f033dSHerbert Xu .alg = "lzo", 3799da7f033dSHerbert Xu .test = alg_test_comp, 38000818904dSMilan Broz .fips_allowed = 1, 3801da7f033dSHerbert Xu .suite = { 3802da7f033dSHerbert Xu .comp = { 380321c8e720SArd Biesheuvel .comp = __VECS(lzo_comp_tv_template), 380421c8e720SArd Biesheuvel .decomp = __VECS(lzo_decomp_tv_template) 3805da7f033dSHerbert Xu } 3806da7f033dSHerbert Xu } 3807da7f033dSHerbert Xu }, { 3808da7f033dSHerbert Xu .alg = "md4", 3809da7f033dSHerbert Xu .test = alg_test_hash, 3810da7f033dSHerbert Xu .suite = { 381121c8e720SArd Biesheuvel .hash = __VECS(md4_tv_template) 3812da7f033dSHerbert Xu } 3813da7f033dSHerbert Xu }, { 3814da7f033dSHerbert Xu .alg = "md5", 3815da7f033dSHerbert Xu .test = alg_test_hash, 3816da7f033dSHerbert Xu .suite = { 381721c8e720SArd Biesheuvel .hash = __VECS(md5_tv_template) 3818da7f033dSHerbert Xu } 3819da7f033dSHerbert Xu }, { 3820da7f033dSHerbert Xu .alg = "michael_mic", 3821da7f033dSHerbert Xu .test = alg_test_hash, 3822da7f033dSHerbert Xu .suite = { 382321c8e720SArd Biesheuvel .hash = __VECS(michael_mic_tv_template) 3824da7f033dSHerbert Xu } 3825da7f033dSHerbert Xu }, { 38264feb4c59SOndrej Mosnacek .alg = "morus1280", 38274feb4c59SOndrej Mosnacek .test = alg_test_aead, 38284feb4c59SOndrej Mosnacek .suite = { 3829a0d608eeSEric Biggers .aead = __VECS(morus1280_tv_template) 38304feb4c59SOndrej Mosnacek } 38314feb4c59SOndrej Mosnacek }, { 38324feb4c59SOndrej Mosnacek .alg = "morus640", 38334feb4c59SOndrej Mosnacek .test = alg_test_aead, 38344feb4c59SOndrej Mosnacek .suite = { 3835a0d608eeSEric Biggers .aead = __VECS(morus640_tv_template) 38364feb4c59SOndrej Mosnacek } 38374feb4c59SOndrej Mosnacek }, { 383826609a21SEric Biggers .alg = "nhpoly1305", 383926609a21SEric Biggers .test = alg_test_hash, 384026609a21SEric Biggers .suite = { 384126609a21SEric Biggers .hash = __VECS(nhpoly1305_tv_template) 384226609a21SEric Biggers } 384326609a21SEric Biggers }, { 3844ba0e14acSPuneet Saxena .alg = "ofb(aes)", 3845ba0e14acSPuneet Saxena .test = alg_test_skcipher, 3846ba0e14acSPuneet Saxena .fips_allowed = 1, 3847ba0e14acSPuneet Saxena .suite = { 384892a4c9feSEric Biggers .cipher = __VECS(aes_ofb_tv_template) 3849ba0e14acSPuneet Saxena } 3850ba0e14acSPuneet Saxena }, { 3851a794d8d8SGilad Ben-Yossef /* Same as ofb(aes) except the key is stored in 3852a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 3853a794d8d8SGilad Ben-Yossef */ 3854a794d8d8SGilad Ben-Yossef .alg = "ofb(paes)", 3855a794d8d8SGilad Ben-Yossef .test = alg_test_null, 3856a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 3857a794d8d8SGilad Ben-Yossef }, { 3858da7f033dSHerbert Xu .alg = "pcbc(fcrypt)", 38591aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3860da7f033dSHerbert Xu .suite = { 386192a4c9feSEric Biggers .cipher = __VECS(fcrypt_pcbc_tv_template) 3862da7f033dSHerbert Xu } 3863da7f033dSHerbert Xu }, { 38641207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha224)", 38651207107cSStephan Mueller .test = alg_test_null, 38661207107cSStephan Mueller .fips_allowed = 1, 38671207107cSStephan Mueller }, { 38681207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha256)", 38691207107cSStephan Mueller .test = alg_test_akcipher, 38701207107cSStephan Mueller .fips_allowed = 1, 38711207107cSStephan Mueller .suite = { 38721207107cSStephan Mueller .akcipher = __VECS(pkcs1pad_rsa_tv_template) 38731207107cSStephan Mueller } 38741207107cSStephan Mueller }, { 38751207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha384)", 38761207107cSStephan Mueller .test = alg_test_null, 38771207107cSStephan Mueller .fips_allowed = 1, 38781207107cSStephan Mueller }, { 38791207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha512)", 38801207107cSStephan Mueller .test = alg_test_null, 38811207107cSStephan Mueller .fips_allowed = 1, 38821207107cSStephan Mueller }, { 3883eee9dc61SMartin Willi .alg = "poly1305", 3884eee9dc61SMartin Willi .test = alg_test_hash, 3885eee9dc61SMartin Willi .suite = { 388621c8e720SArd Biesheuvel .hash = __VECS(poly1305_tv_template) 3887eee9dc61SMartin Willi } 3888eee9dc61SMartin Willi }, { 3889da7f033dSHerbert Xu .alg = "rfc3686(ctr(aes))", 38901aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3891a1915d51SJarod Wilson .fips_allowed = 1, 3892da7f033dSHerbert Xu .suite = { 389392a4c9feSEric Biggers .cipher = __VECS(aes_ctr_rfc3686_tv_template) 3894da7f033dSHerbert Xu } 3895da7f033dSHerbert Xu }, { 38963f31a740SHerbert Xu .alg = "rfc4106(gcm(aes))", 389769435b94SAdrian Hoban .test = alg_test_aead, 3898db71f29aSJarod Wilson .fips_allowed = 1, 389969435b94SAdrian Hoban .suite = { 3900a0d608eeSEric Biggers .aead = __VECS(aes_gcm_rfc4106_tv_template) 390169435b94SAdrian Hoban } 390269435b94SAdrian Hoban }, { 3903544c436aSHerbert Xu .alg = "rfc4309(ccm(aes))", 39045d667322SJarod Wilson .test = alg_test_aead, 3905a1915d51SJarod Wilson .fips_allowed = 1, 39065d667322SJarod Wilson .suite = { 3907a0d608eeSEric Biggers .aead = __VECS(aes_ccm_rfc4309_tv_template) 39085d667322SJarod Wilson } 39095d667322SJarod Wilson }, { 3910bb68745eSHerbert Xu .alg = "rfc4543(gcm(aes))", 3911e9b7441aSJussi Kivilinna .test = alg_test_aead, 3912e9b7441aSJussi Kivilinna .suite = { 3913a0d608eeSEric Biggers .aead = __VECS(aes_gcm_rfc4543_tv_template) 3914e9b7441aSJussi Kivilinna } 3915e9b7441aSJussi Kivilinna }, { 3916af2b76b5SMartin Willi .alg = "rfc7539(chacha20,poly1305)", 3917af2b76b5SMartin Willi .test = alg_test_aead, 3918af2b76b5SMartin Willi .suite = { 3919a0d608eeSEric Biggers .aead = __VECS(rfc7539_tv_template) 3920af2b76b5SMartin Willi } 3921af2b76b5SMartin Willi }, { 39225900758dSMartin Willi .alg = "rfc7539esp(chacha20,poly1305)", 39235900758dSMartin Willi .test = alg_test_aead, 39245900758dSMartin Willi .suite = { 3925a0d608eeSEric Biggers .aead = __VECS(rfc7539esp_tv_template) 39265900758dSMartin Willi } 39275900758dSMartin Willi }, { 3928da7f033dSHerbert Xu .alg = "rmd128", 3929da7f033dSHerbert Xu .test = alg_test_hash, 3930da7f033dSHerbert Xu .suite = { 393121c8e720SArd Biesheuvel .hash = __VECS(rmd128_tv_template) 3932da7f033dSHerbert Xu } 3933da7f033dSHerbert Xu }, { 3934da7f033dSHerbert Xu .alg = "rmd160", 3935da7f033dSHerbert Xu .test = alg_test_hash, 3936da7f033dSHerbert Xu .suite = { 393721c8e720SArd Biesheuvel .hash = __VECS(rmd160_tv_template) 3938da7f033dSHerbert Xu } 3939da7f033dSHerbert Xu }, { 3940da7f033dSHerbert Xu .alg = "rmd256", 3941da7f033dSHerbert Xu .test = alg_test_hash, 3942da7f033dSHerbert Xu .suite = { 394321c8e720SArd Biesheuvel .hash = __VECS(rmd256_tv_template) 3944da7f033dSHerbert Xu } 3945da7f033dSHerbert Xu }, { 3946da7f033dSHerbert Xu .alg = "rmd320", 3947da7f033dSHerbert Xu .test = alg_test_hash, 3948da7f033dSHerbert Xu .suite = { 394921c8e720SArd Biesheuvel .hash = __VECS(rmd320_tv_template) 3950da7f033dSHerbert Xu } 3951da7f033dSHerbert Xu }, { 3952946cc463STadeusz Struk .alg = "rsa", 3953946cc463STadeusz Struk .test = alg_test_akcipher, 3954946cc463STadeusz Struk .fips_allowed = 1, 3955946cc463STadeusz Struk .suite = { 395621c8e720SArd Biesheuvel .akcipher = __VECS(rsa_tv_template) 3957946cc463STadeusz Struk } 3958946cc463STadeusz Struk }, { 3959da7f033dSHerbert Xu .alg = "salsa20", 39601aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3961da7f033dSHerbert Xu .suite = { 396292a4c9feSEric Biggers .cipher = __VECS(salsa20_stream_tv_template) 3963da7f033dSHerbert Xu } 3964da7f033dSHerbert Xu }, { 3965da7f033dSHerbert Xu .alg = "sha1", 3966da7f033dSHerbert Xu .test = alg_test_hash, 3967a1915d51SJarod Wilson .fips_allowed = 1, 3968da7f033dSHerbert Xu .suite = { 396921c8e720SArd Biesheuvel .hash = __VECS(sha1_tv_template) 3970da7f033dSHerbert Xu } 3971da7f033dSHerbert Xu }, { 3972da7f033dSHerbert Xu .alg = "sha224", 3973da7f033dSHerbert Xu .test = alg_test_hash, 3974a1915d51SJarod Wilson .fips_allowed = 1, 3975da7f033dSHerbert Xu .suite = { 397621c8e720SArd Biesheuvel .hash = __VECS(sha224_tv_template) 3977da7f033dSHerbert Xu } 3978da7f033dSHerbert Xu }, { 3979da7f033dSHerbert Xu .alg = "sha256", 3980da7f033dSHerbert Xu .test = alg_test_hash, 3981a1915d51SJarod Wilson .fips_allowed = 1, 3982da7f033dSHerbert Xu .suite = { 398321c8e720SArd Biesheuvel .hash = __VECS(sha256_tv_template) 3984da7f033dSHerbert Xu } 3985da7f033dSHerbert Xu }, { 398679cc6ab8Sraveendra padasalagi .alg = "sha3-224", 398779cc6ab8Sraveendra padasalagi .test = alg_test_hash, 398879cc6ab8Sraveendra padasalagi .fips_allowed = 1, 398979cc6ab8Sraveendra padasalagi .suite = { 399021c8e720SArd Biesheuvel .hash = __VECS(sha3_224_tv_template) 399179cc6ab8Sraveendra padasalagi } 399279cc6ab8Sraveendra padasalagi }, { 399379cc6ab8Sraveendra padasalagi .alg = "sha3-256", 399479cc6ab8Sraveendra padasalagi .test = alg_test_hash, 399579cc6ab8Sraveendra padasalagi .fips_allowed = 1, 399679cc6ab8Sraveendra padasalagi .suite = { 399721c8e720SArd Biesheuvel .hash = __VECS(sha3_256_tv_template) 399879cc6ab8Sraveendra padasalagi } 399979cc6ab8Sraveendra padasalagi }, { 400079cc6ab8Sraveendra padasalagi .alg = "sha3-384", 400179cc6ab8Sraveendra padasalagi .test = alg_test_hash, 400279cc6ab8Sraveendra padasalagi .fips_allowed = 1, 400379cc6ab8Sraveendra padasalagi .suite = { 400421c8e720SArd Biesheuvel .hash = __VECS(sha3_384_tv_template) 400579cc6ab8Sraveendra padasalagi } 400679cc6ab8Sraveendra padasalagi }, { 400779cc6ab8Sraveendra padasalagi .alg = "sha3-512", 400879cc6ab8Sraveendra padasalagi .test = alg_test_hash, 400979cc6ab8Sraveendra padasalagi .fips_allowed = 1, 401079cc6ab8Sraveendra padasalagi .suite = { 401121c8e720SArd Biesheuvel .hash = __VECS(sha3_512_tv_template) 401279cc6ab8Sraveendra padasalagi } 401379cc6ab8Sraveendra padasalagi }, { 4014da7f033dSHerbert Xu .alg = "sha384", 4015da7f033dSHerbert Xu .test = alg_test_hash, 4016a1915d51SJarod Wilson .fips_allowed = 1, 4017da7f033dSHerbert Xu .suite = { 401821c8e720SArd Biesheuvel .hash = __VECS(sha384_tv_template) 4019da7f033dSHerbert Xu } 4020da7f033dSHerbert Xu }, { 4021da7f033dSHerbert Xu .alg = "sha512", 4022da7f033dSHerbert Xu .test = alg_test_hash, 4023a1915d51SJarod Wilson .fips_allowed = 1, 4024da7f033dSHerbert Xu .suite = { 402521c8e720SArd Biesheuvel .hash = __VECS(sha512_tv_template) 4026da7f033dSHerbert Xu } 4027da7f033dSHerbert Xu }, { 4028b7e27530SGilad Ben-Yossef .alg = "sm3", 4029b7e27530SGilad Ben-Yossef .test = alg_test_hash, 4030b7e27530SGilad Ben-Yossef .suite = { 4031b7e27530SGilad Ben-Yossef .hash = __VECS(sm3_tv_template) 4032b7e27530SGilad Ben-Yossef } 4033b7e27530SGilad Ben-Yossef }, { 403425a0b9d4SVitaly Chikunov .alg = "streebog256", 403525a0b9d4SVitaly Chikunov .test = alg_test_hash, 403625a0b9d4SVitaly Chikunov .suite = { 403725a0b9d4SVitaly Chikunov .hash = __VECS(streebog256_tv_template) 403825a0b9d4SVitaly Chikunov } 403925a0b9d4SVitaly Chikunov }, { 404025a0b9d4SVitaly Chikunov .alg = "streebog512", 404125a0b9d4SVitaly Chikunov .test = alg_test_hash, 404225a0b9d4SVitaly Chikunov .suite = { 404325a0b9d4SVitaly Chikunov .hash = __VECS(streebog512_tv_template) 404425a0b9d4SVitaly Chikunov } 404525a0b9d4SVitaly Chikunov }, { 4046da7f033dSHerbert Xu .alg = "tgr128", 4047da7f033dSHerbert Xu .test = alg_test_hash, 4048da7f033dSHerbert Xu .suite = { 404921c8e720SArd Biesheuvel .hash = __VECS(tgr128_tv_template) 4050da7f033dSHerbert Xu } 4051da7f033dSHerbert Xu }, { 4052da7f033dSHerbert Xu .alg = "tgr160", 4053da7f033dSHerbert Xu .test = alg_test_hash, 4054da7f033dSHerbert Xu .suite = { 405521c8e720SArd Biesheuvel .hash = __VECS(tgr160_tv_template) 4056da7f033dSHerbert Xu } 4057da7f033dSHerbert Xu }, { 4058da7f033dSHerbert Xu .alg = "tgr192", 4059da7f033dSHerbert Xu .test = alg_test_hash, 4060da7f033dSHerbert Xu .suite = { 406121c8e720SArd Biesheuvel .hash = __VECS(tgr192_tv_template) 4062da7f033dSHerbert Xu } 4063da7f033dSHerbert Xu }, { 4064ed331adaSEric Biggers .alg = "vmac64(aes)", 4065ed331adaSEric Biggers .test = alg_test_hash, 4066ed331adaSEric Biggers .suite = { 4067ed331adaSEric Biggers .hash = __VECS(vmac64_aes_tv_template) 4068ed331adaSEric Biggers } 4069ed331adaSEric Biggers }, { 4070da7f033dSHerbert Xu .alg = "wp256", 4071da7f033dSHerbert Xu .test = alg_test_hash, 4072da7f033dSHerbert Xu .suite = { 407321c8e720SArd Biesheuvel .hash = __VECS(wp256_tv_template) 4074da7f033dSHerbert Xu } 4075da7f033dSHerbert Xu }, { 4076da7f033dSHerbert Xu .alg = "wp384", 4077da7f033dSHerbert Xu .test = alg_test_hash, 4078da7f033dSHerbert Xu .suite = { 407921c8e720SArd Biesheuvel .hash = __VECS(wp384_tv_template) 4080da7f033dSHerbert Xu } 4081da7f033dSHerbert Xu }, { 4082da7f033dSHerbert Xu .alg = "wp512", 4083da7f033dSHerbert Xu .test = alg_test_hash, 4084da7f033dSHerbert Xu .suite = { 408521c8e720SArd Biesheuvel .hash = __VECS(wp512_tv_template) 4086da7f033dSHerbert Xu } 4087da7f033dSHerbert Xu }, { 4088da7f033dSHerbert Xu .alg = "xcbc(aes)", 4089da7f033dSHerbert Xu .test = alg_test_hash, 4090da7f033dSHerbert Xu .suite = { 409121c8e720SArd Biesheuvel .hash = __VECS(aes_xcbc128_tv_template) 4092da7f033dSHerbert Xu } 4093da7f033dSHerbert Xu }, { 4094aa762409SEric Biggers .alg = "xchacha12", 4095aa762409SEric Biggers .test = alg_test_skcipher, 4096aa762409SEric Biggers .suite = { 4097aa762409SEric Biggers .cipher = __VECS(xchacha12_tv_template) 4098aa762409SEric Biggers }, 4099aa762409SEric Biggers }, { 4100de61d7aeSEric Biggers .alg = "xchacha20", 4101de61d7aeSEric Biggers .test = alg_test_skcipher, 4102de61d7aeSEric Biggers .suite = { 4103de61d7aeSEric Biggers .cipher = __VECS(xchacha20_tv_template) 4104de61d7aeSEric Biggers }, 4105de61d7aeSEric Biggers }, { 4106da7f033dSHerbert Xu .alg = "xts(aes)", 41071aa4ecd9SHerbert Xu .test = alg_test_skcipher, 41082918aa8dSJarod Wilson .fips_allowed = 1, 4109da7f033dSHerbert Xu .suite = { 411092a4c9feSEric Biggers .cipher = __VECS(aes_xts_tv_template) 4111da7f033dSHerbert Xu } 41120c01aed5SGeert Uytterhoeven }, { 41130840605eSJussi Kivilinna .alg = "xts(camellia)", 41140840605eSJussi Kivilinna .test = alg_test_skcipher, 41150840605eSJussi Kivilinna .suite = { 411692a4c9feSEric Biggers .cipher = __VECS(camellia_xts_tv_template) 41170840605eSJussi Kivilinna } 41180840605eSJussi Kivilinna }, { 41199b8b0405SJohannes Goetzfried .alg = "xts(cast6)", 41209b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 41219b8b0405SJohannes Goetzfried .suite = { 412292a4c9feSEric Biggers .cipher = __VECS(cast6_xts_tv_template) 41239b8b0405SJohannes Goetzfried } 41249b8b0405SJohannes Goetzfried }, { 412515f47ce5SGilad Ben-Yossef /* Same as xts(aes) except the key is stored in 412615f47ce5SGilad Ben-Yossef * hardware secure memory which we reference by index 412715f47ce5SGilad Ben-Yossef */ 412815f47ce5SGilad Ben-Yossef .alg = "xts(paes)", 412915f47ce5SGilad Ben-Yossef .test = alg_test_null, 413015f47ce5SGilad Ben-Yossef .fips_allowed = 1, 413115f47ce5SGilad Ben-Yossef }, { 413218be20b9SJussi Kivilinna .alg = "xts(serpent)", 413318be20b9SJussi Kivilinna .test = alg_test_skcipher, 413418be20b9SJussi Kivilinna .suite = { 413592a4c9feSEric Biggers .cipher = __VECS(serpent_xts_tv_template) 413618be20b9SJussi Kivilinna } 413718be20b9SJussi Kivilinna }, { 4138aed265b9SJussi Kivilinna .alg = "xts(twofish)", 4139aed265b9SJussi Kivilinna .test = alg_test_skcipher, 4140aed265b9SJussi Kivilinna .suite = { 414192a4c9feSEric Biggers .cipher = __VECS(tf_xts_tv_template) 4142aed265b9SJussi Kivilinna } 4143a368f43dSGiovanni Cabiddu }, { 414415f47ce5SGilad Ben-Yossef .alg = "xts4096(paes)", 414515f47ce5SGilad Ben-Yossef .test = alg_test_null, 414615f47ce5SGilad Ben-Yossef .fips_allowed = 1, 414715f47ce5SGilad Ben-Yossef }, { 414815f47ce5SGilad Ben-Yossef .alg = "xts512(paes)", 414915f47ce5SGilad Ben-Yossef .test = alg_test_null, 415015f47ce5SGilad Ben-Yossef .fips_allowed = 1, 415115f47ce5SGilad Ben-Yossef }, { 4152a368f43dSGiovanni Cabiddu .alg = "zlib-deflate", 4153a368f43dSGiovanni Cabiddu .test = alg_test_comp, 4154a368f43dSGiovanni Cabiddu .fips_allowed = 1, 4155a368f43dSGiovanni Cabiddu .suite = { 4156a368f43dSGiovanni Cabiddu .comp = { 4157a368f43dSGiovanni Cabiddu .comp = __VECS(zlib_deflate_comp_tv_template), 4158a368f43dSGiovanni Cabiddu .decomp = __VECS(zlib_deflate_decomp_tv_template) 4159a368f43dSGiovanni Cabiddu } 4160a368f43dSGiovanni Cabiddu } 4161d28fc3dbSNick Terrell }, { 4162d28fc3dbSNick Terrell .alg = "zstd", 4163d28fc3dbSNick Terrell .test = alg_test_comp, 4164d28fc3dbSNick Terrell .fips_allowed = 1, 4165d28fc3dbSNick Terrell .suite = { 4166d28fc3dbSNick Terrell .comp = { 4167d28fc3dbSNick Terrell .comp = __VECS(zstd_comp_tv_template), 4168d28fc3dbSNick Terrell .decomp = __VECS(zstd_decomp_tv_template) 4169d28fc3dbSNick Terrell } 4170d28fc3dbSNick Terrell } 4171da7f033dSHerbert Xu } 4172da7f033dSHerbert Xu }; 4173da7f033dSHerbert Xu 41743f47a03dSEric Biggers static void alg_check_test_descs_order(void) 41755714758bSJussi Kivilinna { 41765714758bSJussi Kivilinna int i; 41775714758bSJussi Kivilinna 41785714758bSJussi Kivilinna for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) { 41795714758bSJussi Kivilinna int diff = strcmp(alg_test_descs[i - 1].alg, 41805714758bSJussi Kivilinna alg_test_descs[i].alg); 41815714758bSJussi Kivilinna 41825714758bSJussi Kivilinna if (WARN_ON(diff > 0)) { 41835714758bSJussi Kivilinna pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n", 41845714758bSJussi Kivilinna alg_test_descs[i - 1].alg, 41855714758bSJussi Kivilinna alg_test_descs[i].alg); 41865714758bSJussi Kivilinna } 41875714758bSJussi Kivilinna 41885714758bSJussi Kivilinna if (WARN_ON(diff == 0)) { 41895714758bSJussi Kivilinna pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n", 41905714758bSJussi Kivilinna alg_test_descs[i].alg); 41915714758bSJussi Kivilinna } 41925714758bSJussi Kivilinna } 41935714758bSJussi Kivilinna } 41945714758bSJussi Kivilinna 41953f47a03dSEric Biggers static void alg_check_testvec_configs(void) 41963f47a03dSEric Biggers { 41974e7babbaSEric Biggers int i; 41984e7babbaSEric Biggers 41994e7babbaSEric Biggers for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) 42004e7babbaSEric Biggers WARN_ON(!valid_testvec_config( 42014e7babbaSEric Biggers &default_cipher_testvec_configs[i])); 42023f47a03dSEric Biggers } 42033f47a03dSEric Biggers 42043f47a03dSEric Biggers static void testmgr_onetime_init(void) 42053f47a03dSEric Biggers { 42063f47a03dSEric Biggers alg_check_test_descs_order(); 42073f47a03dSEric Biggers alg_check_testvec_configs(); 42085b2706a4SEric Biggers 42095b2706a4SEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 42105b2706a4SEric Biggers pr_warn("alg: extra crypto tests enabled. This is intended for developer use only.\n"); 42115b2706a4SEric Biggers #endif 42123f47a03dSEric Biggers } 42133f47a03dSEric Biggers 42141aa4ecd9SHerbert Xu static int alg_find_test(const char *alg) 4215da7f033dSHerbert Xu { 4216da7f033dSHerbert Xu int start = 0; 4217da7f033dSHerbert Xu int end = ARRAY_SIZE(alg_test_descs); 4218da7f033dSHerbert Xu 4219da7f033dSHerbert Xu while (start < end) { 4220da7f033dSHerbert Xu int i = (start + end) / 2; 4221da7f033dSHerbert Xu int diff = strcmp(alg_test_descs[i].alg, alg); 4222da7f033dSHerbert Xu 4223da7f033dSHerbert Xu if (diff > 0) { 4224da7f033dSHerbert Xu end = i; 4225da7f033dSHerbert Xu continue; 4226da7f033dSHerbert Xu } 4227da7f033dSHerbert Xu 4228da7f033dSHerbert Xu if (diff < 0) { 4229da7f033dSHerbert Xu start = i + 1; 4230da7f033dSHerbert Xu continue; 4231da7f033dSHerbert Xu } 4232da7f033dSHerbert Xu 42331aa4ecd9SHerbert Xu return i; 4234da7f033dSHerbert Xu } 4235da7f033dSHerbert Xu 42361aa4ecd9SHerbert Xu return -1; 42371aa4ecd9SHerbert Xu } 42381aa4ecd9SHerbert Xu 42391aa4ecd9SHerbert Xu int alg_test(const char *driver, const char *alg, u32 type, u32 mask) 42401aa4ecd9SHerbert Xu { 42411aa4ecd9SHerbert Xu int i; 4242a68f6610SHerbert Xu int j; 4243d12d6b6dSNeil Horman int rc; 42441aa4ecd9SHerbert Xu 42459e5c9fe4SRichard W.M. Jones if (!fips_enabled && notests) { 42469e5c9fe4SRichard W.M. Jones printk_once(KERN_INFO "alg: self-tests disabled\n"); 42479e5c9fe4SRichard W.M. Jones return 0; 42489e5c9fe4SRichard W.M. Jones } 42499e5c9fe4SRichard W.M. Jones 42503f47a03dSEric Biggers DO_ONCE(testmgr_onetime_init); 42515714758bSJussi Kivilinna 42521aa4ecd9SHerbert Xu if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) { 42531aa4ecd9SHerbert Xu char nalg[CRYPTO_MAX_ALG_NAME]; 42541aa4ecd9SHerbert Xu 42551aa4ecd9SHerbert Xu if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >= 42561aa4ecd9SHerbert Xu sizeof(nalg)) 42571aa4ecd9SHerbert Xu return -ENAMETOOLONG; 42581aa4ecd9SHerbert Xu 42591aa4ecd9SHerbert Xu i = alg_find_test(nalg); 42601aa4ecd9SHerbert Xu if (i < 0) 42611aa4ecd9SHerbert Xu goto notest; 42621aa4ecd9SHerbert Xu 4263a3bef3a3SJarod Wilson if (fips_enabled && !alg_test_descs[i].fips_allowed) 4264a3bef3a3SJarod Wilson goto non_fips_alg; 4265a3bef3a3SJarod Wilson 4266941fb328SJarod Wilson rc = alg_test_cipher(alg_test_descs + i, driver, type, mask); 4267941fb328SJarod Wilson goto test_done; 42681aa4ecd9SHerbert Xu } 42691aa4ecd9SHerbert Xu 42701aa4ecd9SHerbert Xu i = alg_find_test(alg); 4271a68f6610SHerbert Xu j = alg_find_test(driver); 4272a68f6610SHerbert Xu if (i < 0 && j < 0) 42731aa4ecd9SHerbert Xu goto notest; 42741aa4ecd9SHerbert Xu 4275a68f6610SHerbert Xu if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) || 4276a68f6610SHerbert Xu (j >= 0 && !alg_test_descs[j].fips_allowed))) 4277a3bef3a3SJarod Wilson goto non_fips_alg; 4278a3bef3a3SJarod Wilson 4279a68f6610SHerbert Xu rc = 0; 4280a68f6610SHerbert Xu if (i >= 0) 4281a68f6610SHerbert Xu rc |= alg_test_descs[i].test(alg_test_descs + i, driver, 42821aa4ecd9SHerbert Xu type, mask); 4283032c8cacSCristian Stoica if (j >= 0 && j != i) 4284a68f6610SHerbert Xu rc |= alg_test_descs[j].test(alg_test_descs + j, driver, 4285a68f6610SHerbert Xu type, mask); 4286a68f6610SHerbert Xu 4287941fb328SJarod Wilson test_done: 4288d12d6b6dSNeil Horman if (fips_enabled && rc) 4289d12d6b6dSNeil Horman panic("%s: %s alg self test failed in fips mode!\n", driver, alg); 4290d12d6b6dSNeil Horman 429129ecd4abSJarod Wilson if (fips_enabled && !rc) 42923e8cffd4SMasanari Iida pr_info("alg: self-tests for %s (%s) passed\n", driver, alg); 429329ecd4abSJarod Wilson 4294d12d6b6dSNeil Horman return rc; 42951aa4ecd9SHerbert Xu 42961aa4ecd9SHerbert Xu notest: 4297da7f033dSHerbert Xu printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); 4298da7f033dSHerbert Xu return 0; 4299a3bef3a3SJarod Wilson non_fips_alg: 4300a3bef3a3SJarod Wilson return -EINVAL; 4301da7f033dSHerbert Xu } 43020b767f96SAlexander Shishkin 4303326a6346SHerbert Xu #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */ 43040b767f96SAlexander Shishkin 4305da7f033dSHerbert Xu EXPORT_SYMBOL_GPL(alg_test); 4306