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 * Used by test_cipher() 76da7f033dSHerbert Xu */ 77da7f033dSHerbert Xu #define ENCRYPT 1 78da7f033dSHerbert Xu #define DECRYPT 0 79da7f033dSHerbert Xu 80da7f033dSHerbert Xu struct aead_test_suite { 81b13b1e0cSEric Biggers const struct aead_testvec *vecs; 82da7f033dSHerbert Xu unsigned int count; 83da7f033dSHerbert Xu }; 84da7f033dSHerbert Xu 85da7f033dSHerbert Xu struct cipher_test_suite { 86b13b1e0cSEric Biggers const struct cipher_testvec *vecs; 87da7f033dSHerbert Xu unsigned int count; 88da7f033dSHerbert Xu }; 89da7f033dSHerbert Xu 90da7f033dSHerbert Xu struct comp_test_suite { 91da7f033dSHerbert Xu struct { 92b13b1e0cSEric Biggers const struct comp_testvec *vecs; 93da7f033dSHerbert Xu unsigned int count; 94da7f033dSHerbert Xu } comp, decomp; 95da7f033dSHerbert Xu }; 96da7f033dSHerbert Xu 97da7f033dSHerbert Xu struct hash_test_suite { 98b13b1e0cSEric Biggers const struct hash_testvec *vecs; 99da7f033dSHerbert Xu unsigned int count; 100da7f033dSHerbert Xu }; 101da7f033dSHerbert Xu 1027647d6ceSJarod Wilson struct cprng_test_suite { 103b13b1e0cSEric Biggers const struct cprng_testvec *vecs; 1047647d6ceSJarod Wilson unsigned int count; 1057647d6ceSJarod Wilson }; 1067647d6ceSJarod Wilson 10764d1cdfbSStephan Mueller struct drbg_test_suite { 108b13b1e0cSEric Biggers const struct drbg_testvec *vecs; 10964d1cdfbSStephan Mueller unsigned int count; 11064d1cdfbSStephan Mueller }; 11164d1cdfbSStephan Mueller 112946cc463STadeusz Struk struct akcipher_test_suite { 113b13b1e0cSEric Biggers const struct akcipher_testvec *vecs; 114946cc463STadeusz Struk unsigned int count; 115946cc463STadeusz Struk }; 116946cc463STadeusz Struk 117802c7f1cSSalvatore Benedetto struct kpp_test_suite { 118b13b1e0cSEric Biggers const struct kpp_testvec *vecs; 119802c7f1cSSalvatore Benedetto unsigned int count; 120802c7f1cSSalvatore Benedetto }; 121802c7f1cSSalvatore Benedetto 122da7f033dSHerbert Xu struct alg_test_desc { 123da7f033dSHerbert Xu const char *alg; 124da7f033dSHerbert Xu int (*test)(const struct alg_test_desc *desc, const char *driver, 125da7f033dSHerbert Xu u32 type, u32 mask); 126a1915d51SJarod Wilson int fips_allowed; /* set if alg is allowed in fips mode */ 127da7f033dSHerbert Xu 128da7f033dSHerbert Xu union { 129da7f033dSHerbert Xu struct aead_test_suite aead; 130da7f033dSHerbert Xu struct cipher_test_suite cipher; 131da7f033dSHerbert Xu struct comp_test_suite comp; 132da7f033dSHerbert Xu struct hash_test_suite hash; 1337647d6ceSJarod Wilson struct cprng_test_suite cprng; 13464d1cdfbSStephan Mueller struct drbg_test_suite drbg; 135946cc463STadeusz Struk struct akcipher_test_suite akcipher; 136802c7f1cSSalvatore Benedetto struct kpp_test_suite kpp; 137da7f033dSHerbert Xu } suite; 138da7f033dSHerbert Xu }; 139da7f033dSHerbert Xu 140da7f033dSHerbert Xu static void hexdump(unsigned char *buf, unsigned int len) 141da7f033dSHerbert Xu { 142da7f033dSHerbert Xu print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, 143da7f033dSHerbert Xu 16, 1, 144da7f033dSHerbert Xu buf, len, false); 145da7f033dSHerbert Xu } 146da7f033dSHerbert Xu 1473f47a03dSEric Biggers static int __testmgr_alloc_buf(char *buf[XBUFSIZE], int order) 148f8b0d4d0SHerbert Xu { 149f8b0d4d0SHerbert Xu int i; 150f8b0d4d0SHerbert Xu 151f8b0d4d0SHerbert Xu for (i = 0; i < XBUFSIZE; i++) { 1523f47a03dSEric Biggers buf[i] = (char *)__get_free_pages(GFP_KERNEL, order); 153f8b0d4d0SHerbert Xu if (!buf[i]) 154f8b0d4d0SHerbert Xu goto err_free_buf; 155f8b0d4d0SHerbert Xu } 156f8b0d4d0SHerbert Xu 157f8b0d4d0SHerbert Xu return 0; 158f8b0d4d0SHerbert Xu 159f8b0d4d0SHerbert Xu err_free_buf: 160f8b0d4d0SHerbert Xu while (i-- > 0) 1613f47a03dSEric Biggers free_pages((unsigned long)buf[i], order); 162f8b0d4d0SHerbert Xu 163f8b0d4d0SHerbert Xu return -ENOMEM; 164f8b0d4d0SHerbert Xu } 165f8b0d4d0SHerbert Xu 1663f47a03dSEric Biggers static int testmgr_alloc_buf(char *buf[XBUFSIZE]) 1673f47a03dSEric Biggers { 1683f47a03dSEric Biggers return __testmgr_alloc_buf(buf, 0); 1693f47a03dSEric Biggers } 1703f47a03dSEric Biggers 1713f47a03dSEric Biggers static void __testmgr_free_buf(char *buf[XBUFSIZE], int order) 172f8b0d4d0SHerbert Xu { 173f8b0d4d0SHerbert Xu int i; 174f8b0d4d0SHerbert Xu 175f8b0d4d0SHerbert Xu for (i = 0; i < XBUFSIZE; i++) 1763f47a03dSEric Biggers free_pages((unsigned long)buf[i], order); 1773f47a03dSEric Biggers } 1783f47a03dSEric Biggers 1793f47a03dSEric Biggers static void testmgr_free_buf(char *buf[XBUFSIZE]) 1803f47a03dSEric Biggers { 1813f47a03dSEric Biggers __testmgr_free_buf(buf, 0); 1823f47a03dSEric Biggers } 1833f47a03dSEric Biggers 1843f47a03dSEric Biggers #define TESTMGR_POISON_BYTE 0xfe 1853f47a03dSEric Biggers #define TESTMGR_POISON_LEN 16 1863f47a03dSEric Biggers 1873f47a03dSEric Biggers static inline void testmgr_poison(void *addr, size_t len) 1883f47a03dSEric Biggers { 1893f47a03dSEric Biggers memset(addr, TESTMGR_POISON_BYTE, len); 1903f47a03dSEric Biggers } 1913f47a03dSEric Biggers 1923f47a03dSEric Biggers /* Is the memory region still fully poisoned? */ 1933f47a03dSEric Biggers static inline bool testmgr_is_poison(const void *addr, size_t len) 1943f47a03dSEric Biggers { 1953f47a03dSEric Biggers return memchr_inv(addr, TESTMGR_POISON_BYTE, len) == NULL; 1963f47a03dSEric Biggers } 1973f47a03dSEric Biggers 1983f47a03dSEric Biggers /* flush type for hash algorithms */ 1993f47a03dSEric Biggers enum flush_type { 2003f47a03dSEric Biggers /* merge with update of previous buffer(s) */ 2013f47a03dSEric Biggers FLUSH_TYPE_NONE = 0, 2023f47a03dSEric Biggers 2033f47a03dSEric Biggers /* update with previous buffer(s) before doing this one */ 2043f47a03dSEric Biggers FLUSH_TYPE_FLUSH, 2053f47a03dSEric Biggers 2063f47a03dSEric Biggers /* likewise, but also export and re-import the intermediate state */ 2073f47a03dSEric Biggers FLUSH_TYPE_REIMPORT, 2083f47a03dSEric Biggers }; 2093f47a03dSEric Biggers 2103f47a03dSEric Biggers /* finalization function for hash algorithms */ 2113f47a03dSEric Biggers enum finalization_type { 2123f47a03dSEric Biggers FINALIZATION_TYPE_FINAL, /* use final() */ 2133f47a03dSEric Biggers FINALIZATION_TYPE_FINUP, /* use finup() */ 2143f47a03dSEric Biggers FINALIZATION_TYPE_DIGEST, /* use digest() */ 2153f47a03dSEric Biggers }; 2163f47a03dSEric Biggers 2173f47a03dSEric Biggers #define TEST_SG_TOTAL 10000 2183f47a03dSEric Biggers 2193f47a03dSEric Biggers /** 2203f47a03dSEric Biggers * struct test_sg_division - description of a scatterlist entry 2213f47a03dSEric Biggers * 2223f47a03dSEric Biggers * This struct describes one entry of a scatterlist being constructed to check a 2233f47a03dSEric Biggers * crypto test vector. 2243f47a03dSEric Biggers * 2253f47a03dSEric Biggers * @proportion_of_total: length of this chunk relative to the total length, 2263f47a03dSEric Biggers * given as a proportion out of TEST_SG_TOTAL so that it 2273f47a03dSEric Biggers * scales to fit any test vector 2283f47a03dSEric Biggers * @offset: byte offset into a 2-page buffer at which this chunk will start 2293f47a03dSEric Biggers * @offset_relative_to_alignmask: if true, add the algorithm's alignmask to the 2303f47a03dSEric Biggers * @offset 2313f47a03dSEric Biggers * @flush_type: for hashes, whether an update() should be done now vs. 2323f47a03dSEric Biggers * continuing to accumulate data 2333f47a03dSEric Biggers */ 2343f47a03dSEric Biggers struct test_sg_division { 2353f47a03dSEric Biggers unsigned int proportion_of_total; 2363f47a03dSEric Biggers unsigned int offset; 2373f47a03dSEric Biggers bool offset_relative_to_alignmask; 2383f47a03dSEric Biggers enum flush_type flush_type; 2393f47a03dSEric Biggers }; 2403f47a03dSEric Biggers 2413f47a03dSEric Biggers /** 2423f47a03dSEric Biggers * struct testvec_config - configuration for testing a crypto test vector 2433f47a03dSEric Biggers * 2443f47a03dSEric Biggers * This struct describes the data layout and other parameters with which each 2453f47a03dSEric Biggers * crypto test vector can be tested. 2463f47a03dSEric Biggers * 2473f47a03dSEric Biggers * @name: name of this config, logged for debugging purposes if a test fails 2483f47a03dSEric Biggers * @inplace: operate on the data in-place, if applicable for the algorithm type? 2493f47a03dSEric Biggers * @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP 2503f47a03dSEric Biggers * @src_divs: description of how to arrange the source scatterlist 2513f47a03dSEric Biggers * @dst_divs: description of how to arrange the dst scatterlist, if applicable 2523f47a03dSEric Biggers * for the algorithm type. Defaults to @src_divs if unset. 2533f47a03dSEric Biggers * @iv_offset: misalignment of the IV in the range [0..MAX_ALGAPI_ALIGNMASK+1], 2543f47a03dSEric Biggers * where 0 is aligned to a 2*(MAX_ALGAPI_ALIGNMASK+1) byte boundary 2553f47a03dSEric Biggers * @iv_offset_relative_to_alignmask: if true, add the algorithm's alignmask to 2563f47a03dSEric Biggers * the @iv_offset 2573f47a03dSEric Biggers * @finalization_type: what finalization function to use for hashes 2583f47a03dSEric Biggers */ 2593f47a03dSEric Biggers struct testvec_config { 2603f47a03dSEric Biggers const char *name; 2613f47a03dSEric Biggers bool inplace; 2623f47a03dSEric Biggers u32 req_flags; 2633f47a03dSEric Biggers struct test_sg_division src_divs[XBUFSIZE]; 2643f47a03dSEric Biggers struct test_sg_division dst_divs[XBUFSIZE]; 2653f47a03dSEric Biggers unsigned int iv_offset; 2663f47a03dSEric Biggers bool iv_offset_relative_to_alignmask; 2673f47a03dSEric Biggers enum finalization_type finalization_type; 2683f47a03dSEric Biggers }; 2693f47a03dSEric Biggers 2703f47a03dSEric Biggers #define TESTVEC_CONFIG_NAMELEN 192 2713f47a03dSEric Biggers 2724e7babbaSEric Biggers /* 2734e7babbaSEric Biggers * The following are the lists of testvec_configs to test for each algorithm 2744e7babbaSEric Biggers * type when the basic crypto self-tests are enabled, i.e. when 2754e7babbaSEric Biggers * CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is unset. They aim to provide good test 2764e7babbaSEric Biggers * coverage, while keeping the test time much shorter than the full fuzz tests 2774e7babbaSEric Biggers * so that the basic tests can be enabled in a wider range of circumstances. 2784e7babbaSEric Biggers */ 2794e7babbaSEric Biggers 2804e7babbaSEric Biggers /* Configs for skciphers and aeads */ 2814e7babbaSEric Biggers static const struct testvec_config default_cipher_testvec_configs[] = { 2824e7babbaSEric Biggers { 2834e7babbaSEric Biggers .name = "in-place", 2844e7babbaSEric Biggers .inplace = true, 2854e7babbaSEric Biggers .src_divs = { { .proportion_of_total = 10000 } }, 2864e7babbaSEric Biggers }, { 2874e7babbaSEric Biggers .name = "out-of-place", 2884e7babbaSEric Biggers .src_divs = { { .proportion_of_total = 10000 } }, 2894e7babbaSEric Biggers }, { 2904e7babbaSEric Biggers .name = "unaligned buffer, offset=1", 2914e7babbaSEric Biggers .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, 2924e7babbaSEric Biggers .iv_offset = 1, 2934e7babbaSEric Biggers }, { 2944e7babbaSEric Biggers .name = "buffer aligned only to alignmask", 2954e7babbaSEric Biggers .src_divs = { 2964e7babbaSEric Biggers { 2974e7babbaSEric Biggers .proportion_of_total = 10000, 2984e7babbaSEric Biggers .offset = 1, 2994e7babbaSEric Biggers .offset_relative_to_alignmask = true, 3004e7babbaSEric Biggers }, 3014e7babbaSEric Biggers }, 3024e7babbaSEric Biggers .iv_offset = 1, 3034e7babbaSEric Biggers .iv_offset_relative_to_alignmask = true, 3044e7babbaSEric Biggers }, { 3054e7babbaSEric Biggers .name = "two even aligned splits", 3064e7babbaSEric Biggers .src_divs = { 3074e7babbaSEric Biggers { .proportion_of_total = 5000 }, 3084e7babbaSEric Biggers { .proportion_of_total = 5000 }, 3094e7babbaSEric Biggers }, 3104e7babbaSEric Biggers }, { 3114e7babbaSEric Biggers .name = "uneven misaligned splits, may sleep", 3124e7babbaSEric Biggers .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, 3134e7babbaSEric Biggers .src_divs = { 3144e7babbaSEric Biggers { .proportion_of_total = 1900, .offset = 33 }, 3154e7babbaSEric Biggers { .proportion_of_total = 3300, .offset = 7 }, 3164e7babbaSEric Biggers { .proportion_of_total = 4800, .offset = 18 }, 3174e7babbaSEric Biggers }, 3184e7babbaSEric Biggers .iv_offset = 3, 3194e7babbaSEric Biggers }, { 3204e7babbaSEric Biggers .name = "misaligned splits crossing pages, inplace", 3214e7babbaSEric Biggers .inplace = true, 3224e7babbaSEric Biggers .src_divs = { 3234e7babbaSEric Biggers { 3244e7babbaSEric Biggers .proportion_of_total = 7500, 3254e7babbaSEric Biggers .offset = PAGE_SIZE - 32 3264e7babbaSEric Biggers }, { 3274e7babbaSEric Biggers .proportion_of_total = 2500, 3284e7babbaSEric Biggers .offset = PAGE_SIZE - 7 3294e7babbaSEric Biggers }, 3304e7babbaSEric Biggers }, 3314e7babbaSEric Biggers } 3324e7babbaSEric Biggers }; 3334e7babbaSEric Biggers 3344cc2dcf9SEric Biggers static const struct testvec_config default_hash_testvec_configs[] = { 3354cc2dcf9SEric Biggers { 3364cc2dcf9SEric Biggers .name = "init+update+final aligned buffer", 3374cc2dcf9SEric Biggers .src_divs = { { .proportion_of_total = 10000 } }, 3384cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_FINAL, 3394cc2dcf9SEric Biggers }, { 3404cc2dcf9SEric Biggers .name = "init+finup aligned buffer", 3414cc2dcf9SEric Biggers .src_divs = { { .proportion_of_total = 10000 } }, 3424cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_FINUP, 3434cc2dcf9SEric Biggers }, { 3444cc2dcf9SEric Biggers .name = "digest aligned buffer", 3454cc2dcf9SEric Biggers .src_divs = { { .proportion_of_total = 10000 } }, 3464cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_DIGEST, 3474cc2dcf9SEric Biggers }, { 3484cc2dcf9SEric Biggers .name = "init+update+final misaligned buffer", 3494cc2dcf9SEric Biggers .src_divs = { { .proportion_of_total = 10000, .offset = 1 } }, 3504cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_FINAL, 3514cc2dcf9SEric Biggers }, { 3524cc2dcf9SEric Biggers .name = "digest buffer aligned only to alignmask", 3534cc2dcf9SEric Biggers .src_divs = { 3544cc2dcf9SEric Biggers { 3554cc2dcf9SEric Biggers .proportion_of_total = 10000, 3564cc2dcf9SEric Biggers .offset = 1, 3574cc2dcf9SEric Biggers .offset_relative_to_alignmask = true, 3584cc2dcf9SEric Biggers }, 3594cc2dcf9SEric Biggers }, 3604cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_DIGEST, 3614cc2dcf9SEric Biggers }, { 3624cc2dcf9SEric Biggers .name = "init+update+update+final two even splits", 3634cc2dcf9SEric Biggers .src_divs = { 3644cc2dcf9SEric Biggers { .proportion_of_total = 5000 }, 3654cc2dcf9SEric Biggers { 3664cc2dcf9SEric Biggers .proportion_of_total = 5000, 3674cc2dcf9SEric Biggers .flush_type = FLUSH_TYPE_FLUSH, 3684cc2dcf9SEric Biggers }, 3694cc2dcf9SEric Biggers }, 3704cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_FINAL, 3714cc2dcf9SEric Biggers }, { 3724cc2dcf9SEric Biggers .name = "digest uneven misaligned splits, may sleep", 3734cc2dcf9SEric Biggers .req_flags = CRYPTO_TFM_REQ_MAY_SLEEP, 3744cc2dcf9SEric Biggers .src_divs = { 3754cc2dcf9SEric Biggers { .proportion_of_total = 1900, .offset = 33 }, 3764cc2dcf9SEric Biggers { .proportion_of_total = 3300, .offset = 7 }, 3774cc2dcf9SEric Biggers { .proportion_of_total = 4800, .offset = 18 }, 3784cc2dcf9SEric Biggers }, 3794cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_DIGEST, 3804cc2dcf9SEric Biggers }, { 3814cc2dcf9SEric Biggers .name = "digest misaligned splits crossing pages", 3824cc2dcf9SEric Biggers .src_divs = { 3834cc2dcf9SEric Biggers { 3844cc2dcf9SEric Biggers .proportion_of_total = 7500, 3854cc2dcf9SEric Biggers .offset = PAGE_SIZE - 32, 3864cc2dcf9SEric Biggers }, { 3874cc2dcf9SEric Biggers .proportion_of_total = 2500, 3884cc2dcf9SEric Biggers .offset = PAGE_SIZE - 7, 3894cc2dcf9SEric Biggers }, 3904cc2dcf9SEric Biggers }, 3914cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_DIGEST, 3924cc2dcf9SEric Biggers }, { 3934cc2dcf9SEric Biggers .name = "import/export", 3944cc2dcf9SEric Biggers .src_divs = { 3954cc2dcf9SEric Biggers { 3964cc2dcf9SEric Biggers .proportion_of_total = 6500, 3974cc2dcf9SEric Biggers .flush_type = FLUSH_TYPE_REIMPORT, 3984cc2dcf9SEric Biggers }, { 3994cc2dcf9SEric Biggers .proportion_of_total = 3500, 4004cc2dcf9SEric Biggers .flush_type = FLUSH_TYPE_REIMPORT, 4014cc2dcf9SEric Biggers }, 4024cc2dcf9SEric Biggers }, 4034cc2dcf9SEric Biggers .finalization_type = FINALIZATION_TYPE_FINAL, 4044cc2dcf9SEric Biggers } 4054cc2dcf9SEric Biggers }; 4064cc2dcf9SEric Biggers 4073f47a03dSEric Biggers static unsigned int count_test_sg_divisions(const struct test_sg_division *divs) 4083f47a03dSEric Biggers { 4093f47a03dSEric Biggers unsigned int remaining = TEST_SG_TOTAL; 4103f47a03dSEric Biggers unsigned int ndivs = 0; 4113f47a03dSEric Biggers 4123f47a03dSEric Biggers do { 4133f47a03dSEric Biggers remaining -= divs[ndivs++].proportion_of_total; 4143f47a03dSEric Biggers } while (remaining); 4153f47a03dSEric Biggers 4163f47a03dSEric Biggers return ndivs; 4173f47a03dSEric Biggers } 4183f47a03dSEric Biggers 4193f47a03dSEric Biggers static bool valid_sg_divisions(const struct test_sg_division *divs, 4203f47a03dSEric Biggers unsigned int count, bool *any_flushes_ret) 4213f47a03dSEric Biggers { 4223f47a03dSEric Biggers unsigned int total = 0; 4233f47a03dSEric Biggers unsigned int i; 4243f47a03dSEric Biggers 4253f47a03dSEric Biggers for (i = 0; i < count && total != TEST_SG_TOTAL; i++) { 4263f47a03dSEric Biggers if (divs[i].proportion_of_total <= 0 || 4273f47a03dSEric Biggers divs[i].proportion_of_total > TEST_SG_TOTAL - total) 4283f47a03dSEric Biggers return false; 4293f47a03dSEric Biggers total += divs[i].proportion_of_total; 4303f47a03dSEric Biggers if (divs[i].flush_type != FLUSH_TYPE_NONE) 4313f47a03dSEric Biggers *any_flushes_ret = true; 4323f47a03dSEric Biggers } 4333f47a03dSEric Biggers return total == TEST_SG_TOTAL && 4343f47a03dSEric Biggers memchr_inv(&divs[i], 0, (count - i) * sizeof(divs[0])) == NULL; 4353f47a03dSEric Biggers } 4363f47a03dSEric Biggers 4373f47a03dSEric Biggers /* 4383f47a03dSEric Biggers * Check whether the given testvec_config is valid. This isn't strictly needed 4393f47a03dSEric Biggers * since every testvec_config should be valid, but check anyway so that people 4403f47a03dSEric Biggers * don't unknowingly add broken configs that don't do what they wanted. 4413f47a03dSEric Biggers */ 4423f47a03dSEric Biggers static bool valid_testvec_config(const struct testvec_config *cfg) 4433f47a03dSEric Biggers { 4443f47a03dSEric Biggers bool any_flushes = false; 4453f47a03dSEric Biggers 4463f47a03dSEric Biggers if (cfg->name == NULL) 4473f47a03dSEric Biggers return false; 4483f47a03dSEric Biggers 4493f47a03dSEric Biggers if (!valid_sg_divisions(cfg->src_divs, ARRAY_SIZE(cfg->src_divs), 4503f47a03dSEric Biggers &any_flushes)) 4513f47a03dSEric Biggers return false; 4523f47a03dSEric Biggers 4533f47a03dSEric Biggers if (cfg->dst_divs[0].proportion_of_total) { 4543f47a03dSEric Biggers if (!valid_sg_divisions(cfg->dst_divs, 4553f47a03dSEric Biggers ARRAY_SIZE(cfg->dst_divs), 4563f47a03dSEric Biggers &any_flushes)) 4573f47a03dSEric Biggers return false; 4583f47a03dSEric Biggers } else { 4593f47a03dSEric Biggers if (memchr_inv(cfg->dst_divs, 0, sizeof(cfg->dst_divs))) 4603f47a03dSEric Biggers return false; 4613f47a03dSEric Biggers /* defaults to dst_divs=src_divs */ 4623f47a03dSEric Biggers } 4633f47a03dSEric Biggers 4643f47a03dSEric Biggers if (cfg->iv_offset + 4653f47a03dSEric Biggers (cfg->iv_offset_relative_to_alignmask ? MAX_ALGAPI_ALIGNMASK : 0) > 4663f47a03dSEric Biggers MAX_ALGAPI_ALIGNMASK + 1) 4673f47a03dSEric Biggers return false; 4683f47a03dSEric Biggers 4693f47a03dSEric Biggers if (any_flushes && cfg->finalization_type == FINALIZATION_TYPE_DIGEST) 4703f47a03dSEric Biggers return false; 4713f47a03dSEric Biggers 4723f47a03dSEric Biggers return true; 4733f47a03dSEric Biggers } 4743f47a03dSEric Biggers 4753f47a03dSEric Biggers struct test_sglist { 4763f47a03dSEric Biggers char *bufs[XBUFSIZE]; 4773f47a03dSEric Biggers struct scatterlist sgl[XBUFSIZE]; 4783f47a03dSEric Biggers struct scatterlist sgl_saved[XBUFSIZE]; 4793f47a03dSEric Biggers struct scatterlist *sgl_ptr; 4803f47a03dSEric Biggers unsigned int nents; 4813f47a03dSEric Biggers }; 4823f47a03dSEric Biggers 4833f47a03dSEric Biggers static int init_test_sglist(struct test_sglist *tsgl) 4843f47a03dSEric Biggers { 4853f47a03dSEric Biggers return __testmgr_alloc_buf(tsgl->bufs, 1 /* two pages per buffer */); 4863f47a03dSEric Biggers } 4873f47a03dSEric Biggers 4883f47a03dSEric Biggers static void destroy_test_sglist(struct test_sglist *tsgl) 4893f47a03dSEric Biggers { 4903f47a03dSEric Biggers return __testmgr_free_buf(tsgl->bufs, 1 /* two pages per buffer */); 4913f47a03dSEric Biggers } 4923f47a03dSEric Biggers 4933f47a03dSEric Biggers /** 4943f47a03dSEric Biggers * build_test_sglist() - build a scatterlist for a crypto test 4953f47a03dSEric Biggers * 4963f47a03dSEric Biggers * @tsgl: the scatterlist to build. @tsgl->bufs[] contains an array of 2-page 4973f47a03dSEric Biggers * buffers which the scatterlist @tsgl->sgl[] will be made to point into. 4983f47a03dSEric Biggers * @divs: the layout specification on which the scatterlist will be based 4993f47a03dSEric Biggers * @alignmask: the algorithm's alignmask 5003f47a03dSEric Biggers * @total_len: the total length of the scatterlist to build in bytes 5013f47a03dSEric Biggers * @data: if non-NULL, the buffers will be filled with this data until it ends. 5023f47a03dSEric Biggers * Otherwise the buffers will be poisoned. In both cases, some bytes 5033f47a03dSEric Biggers * past the end of each buffer will be poisoned to help detect overruns. 5043f47a03dSEric Biggers * @out_divs: if non-NULL, the test_sg_division to which each scatterlist entry 5053f47a03dSEric Biggers * corresponds will be returned here. This will match @divs except 5063f47a03dSEric Biggers * that divisions resolving to a length of 0 are omitted as they are 5073f47a03dSEric Biggers * not included in the scatterlist. 5083f47a03dSEric Biggers * 5093f47a03dSEric Biggers * Return: 0 or a -errno value 5103f47a03dSEric Biggers */ 5113f47a03dSEric Biggers static int build_test_sglist(struct test_sglist *tsgl, 5123f47a03dSEric Biggers const struct test_sg_division *divs, 5133f47a03dSEric Biggers const unsigned int alignmask, 5143f47a03dSEric Biggers const unsigned int total_len, 5153f47a03dSEric Biggers struct iov_iter *data, 5163f47a03dSEric Biggers const struct test_sg_division *out_divs[XBUFSIZE]) 5173f47a03dSEric Biggers { 5183f47a03dSEric Biggers struct { 5193f47a03dSEric Biggers const struct test_sg_division *div; 5203f47a03dSEric Biggers size_t length; 5213f47a03dSEric Biggers } partitions[XBUFSIZE]; 5223f47a03dSEric Biggers const unsigned int ndivs = count_test_sg_divisions(divs); 5233f47a03dSEric Biggers unsigned int len_remaining = total_len; 5243f47a03dSEric Biggers unsigned int i; 5253f47a03dSEric Biggers 5263f47a03dSEric Biggers BUILD_BUG_ON(ARRAY_SIZE(partitions) != ARRAY_SIZE(tsgl->sgl)); 5273f47a03dSEric Biggers if (WARN_ON(ndivs > ARRAY_SIZE(partitions))) 5283f47a03dSEric Biggers return -EINVAL; 5293f47a03dSEric Biggers 5303f47a03dSEric Biggers /* Calculate the (div, length) pairs */ 5313f47a03dSEric Biggers tsgl->nents = 0; 5323f47a03dSEric Biggers for (i = 0; i < ndivs; i++) { 5333f47a03dSEric Biggers unsigned int len_this_sg = 5343f47a03dSEric Biggers min(len_remaining, 5353f47a03dSEric Biggers (total_len * divs[i].proportion_of_total + 5363f47a03dSEric Biggers TEST_SG_TOTAL / 2) / TEST_SG_TOTAL); 5373f47a03dSEric Biggers 5383f47a03dSEric Biggers if (len_this_sg != 0) { 5393f47a03dSEric Biggers partitions[tsgl->nents].div = &divs[i]; 5403f47a03dSEric Biggers partitions[tsgl->nents].length = len_this_sg; 5413f47a03dSEric Biggers tsgl->nents++; 5423f47a03dSEric Biggers len_remaining -= len_this_sg; 5433f47a03dSEric Biggers } 5443f47a03dSEric Biggers } 5453f47a03dSEric Biggers if (tsgl->nents == 0) { 5463f47a03dSEric Biggers partitions[tsgl->nents].div = &divs[0]; 5473f47a03dSEric Biggers partitions[tsgl->nents].length = 0; 5483f47a03dSEric Biggers tsgl->nents++; 5493f47a03dSEric Biggers } 5503f47a03dSEric Biggers partitions[tsgl->nents - 1].length += len_remaining; 5513f47a03dSEric Biggers 5523f47a03dSEric Biggers /* Set up the sgl entries and fill the data or poison */ 5533f47a03dSEric Biggers sg_init_table(tsgl->sgl, tsgl->nents); 5543f47a03dSEric Biggers for (i = 0; i < tsgl->nents; i++) { 5553f47a03dSEric Biggers unsigned int offset = partitions[i].div->offset; 5563f47a03dSEric Biggers void *addr; 5573f47a03dSEric Biggers 5583f47a03dSEric Biggers if (partitions[i].div->offset_relative_to_alignmask) 5593f47a03dSEric Biggers offset += alignmask; 5603f47a03dSEric Biggers 5613f47a03dSEric Biggers while (offset + partitions[i].length + TESTMGR_POISON_LEN > 5623f47a03dSEric Biggers 2 * PAGE_SIZE) { 5633f47a03dSEric Biggers if (WARN_ON(offset <= 0)) 5643f47a03dSEric Biggers return -EINVAL; 5653f47a03dSEric Biggers offset /= 2; 5663f47a03dSEric Biggers } 5673f47a03dSEric Biggers 5683f47a03dSEric Biggers addr = &tsgl->bufs[i][offset]; 5693f47a03dSEric Biggers sg_set_buf(&tsgl->sgl[i], addr, partitions[i].length); 5703f47a03dSEric Biggers 5713f47a03dSEric Biggers if (out_divs) 5723f47a03dSEric Biggers out_divs[i] = partitions[i].div; 5733f47a03dSEric Biggers 5743f47a03dSEric Biggers if (data) { 5753f47a03dSEric Biggers size_t copy_len, copied; 5763f47a03dSEric Biggers 5773f47a03dSEric Biggers copy_len = min(partitions[i].length, data->count); 5783f47a03dSEric Biggers copied = copy_from_iter(addr, copy_len, data); 5793f47a03dSEric Biggers if (WARN_ON(copied != copy_len)) 5803f47a03dSEric Biggers return -EINVAL; 5813f47a03dSEric Biggers testmgr_poison(addr + copy_len, partitions[i].length + 5823f47a03dSEric Biggers TESTMGR_POISON_LEN - copy_len); 5833f47a03dSEric Biggers } else { 5843f47a03dSEric Biggers testmgr_poison(addr, partitions[i].length + 5853f47a03dSEric Biggers TESTMGR_POISON_LEN); 5863f47a03dSEric Biggers } 5873f47a03dSEric Biggers } 5883f47a03dSEric Biggers 5893f47a03dSEric Biggers sg_mark_end(&tsgl->sgl[tsgl->nents - 1]); 5903f47a03dSEric Biggers tsgl->sgl_ptr = tsgl->sgl; 5913f47a03dSEric Biggers memcpy(tsgl->sgl_saved, tsgl->sgl, tsgl->nents * sizeof(tsgl->sgl[0])); 5923f47a03dSEric Biggers return 0; 5933f47a03dSEric Biggers } 5943f47a03dSEric Biggers 5953f47a03dSEric Biggers /* 5963f47a03dSEric Biggers * Verify that a scatterlist crypto operation produced the correct output. 5973f47a03dSEric Biggers * 5983f47a03dSEric Biggers * @tsgl: scatterlist containing the actual output 5993f47a03dSEric Biggers * @expected_output: buffer containing the expected output 6003f47a03dSEric Biggers * @len_to_check: length of @expected_output in bytes 6013f47a03dSEric Biggers * @unchecked_prefix_len: number of ignored bytes in @tsgl prior to real result 6023f47a03dSEric Biggers * @check_poison: verify that the poison bytes after each chunk are intact? 6033f47a03dSEric Biggers * 6043f47a03dSEric Biggers * Return: 0 if correct, -EINVAL if incorrect, -EOVERFLOW if buffer overrun. 6053f47a03dSEric Biggers */ 6063f47a03dSEric Biggers static int verify_correct_output(const struct test_sglist *tsgl, 6073f47a03dSEric Biggers const char *expected_output, 6083f47a03dSEric Biggers unsigned int len_to_check, 6093f47a03dSEric Biggers unsigned int unchecked_prefix_len, 6103f47a03dSEric Biggers bool check_poison) 6113f47a03dSEric Biggers { 6123f47a03dSEric Biggers unsigned int i; 6133f47a03dSEric Biggers 6143f47a03dSEric Biggers for (i = 0; i < tsgl->nents; i++) { 6153f47a03dSEric Biggers struct scatterlist *sg = &tsgl->sgl_ptr[i]; 6163f47a03dSEric Biggers unsigned int len = sg->length; 6173f47a03dSEric Biggers unsigned int offset = sg->offset; 6183f47a03dSEric Biggers const char *actual_output; 6193f47a03dSEric Biggers 6203f47a03dSEric Biggers if (unchecked_prefix_len) { 6213f47a03dSEric Biggers if (unchecked_prefix_len >= len) { 6223f47a03dSEric Biggers unchecked_prefix_len -= len; 6233f47a03dSEric Biggers continue; 6243f47a03dSEric Biggers } 6253f47a03dSEric Biggers offset += unchecked_prefix_len; 6263f47a03dSEric Biggers len -= unchecked_prefix_len; 6273f47a03dSEric Biggers unchecked_prefix_len = 0; 6283f47a03dSEric Biggers } 6293f47a03dSEric Biggers len = min(len, len_to_check); 6303f47a03dSEric Biggers actual_output = page_address(sg_page(sg)) + offset; 6313f47a03dSEric Biggers if (memcmp(expected_output, actual_output, len) != 0) 6323f47a03dSEric Biggers return -EINVAL; 6333f47a03dSEric Biggers if (check_poison && 6343f47a03dSEric Biggers !testmgr_is_poison(actual_output + len, TESTMGR_POISON_LEN)) 6353f47a03dSEric Biggers return -EOVERFLOW; 6363f47a03dSEric Biggers len_to_check -= len; 6373f47a03dSEric Biggers expected_output += len; 6383f47a03dSEric Biggers } 6393f47a03dSEric Biggers if (WARN_ON(len_to_check != 0)) 6403f47a03dSEric Biggers return -EINVAL; 6413f47a03dSEric Biggers return 0; 6423f47a03dSEric Biggers } 6433f47a03dSEric Biggers 6443f47a03dSEric Biggers static bool is_test_sglist_corrupted(const struct test_sglist *tsgl) 6453f47a03dSEric Biggers { 6463f47a03dSEric Biggers unsigned int i; 6473f47a03dSEric Biggers 6483f47a03dSEric Biggers for (i = 0; i < tsgl->nents; i++) { 6493f47a03dSEric Biggers if (tsgl->sgl[i].page_link != tsgl->sgl_saved[i].page_link) 6503f47a03dSEric Biggers return true; 6513f47a03dSEric Biggers if (tsgl->sgl[i].offset != tsgl->sgl_saved[i].offset) 6523f47a03dSEric Biggers return true; 6533f47a03dSEric Biggers if (tsgl->sgl[i].length != tsgl->sgl_saved[i].length) 6543f47a03dSEric Biggers return true; 6553f47a03dSEric Biggers } 6563f47a03dSEric Biggers return false; 6573f47a03dSEric Biggers } 6583f47a03dSEric Biggers 6593f47a03dSEric Biggers struct cipher_test_sglists { 6603f47a03dSEric Biggers struct test_sglist src; 6613f47a03dSEric Biggers struct test_sglist dst; 6623f47a03dSEric Biggers }; 6633f47a03dSEric Biggers 6643f47a03dSEric Biggers static struct cipher_test_sglists *alloc_cipher_test_sglists(void) 6653f47a03dSEric Biggers { 6663f47a03dSEric Biggers struct cipher_test_sglists *tsgls; 6673f47a03dSEric Biggers 6683f47a03dSEric Biggers tsgls = kmalloc(sizeof(*tsgls), GFP_KERNEL); 6693f47a03dSEric Biggers if (!tsgls) 6703f47a03dSEric Biggers return NULL; 6713f47a03dSEric Biggers 6723f47a03dSEric Biggers if (init_test_sglist(&tsgls->src) != 0) 6733f47a03dSEric Biggers goto fail_kfree; 6743f47a03dSEric Biggers if (init_test_sglist(&tsgls->dst) != 0) 6753f47a03dSEric Biggers goto fail_destroy_src; 6763f47a03dSEric Biggers 6773f47a03dSEric Biggers return tsgls; 6783f47a03dSEric Biggers 6793f47a03dSEric Biggers fail_destroy_src: 6803f47a03dSEric Biggers destroy_test_sglist(&tsgls->src); 6813f47a03dSEric Biggers fail_kfree: 6823f47a03dSEric Biggers kfree(tsgls); 6833f47a03dSEric Biggers return NULL; 6843f47a03dSEric Biggers } 6853f47a03dSEric Biggers 6863f47a03dSEric Biggers static void free_cipher_test_sglists(struct cipher_test_sglists *tsgls) 6873f47a03dSEric Biggers { 6883f47a03dSEric Biggers if (tsgls) { 6893f47a03dSEric Biggers destroy_test_sglist(&tsgls->src); 6903f47a03dSEric Biggers destroy_test_sglist(&tsgls->dst); 6913f47a03dSEric Biggers kfree(tsgls); 6923f47a03dSEric Biggers } 6933f47a03dSEric Biggers } 6943f47a03dSEric Biggers 6953f47a03dSEric Biggers /* Build the src and dst scatterlists for an skcipher or AEAD test */ 6963f47a03dSEric Biggers static int build_cipher_test_sglists(struct cipher_test_sglists *tsgls, 6973f47a03dSEric Biggers const struct testvec_config *cfg, 6983f47a03dSEric Biggers unsigned int alignmask, 6993f47a03dSEric Biggers unsigned int src_total_len, 7003f47a03dSEric Biggers unsigned int dst_total_len, 7013f47a03dSEric Biggers const struct kvec *inputs, 7023f47a03dSEric Biggers unsigned int nr_inputs) 7033f47a03dSEric Biggers { 7043f47a03dSEric Biggers struct iov_iter input; 7053f47a03dSEric Biggers int err; 7063f47a03dSEric Biggers 7073f47a03dSEric Biggers iov_iter_kvec(&input, WRITE, inputs, nr_inputs, src_total_len); 7083f47a03dSEric Biggers err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask, 7093f47a03dSEric Biggers cfg->inplace ? 7103f47a03dSEric Biggers max(dst_total_len, src_total_len) : 7113f47a03dSEric Biggers src_total_len, 7123f47a03dSEric Biggers &input, NULL); 7133f47a03dSEric Biggers if (err) 7143f47a03dSEric Biggers return err; 7153f47a03dSEric Biggers 7163f47a03dSEric Biggers if (cfg->inplace) { 7173f47a03dSEric Biggers tsgls->dst.sgl_ptr = tsgls->src.sgl; 7183f47a03dSEric Biggers tsgls->dst.nents = tsgls->src.nents; 7193f47a03dSEric Biggers return 0; 7203f47a03dSEric Biggers } 7213f47a03dSEric Biggers return build_test_sglist(&tsgls->dst, 7223f47a03dSEric Biggers cfg->dst_divs[0].proportion_of_total ? 7233f47a03dSEric Biggers cfg->dst_divs : cfg->src_divs, 7243f47a03dSEric Biggers alignmask, dst_total_len, NULL, NULL); 725f8b0d4d0SHerbert Xu } 726f8b0d4d0SHerbert Xu 72725f9dddbSEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 72825f9dddbSEric Biggers static char *generate_random_sgl_divisions(struct test_sg_division *divs, 72925f9dddbSEric Biggers size_t max_divs, char *p, char *end, 73025f9dddbSEric Biggers bool gen_flushes) 73125f9dddbSEric Biggers { 73225f9dddbSEric Biggers struct test_sg_division *div = divs; 73325f9dddbSEric Biggers unsigned int remaining = TEST_SG_TOTAL; 73425f9dddbSEric Biggers 73525f9dddbSEric Biggers do { 73625f9dddbSEric Biggers unsigned int this_len; 73725f9dddbSEric Biggers 73825f9dddbSEric Biggers if (div == &divs[max_divs - 1] || prandom_u32() % 2 == 0) 73925f9dddbSEric Biggers this_len = remaining; 74025f9dddbSEric Biggers else 74125f9dddbSEric Biggers this_len = 1 + (prandom_u32() % remaining); 74225f9dddbSEric Biggers div->proportion_of_total = this_len; 74325f9dddbSEric Biggers 74425f9dddbSEric Biggers if (prandom_u32() % 4 == 0) 74525f9dddbSEric Biggers div->offset = (PAGE_SIZE - 128) + (prandom_u32() % 128); 74625f9dddbSEric Biggers else if (prandom_u32() % 2 == 0) 74725f9dddbSEric Biggers div->offset = prandom_u32() % 32; 74825f9dddbSEric Biggers else 74925f9dddbSEric Biggers div->offset = prandom_u32() % PAGE_SIZE; 75025f9dddbSEric Biggers if (prandom_u32() % 8 == 0) 75125f9dddbSEric Biggers div->offset_relative_to_alignmask = true; 75225f9dddbSEric Biggers 75325f9dddbSEric Biggers div->flush_type = FLUSH_TYPE_NONE; 75425f9dddbSEric Biggers if (gen_flushes) { 75525f9dddbSEric Biggers switch (prandom_u32() % 4) { 75625f9dddbSEric Biggers case 0: 75725f9dddbSEric Biggers div->flush_type = FLUSH_TYPE_REIMPORT; 75825f9dddbSEric Biggers break; 75925f9dddbSEric Biggers case 1: 76025f9dddbSEric Biggers div->flush_type = FLUSH_TYPE_FLUSH; 76125f9dddbSEric Biggers break; 76225f9dddbSEric Biggers } 76325f9dddbSEric Biggers } 76425f9dddbSEric Biggers 76525f9dddbSEric Biggers BUILD_BUG_ON(TEST_SG_TOTAL != 10000); /* for "%u.%u%%" */ 76625f9dddbSEric Biggers p += scnprintf(p, end - p, "%s%u.%u%%@%s+%u%s", 76725f9dddbSEric Biggers div->flush_type == FLUSH_TYPE_NONE ? "" : 76825f9dddbSEric Biggers div->flush_type == FLUSH_TYPE_FLUSH ? 76925f9dddbSEric Biggers "<flush> " : "<reimport> ", 77025f9dddbSEric Biggers this_len / 100, this_len % 100, 77125f9dddbSEric Biggers div->offset_relative_to_alignmask ? 77225f9dddbSEric Biggers "alignmask" : "", 77325f9dddbSEric Biggers div->offset, this_len == remaining ? "" : ", "); 77425f9dddbSEric Biggers remaining -= this_len; 77525f9dddbSEric Biggers div++; 77625f9dddbSEric Biggers } while (remaining); 77725f9dddbSEric Biggers 77825f9dddbSEric Biggers return p; 77925f9dddbSEric Biggers } 78025f9dddbSEric Biggers 78125f9dddbSEric Biggers /* Generate a random testvec_config for fuzz testing */ 78225f9dddbSEric Biggers static void generate_random_testvec_config(struct testvec_config *cfg, 78325f9dddbSEric Biggers char *name, size_t max_namelen) 78425f9dddbSEric Biggers { 78525f9dddbSEric Biggers char *p = name; 78625f9dddbSEric Biggers char * const end = name + max_namelen; 78725f9dddbSEric Biggers 78825f9dddbSEric Biggers memset(cfg, 0, sizeof(*cfg)); 78925f9dddbSEric Biggers 79025f9dddbSEric Biggers cfg->name = name; 79125f9dddbSEric Biggers 79225f9dddbSEric Biggers p += scnprintf(p, end - p, "random:"); 79325f9dddbSEric Biggers 79425f9dddbSEric Biggers if (prandom_u32() % 2 == 0) { 79525f9dddbSEric Biggers cfg->inplace = true; 79625f9dddbSEric Biggers p += scnprintf(p, end - p, " inplace"); 79725f9dddbSEric Biggers } 79825f9dddbSEric Biggers 79925f9dddbSEric Biggers if (prandom_u32() % 2 == 0) { 80025f9dddbSEric Biggers cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP; 80125f9dddbSEric Biggers p += scnprintf(p, end - p, " may_sleep"); 80225f9dddbSEric Biggers } 80325f9dddbSEric Biggers 80425f9dddbSEric Biggers switch (prandom_u32() % 4) { 80525f9dddbSEric Biggers case 0: 80625f9dddbSEric Biggers cfg->finalization_type = FINALIZATION_TYPE_FINAL; 80725f9dddbSEric Biggers p += scnprintf(p, end - p, " use_final"); 80825f9dddbSEric Biggers break; 80925f9dddbSEric Biggers case 1: 81025f9dddbSEric Biggers cfg->finalization_type = FINALIZATION_TYPE_FINUP; 81125f9dddbSEric Biggers p += scnprintf(p, end - p, " use_finup"); 81225f9dddbSEric Biggers break; 81325f9dddbSEric Biggers default: 81425f9dddbSEric Biggers cfg->finalization_type = FINALIZATION_TYPE_DIGEST; 81525f9dddbSEric Biggers p += scnprintf(p, end - p, " use_digest"); 81625f9dddbSEric Biggers break; 81725f9dddbSEric Biggers } 81825f9dddbSEric Biggers 81925f9dddbSEric Biggers p += scnprintf(p, end - p, " src_divs=["); 82025f9dddbSEric Biggers p = generate_random_sgl_divisions(cfg->src_divs, 82125f9dddbSEric Biggers ARRAY_SIZE(cfg->src_divs), p, end, 82225f9dddbSEric Biggers (cfg->finalization_type != 82325f9dddbSEric Biggers FINALIZATION_TYPE_DIGEST)); 82425f9dddbSEric Biggers p += scnprintf(p, end - p, "]"); 82525f9dddbSEric Biggers 82625f9dddbSEric Biggers if (!cfg->inplace && prandom_u32() % 2 == 0) { 82725f9dddbSEric Biggers p += scnprintf(p, end - p, " dst_divs=["); 82825f9dddbSEric Biggers p = generate_random_sgl_divisions(cfg->dst_divs, 82925f9dddbSEric Biggers ARRAY_SIZE(cfg->dst_divs), 83025f9dddbSEric Biggers p, end, false); 83125f9dddbSEric Biggers p += scnprintf(p, end - p, "]"); 83225f9dddbSEric Biggers } 83325f9dddbSEric Biggers 83425f9dddbSEric Biggers if (prandom_u32() % 2 == 0) { 83525f9dddbSEric Biggers cfg->iv_offset = 1 + (prandom_u32() % MAX_ALGAPI_ALIGNMASK); 83625f9dddbSEric Biggers p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset); 83725f9dddbSEric Biggers } 83825f9dddbSEric Biggers 83925f9dddbSEric Biggers WARN_ON_ONCE(!valid_testvec_config(cfg)); 84025f9dddbSEric Biggers } 84125f9dddbSEric Biggers #endif /* CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ 84225f9dddbSEric Biggers 8434cc2dcf9SEric Biggers static int check_nonfinal_hash_op(const char *op, int err, 8444cc2dcf9SEric Biggers u8 *result, unsigned int digestsize, 8454cc2dcf9SEric Biggers const char *driver, unsigned int vec_num, 8464cc2dcf9SEric Biggers const struct testvec_config *cfg) 847466d7b9fSKamil Konieczny { 8484cc2dcf9SEric Biggers if (err) { 8494cc2dcf9SEric Biggers pr_err("alg: hash: %s %s() failed with err %d on test vector %u, cfg=\"%s\"\n", 8504cc2dcf9SEric Biggers driver, op, err, vec_num, cfg->name); 8514cc2dcf9SEric Biggers return err; 8524cc2dcf9SEric Biggers } 8534cc2dcf9SEric Biggers if (!testmgr_is_poison(result, digestsize)) { 8544cc2dcf9SEric Biggers pr_err("alg: hash: %s %s() used result buffer on test vector %u, cfg=\"%s\"\n", 8554cc2dcf9SEric Biggers driver, op, vec_num, cfg->name); 856466d7b9fSKamil Konieczny return -EINVAL; 857466d7b9fSKamil Konieczny } 858466d7b9fSKamil Konieczny return 0; 859466d7b9fSKamil Konieczny } 860466d7b9fSKamil Konieczny 8614cc2dcf9SEric Biggers static int test_hash_vec_cfg(const char *driver, 8624cc2dcf9SEric Biggers const struct hash_testvec *vec, 8634cc2dcf9SEric Biggers unsigned int vec_num, 8644cc2dcf9SEric Biggers const struct testvec_config *cfg, 8654cc2dcf9SEric Biggers struct ahash_request *req, 8664cc2dcf9SEric Biggers struct test_sglist *tsgl, 8674cc2dcf9SEric Biggers u8 *hashstate) 868018ba95cSWang, Rui Y { 8694cc2dcf9SEric Biggers struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 8704cc2dcf9SEric Biggers const unsigned int alignmask = crypto_ahash_alignmask(tfm); 8714cc2dcf9SEric Biggers const unsigned int digestsize = crypto_ahash_digestsize(tfm); 8724cc2dcf9SEric Biggers const unsigned int statesize = crypto_ahash_statesize(tfm); 8734cc2dcf9SEric Biggers const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 8744cc2dcf9SEric Biggers const struct test_sg_division *divs[XBUFSIZE]; 8754cc2dcf9SEric Biggers DECLARE_CRYPTO_WAIT(wait); 8764cc2dcf9SEric Biggers struct kvec _input; 8774cc2dcf9SEric Biggers struct iov_iter input; 8784cc2dcf9SEric Biggers unsigned int i; 8794cc2dcf9SEric Biggers struct scatterlist *pending_sgl; 8804cc2dcf9SEric Biggers unsigned int pending_len; 8814cc2dcf9SEric Biggers u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN]; 8824cc2dcf9SEric Biggers int err; 883018ba95cSWang, Rui Y 8844cc2dcf9SEric Biggers /* Set the key, if specified */ 8854cc2dcf9SEric Biggers if (vec->ksize) { 8864cc2dcf9SEric Biggers err = crypto_ahash_setkey(tfm, vec->key, vec->ksize); 8874cc2dcf9SEric Biggers if (err) { 8884cc2dcf9SEric Biggers pr_err("alg: hash: %s setkey failed with err %d on test vector %u; flags=%#x\n", 8894cc2dcf9SEric Biggers driver, err, vec_num, 8904cc2dcf9SEric Biggers crypto_ahash_get_flags(tfm)); 8914cc2dcf9SEric Biggers return err; 892da7f033dSHerbert Xu } 893da7f033dSHerbert Xu } 894da7f033dSHerbert Xu 8954cc2dcf9SEric Biggers /* Build the scatterlist for the source data */ 8964cc2dcf9SEric Biggers _input.iov_base = (void *)vec->plaintext; 8974cc2dcf9SEric Biggers _input.iov_len = vec->psize; 8984cc2dcf9SEric Biggers iov_iter_kvec(&input, WRITE, &_input, 1, vec->psize); 8994cc2dcf9SEric Biggers err = build_test_sglist(tsgl, cfg->src_divs, alignmask, vec->psize, 9004cc2dcf9SEric Biggers &input, divs); 9014cc2dcf9SEric Biggers if (err) { 9024cc2dcf9SEric Biggers pr_err("alg: hash: %s: error preparing scatterlist for test vector %u, cfg=\"%s\"\n", 9034cc2dcf9SEric Biggers driver, vec_num, cfg->name); 9044cc2dcf9SEric Biggers return err; 905a8f1a052SDavid S. Miller } 906da7f033dSHerbert Xu 9074cc2dcf9SEric Biggers /* Do the actual hashing */ 908da7f033dSHerbert Xu 9094cc2dcf9SEric Biggers testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm)); 9104cc2dcf9SEric Biggers testmgr_poison(result, digestsize + TESTMGR_POISON_LEN); 91176715095SGilad Ben-Yossef 9124cc2dcf9SEric Biggers if (cfg->finalization_type == FINALIZATION_TYPE_DIGEST) { 9134cc2dcf9SEric Biggers /* Just using digest() */ 9144cc2dcf9SEric Biggers ahash_request_set_callback(req, req_flags, crypto_req_done, 9157f397136SGilad Ben-Yossef &wait); 9164cc2dcf9SEric Biggers ahash_request_set_crypt(req, tsgl->sgl, result, vec->psize); 9174cc2dcf9SEric Biggers err = crypto_wait_req(crypto_ahash_digest(req), &wait); 9184cc2dcf9SEric Biggers if (err) { 9194cc2dcf9SEric Biggers pr_err("alg: hash: %s digest() failed with err %d on test vector %u, cfg=\"%s\"\n", 9204cc2dcf9SEric Biggers driver, err, vec_num, cfg->name); 9214cc2dcf9SEric Biggers return err; 922018ba95cSWang, Rui Y } 9234cc2dcf9SEric Biggers goto result_ready; 924018ba95cSWang, Rui Y } 9254cc2dcf9SEric Biggers 9264cc2dcf9SEric Biggers /* Using init(), zero or more update(), then final() or finup() */ 9274cc2dcf9SEric Biggers 9284cc2dcf9SEric Biggers ahash_request_set_callback(req, req_flags, crypto_req_done, &wait); 9294cc2dcf9SEric Biggers ahash_request_set_crypt(req, NULL, result, 0); 9304cc2dcf9SEric Biggers err = crypto_wait_req(crypto_ahash_init(req), &wait); 9314cc2dcf9SEric Biggers err = check_nonfinal_hash_op("init", err, result, digestsize, 9324cc2dcf9SEric Biggers driver, vec_num, cfg); 9334cc2dcf9SEric Biggers if (err) 9344cc2dcf9SEric Biggers return err; 9354cc2dcf9SEric Biggers 9364cc2dcf9SEric Biggers pending_sgl = NULL; 9374cc2dcf9SEric Biggers pending_len = 0; 9384cc2dcf9SEric Biggers for (i = 0; i < tsgl->nents; i++) { 9394cc2dcf9SEric Biggers if (divs[i]->flush_type != FLUSH_TYPE_NONE && 9404cc2dcf9SEric Biggers pending_sgl != NULL) { 9414cc2dcf9SEric Biggers /* update() with the pending data */ 9424cc2dcf9SEric Biggers ahash_request_set_callback(req, req_flags, 9434cc2dcf9SEric Biggers crypto_req_done, &wait); 9444cc2dcf9SEric Biggers ahash_request_set_crypt(req, pending_sgl, result, 9454cc2dcf9SEric Biggers pending_len); 9464cc2dcf9SEric Biggers err = crypto_wait_req(crypto_ahash_update(req), &wait); 9474cc2dcf9SEric Biggers err = check_nonfinal_hash_op("update", err, 9484cc2dcf9SEric Biggers result, digestsize, 9494cc2dcf9SEric Biggers driver, vec_num, cfg); 9504cc2dcf9SEric Biggers if (err) 9514cc2dcf9SEric Biggers return err; 9524cc2dcf9SEric Biggers pending_sgl = NULL; 9534cc2dcf9SEric Biggers pending_len = 0; 954018ba95cSWang, Rui Y } 9554cc2dcf9SEric Biggers if (divs[i]->flush_type == FLUSH_TYPE_REIMPORT) { 9564cc2dcf9SEric Biggers /* Test ->export() and ->import() */ 9574cc2dcf9SEric Biggers testmgr_poison(hashstate + statesize, 9584cc2dcf9SEric Biggers TESTMGR_POISON_LEN); 9594cc2dcf9SEric Biggers err = crypto_ahash_export(req, hashstate); 9604cc2dcf9SEric Biggers err = check_nonfinal_hash_op("export", err, 9614cc2dcf9SEric Biggers result, digestsize, 9624cc2dcf9SEric Biggers driver, vec_num, cfg); 9634cc2dcf9SEric Biggers if (err) 9644cc2dcf9SEric Biggers return err; 9654cc2dcf9SEric Biggers if (!testmgr_is_poison(hashstate + statesize, 9664cc2dcf9SEric Biggers TESTMGR_POISON_LEN)) { 9674cc2dcf9SEric Biggers pr_err("alg: hash: %s export() overran state buffer on test vector %u, cfg=\"%s\"\n", 9684cc2dcf9SEric Biggers driver, vec_num, cfg->name); 9694cc2dcf9SEric Biggers return -EOVERFLOW; 9704cc2dcf9SEric Biggers } 9714cc2dcf9SEric Biggers 9724cc2dcf9SEric Biggers testmgr_poison(req->__ctx, crypto_ahash_reqsize(tfm)); 9734cc2dcf9SEric Biggers err = crypto_ahash_import(req, hashstate); 9744cc2dcf9SEric Biggers err = check_nonfinal_hash_op("import", err, 9754cc2dcf9SEric Biggers result, digestsize, 9764cc2dcf9SEric Biggers driver, vec_num, cfg); 9774cc2dcf9SEric Biggers if (err) 9784cc2dcf9SEric Biggers return err; 9794cc2dcf9SEric Biggers } 9804cc2dcf9SEric Biggers if (pending_sgl == NULL) 9814cc2dcf9SEric Biggers pending_sgl = &tsgl->sgl[i]; 9824cc2dcf9SEric Biggers pending_len += tsgl->sgl[i].length; 9834cc2dcf9SEric Biggers } 9844cc2dcf9SEric Biggers 9854cc2dcf9SEric Biggers ahash_request_set_callback(req, req_flags, crypto_req_done, &wait); 9864cc2dcf9SEric Biggers ahash_request_set_crypt(req, pending_sgl, result, pending_len); 9874cc2dcf9SEric Biggers if (cfg->finalization_type == FINALIZATION_TYPE_FINAL) { 9884cc2dcf9SEric Biggers /* finish with update() and final() */ 9894cc2dcf9SEric Biggers err = crypto_wait_req(crypto_ahash_update(req), &wait); 9904cc2dcf9SEric Biggers err = check_nonfinal_hash_op("update", err, result, digestsize, 9914cc2dcf9SEric Biggers driver, vec_num, cfg); 9924cc2dcf9SEric Biggers if (err) 9934cc2dcf9SEric Biggers return err; 9944cc2dcf9SEric Biggers err = crypto_wait_req(crypto_ahash_final(req), &wait); 9954cc2dcf9SEric Biggers if (err) { 9964cc2dcf9SEric Biggers pr_err("alg: hash: %s final() failed with err %d on test vector %u, cfg=\"%s\"\n", 9974cc2dcf9SEric Biggers driver, err, vec_num, cfg->name); 9984cc2dcf9SEric Biggers return err; 9994cc2dcf9SEric Biggers } 10004cc2dcf9SEric Biggers } else { 10014cc2dcf9SEric Biggers /* finish with finup() */ 10024cc2dcf9SEric Biggers err = crypto_wait_req(crypto_ahash_finup(req), &wait); 10034cc2dcf9SEric Biggers if (err) { 10044cc2dcf9SEric Biggers pr_err("alg: hash: %s finup() failed with err %d on test vector %u, cfg=\"%s\"\n", 10054cc2dcf9SEric Biggers driver, err, vec_num, cfg->name); 10064cc2dcf9SEric Biggers return err; 1007018ba95cSWang, Rui Y } 1008018ba95cSWang, Rui Y } 1009018ba95cSWang, Rui Y 10104cc2dcf9SEric Biggers result_ready: 10114cc2dcf9SEric Biggers /* Check that the algorithm produced the correct digest */ 10124cc2dcf9SEric Biggers if (memcmp(result, vec->digest, digestsize) != 0) { 10134cc2dcf9SEric Biggers pr_err("alg: hash: %s test failed (wrong result) on test vector %u, cfg=\"%s\"\n", 10144cc2dcf9SEric Biggers driver, vec_num, cfg->name); 10154cc2dcf9SEric Biggers return -EINVAL; 1016da7f033dSHerbert Xu } 10174cc2dcf9SEric Biggers if (!testmgr_is_poison(&result[digestsize], TESTMGR_POISON_LEN)) { 10184cc2dcf9SEric Biggers pr_err("alg: hash: %s overran result buffer on test vector %u, cfg=\"%s\"\n", 10194cc2dcf9SEric Biggers driver, vec_num, cfg->name); 10204cc2dcf9SEric Biggers return -EOVERFLOW; 1021da5ffe11SJussi Kivilinna } 1022da5ffe11SJussi Kivilinna 1023da5ffe11SJussi Kivilinna return 0; 1024da5ffe11SJussi Kivilinna } 1025da5ffe11SJussi Kivilinna 10264cc2dcf9SEric Biggers static int test_hash_vec(const char *driver, const struct hash_testvec *vec, 10274cc2dcf9SEric Biggers unsigned int vec_num, struct ahash_request *req, 10284cc2dcf9SEric Biggers struct test_sglist *tsgl, u8 *hashstate) 10294cc2dcf9SEric Biggers { 10304cc2dcf9SEric Biggers unsigned int i; 10314cc2dcf9SEric Biggers int err; 10324cc2dcf9SEric Biggers 10334cc2dcf9SEric Biggers for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) { 10344cc2dcf9SEric Biggers err = test_hash_vec_cfg(driver, vec, vec_num, 10354cc2dcf9SEric Biggers &default_hash_testvec_configs[i], 10364cc2dcf9SEric Biggers req, tsgl, hashstate); 10374cc2dcf9SEric Biggers if (err) 10384cc2dcf9SEric Biggers return err; 10394cc2dcf9SEric Biggers } 10404cc2dcf9SEric Biggers 10414cc2dcf9SEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 10424cc2dcf9SEric Biggers if (!noextratests) { 10434cc2dcf9SEric Biggers struct testvec_config cfg; 10444cc2dcf9SEric Biggers char cfgname[TESTVEC_CONFIG_NAMELEN]; 10454cc2dcf9SEric Biggers 10464cc2dcf9SEric Biggers for (i = 0; i < fuzz_iterations; i++) { 10474cc2dcf9SEric Biggers generate_random_testvec_config(&cfg, cfgname, 10484cc2dcf9SEric Biggers sizeof(cfgname)); 10494cc2dcf9SEric Biggers err = test_hash_vec_cfg(driver, vec, vec_num, &cfg, 10504cc2dcf9SEric Biggers req, tsgl, hashstate); 10514cc2dcf9SEric Biggers if (err) 10524cc2dcf9SEric Biggers return err; 10534cc2dcf9SEric Biggers } 10544cc2dcf9SEric Biggers } 10554cc2dcf9SEric Biggers #endif 10564cc2dcf9SEric Biggers return 0; 10574cc2dcf9SEric Biggers } 10584cc2dcf9SEric Biggers 10594cc2dcf9SEric Biggers static int __alg_test_hash(const struct hash_testvec *vecs, 10604cc2dcf9SEric Biggers unsigned int num_vecs, const char *driver, 10614cc2dcf9SEric Biggers u32 type, u32 mask) 10624cc2dcf9SEric Biggers { 10634cc2dcf9SEric Biggers struct crypto_ahash *tfm; 10644cc2dcf9SEric Biggers struct ahash_request *req = NULL; 10654cc2dcf9SEric Biggers struct test_sglist *tsgl = NULL; 10664cc2dcf9SEric Biggers u8 *hashstate = NULL; 10674cc2dcf9SEric Biggers unsigned int i; 10684cc2dcf9SEric Biggers int err; 10694cc2dcf9SEric Biggers 10704cc2dcf9SEric Biggers tfm = crypto_alloc_ahash(driver, type, mask); 10714cc2dcf9SEric Biggers if (IS_ERR(tfm)) { 10724cc2dcf9SEric Biggers pr_err("alg: hash: failed to allocate transform for %s: %ld\n", 10734cc2dcf9SEric Biggers driver, PTR_ERR(tfm)); 10744cc2dcf9SEric Biggers return PTR_ERR(tfm); 10754cc2dcf9SEric Biggers } 10764cc2dcf9SEric Biggers 10774cc2dcf9SEric Biggers req = ahash_request_alloc(tfm, GFP_KERNEL); 10784cc2dcf9SEric Biggers if (!req) { 10794cc2dcf9SEric Biggers pr_err("alg: hash: failed to allocate request for %s\n", 10804cc2dcf9SEric Biggers driver); 10814cc2dcf9SEric Biggers err = -ENOMEM; 10824cc2dcf9SEric Biggers goto out; 10834cc2dcf9SEric Biggers } 10844cc2dcf9SEric Biggers 10854cc2dcf9SEric Biggers tsgl = kmalloc(sizeof(*tsgl), GFP_KERNEL); 10864cc2dcf9SEric Biggers if (!tsgl || init_test_sglist(tsgl) != 0) { 10874cc2dcf9SEric Biggers pr_err("alg: hash: failed to allocate test buffers for %s\n", 10884cc2dcf9SEric Biggers driver); 10894cc2dcf9SEric Biggers kfree(tsgl); 10904cc2dcf9SEric Biggers tsgl = NULL; 10914cc2dcf9SEric Biggers err = -ENOMEM; 10924cc2dcf9SEric Biggers goto out; 10934cc2dcf9SEric Biggers } 10944cc2dcf9SEric Biggers 10954cc2dcf9SEric Biggers hashstate = kmalloc(crypto_ahash_statesize(tfm) + TESTMGR_POISON_LEN, 10964cc2dcf9SEric Biggers GFP_KERNEL); 10974cc2dcf9SEric Biggers if (!hashstate) { 10984cc2dcf9SEric Biggers pr_err("alg: hash: failed to allocate hash state buffer for %s\n", 10994cc2dcf9SEric Biggers driver); 11004cc2dcf9SEric Biggers err = -ENOMEM; 11014cc2dcf9SEric Biggers goto out; 11024cc2dcf9SEric Biggers } 11034cc2dcf9SEric Biggers 11044cc2dcf9SEric Biggers for (i = 0; i < num_vecs; i++) { 11054cc2dcf9SEric Biggers err = test_hash_vec(driver, &vecs[i], i, req, tsgl, hashstate); 11064cc2dcf9SEric Biggers if (err) 11074cc2dcf9SEric Biggers goto out; 11084cc2dcf9SEric Biggers } 11094cc2dcf9SEric Biggers err = 0; 11104cc2dcf9SEric Biggers out: 11114cc2dcf9SEric Biggers kfree(hashstate); 11124cc2dcf9SEric Biggers if (tsgl) { 11134cc2dcf9SEric Biggers destroy_test_sglist(tsgl); 11144cc2dcf9SEric Biggers kfree(tsgl); 11154cc2dcf9SEric Biggers } 11164cc2dcf9SEric Biggers ahash_request_free(req); 11174cc2dcf9SEric Biggers crypto_free_ahash(tfm); 11184cc2dcf9SEric Biggers return err; 11194cc2dcf9SEric Biggers } 11204cc2dcf9SEric Biggers 11214cc2dcf9SEric Biggers static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, 11224cc2dcf9SEric Biggers u32 type, u32 mask) 11234cc2dcf9SEric Biggers { 11244cc2dcf9SEric Biggers const struct hash_testvec *template = desc->suite.hash.vecs; 11254cc2dcf9SEric Biggers unsigned int tcount = desc->suite.hash.count; 11264cc2dcf9SEric Biggers unsigned int nr_unkeyed, nr_keyed; 11274cc2dcf9SEric Biggers int err; 11284cc2dcf9SEric Biggers 11294cc2dcf9SEric Biggers /* 11304cc2dcf9SEric Biggers * For OPTIONAL_KEY algorithms, we have to do all the unkeyed tests 11314cc2dcf9SEric Biggers * first, before setting a key on the tfm. To make this easier, we 11324cc2dcf9SEric Biggers * require that the unkeyed test vectors (if any) are listed first. 11334cc2dcf9SEric Biggers */ 11344cc2dcf9SEric Biggers 11354cc2dcf9SEric Biggers for (nr_unkeyed = 0; nr_unkeyed < tcount; nr_unkeyed++) { 11364cc2dcf9SEric Biggers if (template[nr_unkeyed].ksize) 11374cc2dcf9SEric Biggers break; 11384cc2dcf9SEric Biggers } 11394cc2dcf9SEric Biggers for (nr_keyed = 0; nr_unkeyed + nr_keyed < tcount; nr_keyed++) { 11404cc2dcf9SEric Biggers if (!template[nr_unkeyed + nr_keyed].ksize) { 11414cc2dcf9SEric Biggers pr_err("alg: hash: test vectors for %s out of order, " 11424cc2dcf9SEric Biggers "unkeyed ones must come first\n", desc->alg); 11434cc2dcf9SEric Biggers return -EINVAL; 11444cc2dcf9SEric Biggers } 11454cc2dcf9SEric Biggers } 11464cc2dcf9SEric Biggers 11474cc2dcf9SEric Biggers err = 0; 11484cc2dcf9SEric Biggers if (nr_unkeyed) { 11494cc2dcf9SEric Biggers err = __alg_test_hash(template, nr_unkeyed, driver, type, mask); 11504cc2dcf9SEric Biggers template += nr_unkeyed; 11514cc2dcf9SEric Biggers } 11524cc2dcf9SEric Biggers 11534cc2dcf9SEric Biggers if (!err && nr_keyed) 11544cc2dcf9SEric Biggers err = __alg_test_hash(template, nr_keyed, driver, type, mask); 11554cc2dcf9SEric Biggers 11564cc2dcf9SEric Biggers return err; 11574cc2dcf9SEric Biggers } 11584cc2dcf9SEric Biggers 1159ed96804fSEric Biggers static int test_aead_vec_cfg(const char *driver, int enc, 1160ed96804fSEric Biggers const struct aead_testvec *vec, 1161ed96804fSEric Biggers unsigned int vec_num, 1162ed96804fSEric Biggers const struct testvec_config *cfg, 1163ed96804fSEric Biggers struct aead_request *req, 1164ed96804fSEric Biggers struct cipher_test_sglists *tsgls) 1165da7f033dSHerbert Xu { 1166ed96804fSEric Biggers struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1167ed96804fSEric Biggers const unsigned int alignmask = crypto_aead_alignmask(tfm); 1168ed96804fSEric Biggers const unsigned int ivsize = crypto_aead_ivsize(tfm); 1169ed96804fSEric Biggers const unsigned int authsize = vec->clen - vec->plen; 1170ed96804fSEric Biggers const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 1171ed96804fSEric Biggers const char *op = enc ? "encryption" : "decryption"; 1172ed96804fSEric Biggers DECLARE_CRYPTO_WAIT(wait); 1173ed96804fSEric Biggers u8 _iv[3 * (MAX_ALGAPI_ALIGNMASK + 1) + MAX_IVLEN]; 1174ed96804fSEric Biggers u8 *iv = PTR_ALIGN(&_iv[0], 2 * (MAX_ALGAPI_ALIGNMASK + 1)) + 1175ed96804fSEric Biggers cfg->iv_offset + 1176ed96804fSEric Biggers (cfg->iv_offset_relative_to_alignmask ? alignmask : 0); 1177ed96804fSEric Biggers struct kvec input[2]; 1178ed96804fSEric Biggers int err; 1179f8b0d4d0SHerbert Xu 1180ed96804fSEric Biggers /* Set the key */ 1181ed96804fSEric Biggers if (vec->wk) 1182ed96804fSEric Biggers crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 1183d8a32ac2SJussi Kivilinna else 1184ed96804fSEric Biggers crypto_aead_clear_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 1185ed96804fSEric Biggers err = crypto_aead_setkey(tfm, vec->key, vec->klen); 1186ed96804fSEric Biggers if (err) { 1187ed96804fSEric Biggers if (vec->fail) /* expectedly failed to set key? */ 1188ed96804fSEric Biggers return 0; 1189ed96804fSEric Biggers pr_err("alg: aead: %s setkey failed with err %d on test vector %u; flags=%#x\n", 1190ed96804fSEric Biggers driver, err, vec_num, crypto_aead_get_flags(tfm)); 1191ed96804fSEric Biggers return err; 1192ed96804fSEric Biggers } 1193ed96804fSEric Biggers if (vec->fail) { 1194ed96804fSEric Biggers pr_err("alg: aead: %s setkey unexpectedly succeeded on test vector %u\n", 1195ed96804fSEric Biggers driver, vec_num); 1196ed96804fSEric Biggers return -EINVAL; 1197ed96804fSEric Biggers } 1198d8a32ac2SJussi Kivilinna 1199ed96804fSEric Biggers /* Set the authentication tag size */ 1200ed96804fSEric Biggers err = crypto_aead_setauthsize(tfm, authsize); 1201ed96804fSEric Biggers if (err) { 1202ed96804fSEric Biggers pr_err("alg: aead: %s setauthsize failed with err %d on test vector %u\n", 1203ed96804fSEric Biggers driver, err, vec_num); 1204ed96804fSEric Biggers return err; 1205ed96804fSEric Biggers } 1206ed96804fSEric Biggers 1207ed96804fSEric Biggers /* The IV must be copied to a buffer, as the algorithm may modify it */ 1208ed96804fSEric Biggers if (WARN_ON(ivsize > MAX_IVLEN)) 1209ed96804fSEric Biggers return -EINVAL; 1210ed96804fSEric Biggers if (vec->iv) 1211ed96804fSEric Biggers memcpy(iv, vec->iv, ivsize); 1212da7f033dSHerbert Xu else 1213ed96804fSEric Biggers memset(iv, 0, ivsize); 1214da7f033dSHerbert Xu 1215ed96804fSEric Biggers /* Build the src/dst scatterlists */ 1216ed96804fSEric Biggers input[0].iov_base = (void *)vec->assoc; 1217ed96804fSEric Biggers input[0].iov_len = vec->alen; 1218ed96804fSEric Biggers input[1].iov_base = enc ? (void *)vec->ptext : (void *)vec->ctext; 1219ed96804fSEric Biggers input[1].iov_len = enc ? vec->plen : vec->clen; 1220ed96804fSEric Biggers err = build_cipher_test_sglists(tsgls, cfg, alignmask, 1221ed96804fSEric Biggers vec->alen + (enc ? vec->plen : 1222ed96804fSEric Biggers vec->clen), 1223ed96804fSEric Biggers vec->alen + (enc ? vec->clen : 1224ed96804fSEric Biggers vec->plen), 1225ed96804fSEric Biggers input, 2); 1226ed96804fSEric Biggers if (err) { 1227ed96804fSEric Biggers pr_err("alg: aead: %s %s: error preparing scatterlists for test vector %u, cfg=\"%s\"\n", 1228ed96804fSEric Biggers driver, op, vec_num, cfg->name); 1229ed96804fSEric Biggers return err; 1230da7f033dSHerbert Xu } 1231da7f033dSHerbert Xu 1232ed96804fSEric Biggers /* Do the actual encryption or decryption */ 1233ed96804fSEric Biggers testmgr_poison(req->__ctx, crypto_aead_reqsize(tfm)); 1234ed96804fSEric Biggers aead_request_set_callback(req, req_flags, crypto_req_done, &wait); 1235ed96804fSEric Biggers aead_request_set_crypt(req, tsgls->src.sgl_ptr, tsgls->dst.sgl_ptr, 1236ed96804fSEric Biggers enc ? vec->plen : vec->clen, iv); 1237ed96804fSEric Biggers aead_request_set_ad(req, vec->alen); 1238ed96804fSEric Biggers err = crypto_wait_req(enc ? crypto_aead_encrypt(req) : 1239ed96804fSEric Biggers crypto_aead_decrypt(req), &wait); 1240da7f033dSHerbert Xu 1241ed96804fSEric Biggers aead_request_set_tfm(req, tfm); /* TODO: get rid of this */ 1242abfa7f43SJerome Marchand 1243ed96804fSEric Biggers if (err) { 1244ed96804fSEric Biggers if (err == -EBADMSG && vec->novrfy) 1245ed96804fSEric Biggers return 0; 1246ed96804fSEric Biggers pr_err("alg: aead: %s %s failed with err %d on test vector %u, cfg=\"%s\"\n", 1247ed96804fSEric Biggers driver, op, err, vec_num, cfg->name); 1248ed96804fSEric Biggers return err; 1249ed96804fSEric Biggers } 1250ed96804fSEric Biggers if (vec->novrfy) { 1251ed96804fSEric Biggers pr_err("alg: aead: %s %s unexpectedly succeeded on test vector %u, cfg=\"%s\"\n", 1252ed96804fSEric Biggers driver, op, vec_num, cfg->name); 1253ed96804fSEric Biggers return -EINVAL; 1254a0d608eeSEric Biggers } 125505b1d338SCristian Stoica 1256ed96804fSEric Biggers /* Check for the correct output (ciphertext or plaintext) */ 1257ed96804fSEric Biggers err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext, 1258ed96804fSEric Biggers enc ? vec->clen : vec->plen, 1259ed96804fSEric Biggers vec->alen, enc || !cfg->inplace); 1260ed96804fSEric Biggers if (err == -EOVERFLOW) { 1261ed96804fSEric Biggers pr_err("alg: aead: %s %s overran dst buffer on test vector %u, cfg=\"%s\"\n", 1262ed96804fSEric Biggers driver, op, vec_num, cfg->name); 1263ed96804fSEric Biggers return err; 126429b77e5dSHoria Geanta } 1265ed96804fSEric Biggers if (err) { 1266ed96804fSEric Biggers pr_err("alg: aead: %s %s test failed (wrong result) on test vector %u, cfg=\"%s\"\n", 1267ed96804fSEric Biggers driver, op, vec_num, cfg->name); 1268ed96804fSEric Biggers return err; 126958dcf548SJussi Kivilinna } 127058dcf548SJussi Kivilinna 127158dcf548SJussi Kivilinna return 0; 1272d8a32ac2SJussi Kivilinna } 1273d8a32ac2SJussi Kivilinna 1274ed96804fSEric Biggers static int test_aead_vec(const char *driver, int enc, 1275ed96804fSEric Biggers const struct aead_testvec *vec, unsigned int vec_num, 1276ed96804fSEric Biggers struct aead_request *req, 1277ed96804fSEric Biggers struct cipher_test_sglists *tsgls) 1278ed96804fSEric Biggers { 1279ed96804fSEric Biggers unsigned int i; 1280ed96804fSEric Biggers int err; 1281ed96804fSEric Biggers 1282ed96804fSEric Biggers if (enc && vec->novrfy) 1283ed96804fSEric Biggers return 0; 1284ed96804fSEric Biggers 1285ed96804fSEric Biggers for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) { 1286ed96804fSEric Biggers err = test_aead_vec_cfg(driver, enc, vec, vec_num, 1287ed96804fSEric Biggers &default_cipher_testvec_configs[i], 1288ed96804fSEric Biggers req, tsgls); 1289ed96804fSEric Biggers if (err) 1290ed96804fSEric Biggers return err; 1291ed96804fSEric Biggers } 1292ed96804fSEric Biggers 1293ed96804fSEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 1294ed96804fSEric Biggers if (!noextratests) { 1295ed96804fSEric Biggers struct testvec_config cfg; 1296ed96804fSEric Biggers char cfgname[TESTVEC_CONFIG_NAMELEN]; 1297ed96804fSEric Biggers 1298ed96804fSEric Biggers for (i = 0; i < fuzz_iterations; i++) { 1299ed96804fSEric Biggers generate_random_testvec_config(&cfg, cfgname, 1300ed96804fSEric Biggers sizeof(cfgname)); 1301ed96804fSEric Biggers err = test_aead_vec_cfg(driver, enc, vec, vec_num, 1302ed96804fSEric Biggers &cfg, req, tsgls); 1303ed96804fSEric Biggers if (err) 1304ed96804fSEric Biggers return err; 1305ed96804fSEric Biggers } 1306ed96804fSEric Biggers } 1307ed96804fSEric Biggers #endif 1308ed96804fSEric Biggers return 0; 1309ed96804fSEric Biggers } 1310ed96804fSEric Biggers 1311ed96804fSEric Biggers static int test_aead(const char *driver, int enc, 1312ed96804fSEric Biggers const struct aead_test_suite *suite, 1313ed96804fSEric Biggers struct aead_request *req, 1314ed96804fSEric Biggers struct cipher_test_sglists *tsgls) 1315ed96804fSEric Biggers { 1316ed96804fSEric Biggers unsigned int i; 1317ed96804fSEric Biggers int err; 1318ed96804fSEric Biggers 1319ed96804fSEric Biggers for (i = 0; i < suite->count; i++) { 1320ed96804fSEric Biggers err = test_aead_vec(driver, enc, &suite->vecs[i], i, req, 1321ed96804fSEric Biggers tsgls); 1322ed96804fSEric Biggers if (err) 1323ed96804fSEric Biggers return err; 1324ed96804fSEric Biggers } 1325ed96804fSEric Biggers return 0; 1326ed96804fSEric Biggers } 1327ed96804fSEric Biggers 1328ed96804fSEric Biggers static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, 1329ed96804fSEric Biggers u32 type, u32 mask) 1330ed96804fSEric Biggers { 1331ed96804fSEric Biggers const struct aead_test_suite *suite = &desc->suite.aead; 1332ed96804fSEric Biggers struct crypto_aead *tfm; 1333ed96804fSEric Biggers struct aead_request *req = NULL; 1334ed96804fSEric Biggers struct cipher_test_sglists *tsgls = NULL; 1335ed96804fSEric Biggers int err; 1336ed96804fSEric Biggers 1337ed96804fSEric Biggers if (suite->count <= 0) { 1338ed96804fSEric Biggers pr_err("alg: aead: empty test suite for %s\n", driver); 1339ed96804fSEric Biggers return -EINVAL; 1340ed96804fSEric Biggers } 1341ed96804fSEric Biggers 1342ed96804fSEric Biggers tfm = crypto_alloc_aead(driver, type, mask); 1343ed96804fSEric Biggers if (IS_ERR(tfm)) { 1344ed96804fSEric Biggers pr_err("alg: aead: failed to allocate transform for %s: %ld\n", 1345ed96804fSEric Biggers driver, PTR_ERR(tfm)); 1346ed96804fSEric Biggers return PTR_ERR(tfm); 1347ed96804fSEric Biggers } 1348ed96804fSEric Biggers 1349ed96804fSEric Biggers req = aead_request_alloc(tfm, GFP_KERNEL); 1350ed96804fSEric Biggers if (!req) { 1351ed96804fSEric Biggers pr_err("alg: aead: failed to allocate request for %s\n", 1352ed96804fSEric Biggers driver); 1353ed96804fSEric Biggers err = -ENOMEM; 1354ed96804fSEric Biggers goto out; 1355ed96804fSEric Biggers } 1356ed96804fSEric Biggers 1357ed96804fSEric Biggers tsgls = alloc_cipher_test_sglists(); 1358ed96804fSEric Biggers if (!tsgls) { 1359ed96804fSEric Biggers pr_err("alg: aead: failed to allocate test buffers for %s\n", 1360ed96804fSEric Biggers driver); 1361ed96804fSEric Biggers err = -ENOMEM; 1362ed96804fSEric Biggers goto out; 1363ed96804fSEric Biggers } 1364ed96804fSEric Biggers 1365ed96804fSEric Biggers err = test_aead(driver, ENCRYPT, suite, req, tsgls); 1366ed96804fSEric Biggers if (err) 1367ed96804fSEric Biggers goto out; 1368ed96804fSEric Biggers 1369ed96804fSEric Biggers err = test_aead(driver, DECRYPT, suite, req, tsgls); 1370ed96804fSEric Biggers out: 1371ed96804fSEric Biggers free_cipher_test_sglists(tsgls); 1372ed96804fSEric Biggers aead_request_free(req); 1373ed96804fSEric Biggers crypto_free_aead(tfm); 1374ed96804fSEric Biggers return err; 1375ed96804fSEric Biggers } 1376ed96804fSEric Biggers 13771aa4ecd9SHerbert Xu static int test_cipher(struct crypto_cipher *tfm, int enc, 1378b13b1e0cSEric Biggers const struct cipher_testvec *template, 1379b13b1e0cSEric Biggers unsigned int tcount) 13801aa4ecd9SHerbert Xu { 13811aa4ecd9SHerbert Xu const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); 13821aa4ecd9SHerbert Xu unsigned int i, j, k; 13831aa4ecd9SHerbert Xu char *q; 13841aa4ecd9SHerbert Xu const char *e; 138592a4c9feSEric Biggers const char *input, *result; 13861aa4ecd9SHerbert Xu void *data; 1387f8b0d4d0SHerbert Xu char *xbuf[XBUFSIZE]; 1388f8b0d4d0SHerbert Xu int ret = -ENOMEM; 1389f8b0d4d0SHerbert Xu 1390f8b0d4d0SHerbert Xu if (testmgr_alloc_buf(xbuf)) 1391f8b0d4d0SHerbert Xu goto out_nobuf; 13921aa4ecd9SHerbert Xu 13931aa4ecd9SHerbert Xu if (enc == ENCRYPT) 13941aa4ecd9SHerbert Xu e = "encryption"; 13951aa4ecd9SHerbert Xu else 13961aa4ecd9SHerbert Xu e = "decryption"; 13971aa4ecd9SHerbert Xu 13981aa4ecd9SHerbert Xu j = 0; 13991aa4ecd9SHerbert Xu for (i = 0; i < tcount; i++) { 14001aa4ecd9SHerbert Xu 140110faa8c0SStephan Mueller if (fips_enabled && template[i].fips_skip) 140210faa8c0SStephan Mueller continue; 140310faa8c0SStephan Mueller 140492a4c9feSEric Biggers input = enc ? template[i].ptext : template[i].ctext; 140592a4c9feSEric Biggers result = enc ? template[i].ctext : template[i].ptext; 14061aa4ecd9SHerbert Xu j++; 14071aa4ecd9SHerbert Xu 1408fd57f22aSHerbert Xu ret = -EINVAL; 140992a4c9feSEric Biggers if (WARN_ON(template[i].len > PAGE_SIZE)) 1410fd57f22aSHerbert Xu goto out; 1411fd57f22aSHerbert Xu 14121aa4ecd9SHerbert Xu data = xbuf[0]; 141392a4c9feSEric Biggers memcpy(data, input, template[i].len); 14141aa4ecd9SHerbert Xu 14151aa4ecd9SHerbert Xu crypto_cipher_clear_flags(tfm, ~0); 14161aa4ecd9SHerbert Xu if (template[i].wk) 1417231baecdSEric Biggers crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 14181aa4ecd9SHerbert Xu 14191aa4ecd9SHerbert Xu ret = crypto_cipher_setkey(tfm, template[i].key, 14201aa4ecd9SHerbert Xu template[i].klen); 14210fae0c1eSYanjiang Jin if (template[i].fail == !ret) { 14221aa4ecd9SHerbert Xu printk(KERN_ERR "alg: cipher: setkey failed " 14231aa4ecd9SHerbert Xu "on test %d for %s: flags=%x\n", j, 14241aa4ecd9SHerbert Xu algo, crypto_cipher_get_flags(tfm)); 14251aa4ecd9SHerbert Xu goto out; 14261aa4ecd9SHerbert Xu } else if (ret) 14271aa4ecd9SHerbert Xu continue; 14281aa4ecd9SHerbert Xu 142992a4c9feSEric Biggers for (k = 0; k < template[i].len; 14301aa4ecd9SHerbert Xu k += crypto_cipher_blocksize(tfm)) { 14311aa4ecd9SHerbert Xu if (enc) 14321aa4ecd9SHerbert Xu crypto_cipher_encrypt_one(tfm, data + k, 14331aa4ecd9SHerbert Xu data + k); 14341aa4ecd9SHerbert Xu else 14351aa4ecd9SHerbert Xu crypto_cipher_decrypt_one(tfm, data + k, 14361aa4ecd9SHerbert Xu data + k); 14371aa4ecd9SHerbert Xu } 14381aa4ecd9SHerbert Xu 14391aa4ecd9SHerbert Xu q = data; 144092a4c9feSEric Biggers if (memcmp(q, result, template[i].len)) { 14411aa4ecd9SHerbert Xu printk(KERN_ERR "alg: cipher: Test %d failed " 14421aa4ecd9SHerbert Xu "on %s for %s\n", j, e, algo); 144392a4c9feSEric Biggers hexdump(q, template[i].len); 14441aa4ecd9SHerbert Xu ret = -EINVAL; 14451aa4ecd9SHerbert Xu goto out; 14461aa4ecd9SHerbert Xu } 14471aa4ecd9SHerbert Xu } 14481aa4ecd9SHerbert Xu 14491aa4ecd9SHerbert Xu ret = 0; 14501aa4ecd9SHerbert Xu 14511aa4ecd9SHerbert Xu out: 1452f8b0d4d0SHerbert Xu testmgr_free_buf(xbuf); 1453f8b0d4d0SHerbert Xu out_nobuf: 14541aa4ecd9SHerbert Xu return ret; 14551aa4ecd9SHerbert Xu } 14561aa4ecd9SHerbert Xu 14574e7babbaSEric Biggers static int test_skcipher_vec_cfg(const char *driver, int enc, 14584e7babbaSEric Biggers const struct cipher_testvec *vec, 14594e7babbaSEric Biggers unsigned int vec_num, 14604e7babbaSEric Biggers const struct testvec_config *cfg, 14614e7babbaSEric Biggers struct skcipher_request *req, 14624e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 1463da7f033dSHerbert Xu { 14644e7babbaSEric Biggers struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 14654e7babbaSEric Biggers const unsigned int alignmask = crypto_skcipher_alignmask(tfm); 14664e7babbaSEric Biggers const unsigned int ivsize = crypto_skcipher_ivsize(tfm); 14674e7babbaSEric Biggers const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags; 14684e7babbaSEric Biggers const char *op = enc ? "encryption" : "decryption"; 14694e7babbaSEric Biggers DECLARE_CRYPTO_WAIT(wait); 14704e7babbaSEric Biggers u8 _iv[3 * (MAX_ALGAPI_ALIGNMASK + 1) + MAX_IVLEN]; 14714e7babbaSEric Biggers u8 *iv = PTR_ALIGN(&_iv[0], 2 * (MAX_ALGAPI_ALIGNMASK + 1)) + 14724e7babbaSEric Biggers cfg->iv_offset + 14734e7babbaSEric Biggers (cfg->iv_offset_relative_to_alignmask ? alignmask : 0); 14744e7babbaSEric Biggers struct kvec input; 14754e7babbaSEric Biggers int err; 1476f8b0d4d0SHerbert Xu 14774e7babbaSEric Biggers /* Set the key */ 14784e7babbaSEric Biggers if (vec->wk) 1479231baecdSEric Biggers crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 1480da7f033dSHerbert Xu else 14814e7babbaSEric Biggers crypto_skcipher_clear_flags(tfm, 14824e7babbaSEric Biggers CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 14834e7babbaSEric Biggers err = crypto_skcipher_setkey(tfm, vec->key, vec->klen); 14844e7babbaSEric Biggers if (err) { 14854e7babbaSEric Biggers if (vec->fail) /* expectedly failed to set key? */ 14864e7babbaSEric Biggers return 0; 14874e7babbaSEric Biggers pr_err("alg: skcipher: %s setkey failed with err %d on test vector %u; flags=%#x\n", 14884e7babbaSEric Biggers driver, err, vec_num, crypto_skcipher_get_flags(tfm)); 14894e7babbaSEric Biggers return err; 14904e7babbaSEric Biggers } 14914e7babbaSEric Biggers if (vec->fail) { 14924e7babbaSEric Biggers pr_err("alg: skcipher: %s setkey unexpectedly succeeded on test vector %u\n", 14934e7babbaSEric Biggers driver, vec_num); 14944e7babbaSEric Biggers return -EINVAL; 149508d6af8cSJussi Kivilinna } 1496da7f033dSHerbert Xu 14974e7babbaSEric Biggers /* The IV must be copied to a buffer, as the algorithm may modify it */ 14984e7babbaSEric Biggers if (ivsize) { 14994e7babbaSEric Biggers if (WARN_ON(ivsize > MAX_IVLEN)) 15004e7babbaSEric Biggers return -EINVAL; 15014e7babbaSEric Biggers if (vec->iv && !(vec->generates_iv && enc)) 15024e7babbaSEric Biggers memcpy(iv, vec->iv, ivsize); 150308d6af8cSJussi Kivilinna else 15044e7babbaSEric Biggers memset(iv, 0, ivsize); 15054e7babbaSEric Biggers } else { 15064e7babbaSEric Biggers if (vec->generates_iv) { 15074e7babbaSEric Biggers pr_err("alg: skcipher: %s has ivsize=0 but test vector %u generates IV!\n", 15084e7babbaSEric Biggers driver, vec_num); 15094e7babbaSEric Biggers return -EINVAL; 15104e7babbaSEric Biggers } 15114e7babbaSEric Biggers iv = NULL; 1512da7f033dSHerbert Xu } 1513da7f033dSHerbert Xu 15144e7babbaSEric Biggers /* Build the src/dst scatterlists */ 15154e7babbaSEric Biggers input.iov_base = enc ? (void *)vec->ptext : (void *)vec->ctext; 15164e7babbaSEric Biggers input.iov_len = vec->len; 15174e7babbaSEric Biggers err = build_cipher_test_sglists(tsgls, cfg, alignmask, 15184e7babbaSEric Biggers vec->len, vec->len, &input, 1); 15194e7babbaSEric Biggers if (err) { 15204e7babbaSEric Biggers pr_err("alg: skcipher: %s %s: error preparing scatterlists for test vector %u, cfg=\"%s\"\n", 15214e7babbaSEric Biggers driver, op, vec_num, cfg->name); 15224e7babbaSEric Biggers return err; 1523da7f033dSHerbert Xu } 1524da7f033dSHerbert Xu 15254e7babbaSEric Biggers /* Do the actual encryption or decryption */ 15264e7babbaSEric Biggers testmgr_poison(req->__ctx, crypto_skcipher_reqsize(tfm)); 15274e7babbaSEric Biggers skcipher_request_set_callback(req, req_flags, crypto_req_done, &wait); 15284e7babbaSEric Biggers skcipher_request_set_crypt(req, tsgls->src.sgl_ptr, tsgls->dst.sgl_ptr, 15294e7babbaSEric Biggers vec->len, iv); 15304e7babbaSEric Biggers err = crypto_wait_req(enc ? crypto_skcipher_encrypt(req) : 15314e7babbaSEric Biggers crypto_skcipher_decrypt(req), &wait); 15324e7babbaSEric Biggers if (err) { 15334e7babbaSEric Biggers pr_err("alg: skcipher: %s %s failed with err %d on test vector %u, cfg=\"%s\"\n", 15344e7babbaSEric Biggers driver, op, err, vec_num, cfg->name); 15354e7babbaSEric Biggers return err; 1536da7f033dSHerbert Xu } 1537da7f033dSHerbert Xu 1538fa353c99SEric Biggers /* Check that the algorithm didn't overwrite things it shouldn't have */ 1539fa353c99SEric Biggers if (req->cryptlen != vec->len || 1540fa353c99SEric Biggers req->iv != iv || 1541fa353c99SEric Biggers req->src != tsgls->src.sgl_ptr || 1542fa353c99SEric Biggers req->dst != tsgls->dst.sgl_ptr || 1543fa353c99SEric Biggers crypto_skcipher_reqtfm(req) != tfm || 1544fa353c99SEric Biggers req->base.complete != crypto_req_done || 1545fa353c99SEric Biggers req->base.flags != req_flags || 1546fa353c99SEric Biggers req->base.data != &wait) { 1547fa353c99SEric Biggers pr_err("alg: skcipher: %s %s corrupted request struct on test vector %u, cfg=\"%s\"\n", 1548fa353c99SEric Biggers driver, op, vec_num, cfg->name); 1549fa353c99SEric Biggers if (req->cryptlen != vec->len) 1550fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->cryptlen'\n"); 1551fa353c99SEric Biggers if (req->iv != iv) 1552fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->iv'\n"); 1553fa353c99SEric Biggers if (req->src != tsgls->src.sgl_ptr) 1554fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->src'\n"); 1555fa353c99SEric Biggers if (req->dst != tsgls->dst.sgl_ptr) 1556fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->dst'\n"); 1557fa353c99SEric Biggers if (crypto_skcipher_reqtfm(req) != tfm) 1558fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->base.tfm'\n"); 1559fa353c99SEric Biggers if (req->base.complete != crypto_req_done) 1560fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->base.complete'\n"); 1561fa353c99SEric Biggers if (req->base.flags != req_flags) 1562fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->base.flags'\n"); 1563fa353c99SEric Biggers if (req->base.data != &wait) 1564fa353c99SEric Biggers pr_err("alg: skcipher: changed 'req->base.data'\n"); 1565fa353c99SEric Biggers return -EINVAL; 1566fa353c99SEric Biggers } 1567fa353c99SEric Biggers if (is_test_sglist_corrupted(&tsgls->src)) { 1568fa353c99SEric Biggers pr_err("alg: skcipher: %s %s corrupted src sgl on test vector %u, cfg=\"%s\"\n", 1569fa353c99SEric Biggers driver, op, vec_num, cfg->name); 1570fa353c99SEric Biggers return -EINVAL; 1571fa353c99SEric Biggers } 1572fa353c99SEric Biggers if (tsgls->dst.sgl_ptr != tsgls->src.sgl && 1573fa353c99SEric Biggers is_test_sglist_corrupted(&tsgls->dst)) { 1574fa353c99SEric Biggers pr_err("alg: skcipher: %s %s corrupted dst sgl on test vector %u, cfg=\"%s\"\n", 1575fa353c99SEric Biggers driver, op, vec_num, cfg->name); 1576fa353c99SEric Biggers return -EINVAL; 1577fa353c99SEric Biggers } 1578fa353c99SEric Biggers 15794e7babbaSEric Biggers /* Check for the correct output (ciphertext or plaintext) */ 15804e7babbaSEric Biggers err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext, 15814e7babbaSEric Biggers vec->len, 0, true); 15824e7babbaSEric Biggers if (err == -EOVERFLOW) { 15834e7babbaSEric Biggers pr_err("alg: skcipher: %s %s overran dst buffer on test vector %u, cfg=\"%s\"\n", 15844e7babbaSEric Biggers driver, op, vec_num, cfg->name); 15854e7babbaSEric Biggers return err; 15864e7babbaSEric Biggers } 15874e7babbaSEric Biggers if (err) { 15884e7babbaSEric Biggers pr_err("alg: skcipher: %s %s test failed (wrong result) on test vector %u, cfg=\"%s\"\n", 15894e7babbaSEric Biggers driver, op, vec_num, cfg->name); 15904e7babbaSEric Biggers return err; 15914e7babbaSEric Biggers } 159208d6af8cSJussi Kivilinna 15934e7babbaSEric Biggers /* If applicable, check that the algorithm generated the correct IV */ 15944e7babbaSEric Biggers if (vec->generates_iv && enc && memcmp(iv, vec->iv, ivsize) != 0) { 15954e7babbaSEric Biggers pr_err("alg: skcipher: %s %s test failed (wrong output IV) on test vector %u, cfg=\"%s\"\n", 15964e7babbaSEric Biggers driver, op, vec_num, cfg->name); 15974e7babbaSEric Biggers hexdump(iv, ivsize); 15984e7babbaSEric Biggers return -EINVAL; 15993a338f20SJussi Kivilinna } 16003a338f20SJussi Kivilinna 16013a338f20SJussi Kivilinna return 0; 160208d6af8cSJussi Kivilinna } 160308d6af8cSJussi Kivilinna 16044e7babbaSEric Biggers static int test_skcipher_vec(const char *driver, int enc, 16054e7babbaSEric Biggers const struct cipher_testvec *vec, 16064e7babbaSEric Biggers unsigned int vec_num, 16074e7babbaSEric Biggers struct skcipher_request *req, 16084e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 16094e7babbaSEric Biggers { 16104e7babbaSEric Biggers unsigned int i; 16114e7babbaSEric Biggers int err; 16124e7babbaSEric Biggers 16134e7babbaSEric Biggers if (fips_enabled && vec->fips_skip) 16144e7babbaSEric Biggers return 0; 16154e7babbaSEric Biggers 16164e7babbaSEric Biggers for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) { 16174e7babbaSEric Biggers err = test_skcipher_vec_cfg(driver, enc, vec, vec_num, 16184e7babbaSEric Biggers &default_cipher_testvec_configs[i], 16194e7babbaSEric Biggers req, tsgls); 16204e7babbaSEric Biggers if (err) 16214e7babbaSEric Biggers return err; 16224e7babbaSEric Biggers } 16234e7babbaSEric Biggers 16244e7babbaSEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 16254e7babbaSEric Biggers if (!noextratests) { 16264e7babbaSEric Biggers struct testvec_config cfg; 16274e7babbaSEric Biggers char cfgname[TESTVEC_CONFIG_NAMELEN]; 16284e7babbaSEric Biggers 16294e7babbaSEric Biggers for (i = 0; i < fuzz_iterations; i++) { 16304e7babbaSEric Biggers generate_random_testvec_config(&cfg, cfgname, 16314e7babbaSEric Biggers sizeof(cfgname)); 16324e7babbaSEric Biggers err = test_skcipher_vec_cfg(driver, enc, vec, vec_num, 16334e7babbaSEric Biggers &cfg, req, tsgls); 16344e7babbaSEric Biggers if (err) 16354e7babbaSEric Biggers return err; 16364e7babbaSEric Biggers } 16374e7babbaSEric Biggers } 16384e7babbaSEric Biggers #endif 16394e7babbaSEric Biggers return 0; 16404e7babbaSEric Biggers } 16414e7babbaSEric Biggers 16424e7babbaSEric Biggers static int test_skcipher(const char *driver, int enc, 16434e7babbaSEric Biggers const struct cipher_test_suite *suite, 16444e7babbaSEric Biggers struct skcipher_request *req, 16454e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 16464e7babbaSEric Biggers { 16474e7babbaSEric Biggers unsigned int i; 16484e7babbaSEric Biggers int err; 16494e7babbaSEric Biggers 16504e7babbaSEric Biggers for (i = 0; i < suite->count; i++) { 16514e7babbaSEric Biggers err = test_skcipher_vec(driver, enc, &suite->vecs[i], i, req, 16524e7babbaSEric Biggers tsgls); 16534e7babbaSEric Biggers if (err) 16544e7babbaSEric Biggers return err; 16554e7babbaSEric Biggers } 16564e7babbaSEric Biggers return 0; 16574e7babbaSEric Biggers } 16584e7babbaSEric Biggers 16594e7babbaSEric Biggers static int alg_test_skcipher(const struct alg_test_desc *desc, 16604e7babbaSEric Biggers const char *driver, u32 type, u32 mask) 16614e7babbaSEric Biggers { 16624e7babbaSEric Biggers const struct cipher_test_suite *suite = &desc->suite.cipher; 16634e7babbaSEric Biggers struct crypto_skcipher *tfm; 16644e7babbaSEric Biggers struct skcipher_request *req = NULL; 16654e7babbaSEric Biggers struct cipher_test_sglists *tsgls = NULL; 16664e7babbaSEric Biggers int err; 16674e7babbaSEric Biggers 16684e7babbaSEric Biggers if (suite->count <= 0) { 16694e7babbaSEric Biggers pr_err("alg: skcipher: empty test suite for %s\n", driver); 16704e7babbaSEric Biggers return -EINVAL; 16714e7babbaSEric Biggers } 16724e7babbaSEric Biggers 16734e7babbaSEric Biggers tfm = crypto_alloc_skcipher(driver, type, mask); 16744e7babbaSEric Biggers if (IS_ERR(tfm)) { 16754e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", 16764e7babbaSEric Biggers driver, PTR_ERR(tfm)); 16774e7babbaSEric Biggers return PTR_ERR(tfm); 16784e7babbaSEric Biggers } 16794e7babbaSEric Biggers 16804e7babbaSEric Biggers req = skcipher_request_alloc(tfm, GFP_KERNEL); 16814e7babbaSEric Biggers if (!req) { 16824e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate request for %s\n", 16834e7babbaSEric Biggers driver); 16844e7babbaSEric Biggers err = -ENOMEM; 16854e7babbaSEric Biggers goto out; 16864e7babbaSEric Biggers } 16874e7babbaSEric Biggers 16884e7babbaSEric Biggers tsgls = alloc_cipher_test_sglists(); 16894e7babbaSEric Biggers if (!tsgls) { 16904e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate test buffers for %s\n", 16914e7babbaSEric Biggers driver); 16924e7babbaSEric Biggers err = -ENOMEM; 16934e7babbaSEric Biggers goto out; 16944e7babbaSEric Biggers } 16954e7babbaSEric Biggers 16964e7babbaSEric Biggers err = test_skcipher(driver, ENCRYPT, suite, req, tsgls); 16974e7babbaSEric Biggers if (err) 16984e7babbaSEric Biggers goto out; 16994e7babbaSEric Biggers 17004e7babbaSEric Biggers err = test_skcipher(driver, DECRYPT, suite, req, tsgls); 17014e7babbaSEric Biggers out: 17024e7babbaSEric Biggers free_cipher_test_sglists(tsgls); 17034e7babbaSEric Biggers skcipher_request_free(req); 17044e7babbaSEric Biggers crypto_free_skcipher(tfm); 17054e7babbaSEric Biggers return err; 17064e7babbaSEric Biggers } 17074e7babbaSEric Biggers 1708b13b1e0cSEric Biggers static int test_comp(struct crypto_comp *tfm, 1709b13b1e0cSEric Biggers const struct comp_testvec *ctemplate, 1710b13b1e0cSEric Biggers const struct comp_testvec *dtemplate, 1711b13b1e0cSEric Biggers int ctcount, int dtcount) 1712da7f033dSHerbert Xu { 1713da7f033dSHerbert Xu const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm)); 171433607384SMahipal Challa char *output, *decomp_output; 1715da7f033dSHerbert Xu unsigned int i; 1716da7f033dSHerbert Xu int ret; 1717da7f033dSHerbert Xu 171833607384SMahipal Challa output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 171933607384SMahipal Challa if (!output) 172033607384SMahipal Challa return -ENOMEM; 172133607384SMahipal Challa 172233607384SMahipal Challa decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 172333607384SMahipal Challa if (!decomp_output) { 172433607384SMahipal Challa kfree(output); 172533607384SMahipal Challa return -ENOMEM; 172633607384SMahipal Challa } 172733607384SMahipal Challa 1728da7f033dSHerbert Xu for (i = 0; i < ctcount; i++) { 1729c79cf910SGeert Uytterhoeven int ilen; 1730c79cf910SGeert Uytterhoeven unsigned int dlen = COMP_BUF_SIZE; 1731da7f033dSHerbert Xu 173222a8118dSMichael Schupikov memset(output, 0, COMP_BUF_SIZE); 173322a8118dSMichael Schupikov memset(decomp_output, 0, COMP_BUF_SIZE); 1734da7f033dSHerbert Xu 1735da7f033dSHerbert Xu ilen = ctemplate[i].inlen; 1736da7f033dSHerbert Xu ret = crypto_comp_compress(tfm, ctemplate[i].input, 173733607384SMahipal Challa ilen, output, &dlen); 1738da7f033dSHerbert Xu if (ret) { 1739da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: compression failed " 1740da7f033dSHerbert Xu "on test %d for %s: ret=%d\n", i + 1, algo, 1741da7f033dSHerbert Xu -ret); 1742da7f033dSHerbert Xu goto out; 1743da7f033dSHerbert Xu } 1744da7f033dSHerbert Xu 174533607384SMahipal Challa ilen = dlen; 174633607384SMahipal Challa dlen = COMP_BUF_SIZE; 174733607384SMahipal Challa ret = crypto_comp_decompress(tfm, output, 174833607384SMahipal Challa ilen, decomp_output, &dlen); 174933607384SMahipal Challa if (ret) { 175033607384SMahipal Challa pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n", 175133607384SMahipal Challa i + 1, algo, -ret); 175233607384SMahipal Challa goto out; 175333607384SMahipal Challa } 175433607384SMahipal Challa 175533607384SMahipal Challa if (dlen != ctemplate[i].inlen) { 1756b812eb00SGeert Uytterhoeven printk(KERN_ERR "alg: comp: Compression test %d " 1757b812eb00SGeert Uytterhoeven "failed for %s: output len = %d\n", i + 1, algo, 1758b812eb00SGeert Uytterhoeven dlen); 1759b812eb00SGeert Uytterhoeven ret = -EINVAL; 1760b812eb00SGeert Uytterhoeven goto out; 1761b812eb00SGeert Uytterhoeven } 1762b812eb00SGeert Uytterhoeven 176333607384SMahipal Challa if (memcmp(decomp_output, ctemplate[i].input, 176433607384SMahipal Challa ctemplate[i].inlen)) { 176533607384SMahipal Challa pr_err("alg: comp: compression failed: output differs: on test %d for %s\n", 176633607384SMahipal Challa i + 1, algo); 176733607384SMahipal Challa hexdump(decomp_output, dlen); 1768da7f033dSHerbert Xu ret = -EINVAL; 1769da7f033dSHerbert Xu goto out; 1770da7f033dSHerbert Xu } 1771da7f033dSHerbert Xu } 1772da7f033dSHerbert Xu 1773da7f033dSHerbert Xu for (i = 0; i < dtcount; i++) { 1774c79cf910SGeert Uytterhoeven int ilen; 1775c79cf910SGeert Uytterhoeven unsigned int dlen = COMP_BUF_SIZE; 1776da7f033dSHerbert Xu 177722a8118dSMichael Schupikov memset(decomp_output, 0, COMP_BUF_SIZE); 1778da7f033dSHerbert Xu 1779da7f033dSHerbert Xu ilen = dtemplate[i].inlen; 1780da7f033dSHerbert Xu ret = crypto_comp_decompress(tfm, dtemplate[i].input, 178133607384SMahipal Challa ilen, decomp_output, &dlen); 1782da7f033dSHerbert Xu if (ret) { 1783da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: decompression failed " 1784da7f033dSHerbert Xu "on test %d for %s: ret=%d\n", i + 1, algo, 1785da7f033dSHerbert Xu -ret); 1786da7f033dSHerbert Xu goto out; 1787da7f033dSHerbert Xu } 1788da7f033dSHerbert Xu 1789b812eb00SGeert Uytterhoeven if (dlen != dtemplate[i].outlen) { 1790b812eb00SGeert Uytterhoeven printk(KERN_ERR "alg: comp: Decompression test %d " 1791b812eb00SGeert Uytterhoeven "failed for %s: output len = %d\n", i + 1, algo, 1792b812eb00SGeert Uytterhoeven dlen); 1793b812eb00SGeert Uytterhoeven ret = -EINVAL; 1794b812eb00SGeert Uytterhoeven goto out; 1795b812eb00SGeert Uytterhoeven } 1796b812eb00SGeert Uytterhoeven 179733607384SMahipal Challa if (memcmp(decomp_output, dtemplate[i].output, dlen)) { 1798da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: Decompression test %d " 1799da7f033dSHerbert Xu "failed for %s\n", i + 1, algo); 180033607384SMahipal Challa hexdump(decomp_output, dlen); 1801da7f033dSHerbert Xu ret = -EINVAL; 1802da7f033dSHerbert Xu goto out; 1803da7f033dSHerbert Xu } 1804da7f033dSHerbert Xu } 1805da7f033dSHerbert Xu 1806da7f033dSHerbert Xu ret = 0; 1807da7f033dSHerbert Xu 1808da7f033dSHerbert Xu out: 180933607384SMahipal Challa kfree(decomp_output); 181033607384SMahipal Challa kfree(output); 1811da7f033dSHerbert Xu return ret; 1812da7f033dSHerbert Xu } 1813da7f033dSHerbert Xu 1814b13b1e0cSEric Biggers static int test_acomp(struct crypto_acomp *tfm, 1815b13b1e0cSEric Biggers const struct comp_testvec *ctemplate, 1816b13b1e0cSEric Biggers const struct comp_testvec *dtemplate, 1817b13b1e0cSEric Biggers int ctcount, int dtcount) 1818d7db7a88SGiovanni Cabiddu { 1819d7db7a88SGiovanni Cabiddu const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); 1820d7db7a88SGiovanni Cabiddu unsigned int i; 1821a9943a0aSGiovanni Cabiddu char *output, *decomp_out; 1822d7db7a88SGiovanni Cabiddu int ret; 1823d7db7a88SGiovanni Cabiddu struct scatterlist src, dst; 1824d7db7a88SGiovanni Cabiddu struct acomp_req *req; 18257f397136SGilad Ben-Yossef struct crypto_wait wait; 1826d7db7a88SGiovanni Cabiddu 1827eb095593SEric Biggers output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 1828eb095593SEric Biggers if (!output) 1829eb095593SEric Biggers return -ENOMEM; 1830eb095593SEric Biggers 1831a9943a0aSGiovanni Cabiddu decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 1832a9943a0aSGiovanni Cabiddu if (!decomp_out) { 1833a9943a0aSGiovanni Cabiddu kfree(output); 1834a9943a0aSGiovanni Cabiddu return -ENOMEM; 1835a9943a0aSGiovanni Cabiddu } 1836a9943a0aSGiovanni Cabiddu 1837d7db7a88SGiovanni Cabiddu for (i = 0; i < ctcount; i++) { 1838d7db7a88SGiovanni Cabiddu unsigned int dlen = COMP_BUF_SIZE; 1839d7db7a88SGiovanni Cabiddu int ilen = ctemplate[i].inlen; 184002608e02SLaura Abbott void *input_vec; 1841d7db7a88SGiovanni Cabiddu 1842d2110224SEric Biggers input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); 184302608e02SLaura Abbott if (!input_vec) { 184402608e02SLaura Abbott ret = -ENOMEM; 184502608e02SLaura Abbott goto out; 184602608e02SLaura Abbott } 184702608e02SLaura Abbott 1848eb095593SEric Biggers memset(output, 0, dlen); 18497f397136SGilad Ben-Yossef crypto_init_wait(&wait); 185002608e02SLaura Abbott sg_init_one(&src, input_vec, ilen); 1851d7db7a88SGiovanni Cabiddu sg_init_one(&dst, output, dlen); 1852d7db7a88SGiovanni Cabiddu 1853d7db7a88SGiovanni Cabiddu req = acomp_request_alloc(tfm); 1854d7db7a88SGiovanni Cabiddu if (!req) { 1855d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: request alloc failed for %s\n", 1856d7db7a88SGiovanni Cabiddu algo); 185702608e02SLaura Abbott kfree(input_vec); 1858d7db7a88SGiovanni Cabiddu ret = -ENOMEM; 1859d7db7a88SGiovanni Cabiddu goto out; 1860d7db7a88SGiovanni Cabiddu } 1861d7db7a88SGiovanni Cabiddu 1862d7db7a88SGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 1863d7db7a88SGiovanni Cabiddu acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 18647f397136SGilad Ben-Yossef crypto_req_done, &wait); 1865d7db7a88SGiovanni Cabiddu 18667f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_compress(req), &wait); 1867d7db7a88SGiovanni Cabiddu if (ret) { 1868d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 1869d7db7a88SGiovanni Cabiddu i + 1, algo, -ret); 187002608e02SLaura Abbott kfree(input_vec); 1871d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1872d7db7a88SGiovanni Cabiddu goto out; 1873d7db7a88SGiovanni Cabiddu } 1874d7db7a88SGiovanni Cabiddu 1875a9943a0aSGiovanni Cabiddu ilen = req->dlen; 1876a9943a0aSGiovanni Cabiddu dlen = COMP_BUF_SIZE; 1877a9943a0aSGiovanni Cabiddu sg_init_one(&src, output, ilen); 1878a9943a0aSGiovanni Cabiddu sg_init_one(&dst, decomp_out, dlen); 18797f397136SGilad Ben-Yossef crypto_init_wait(&wait); 1880a9943a0aSGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 1881a9943a0aSGiovanni Cabiddu 18827f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 1883a9943a0aSGiovanni Cabiddu if (ret) { 1884a9943a0aSGiovanni Cabiddu pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 1885a9943a0aSGiovanni Cabiddu i + 1, algo, -ret); 1886a9943a0aSGiovanni Cabiddu kfree(input_vec); 1887a9943a0aSGiovanni Cabiddu acomp_request_free(req); 1888a9943a0aSGiovanni Cabiddu goto out; 1889a9943a0aSGiovanni Cabiddu } 1890a9943a0aSGiovanni Cabiddu 1891a9943a0aSGiovanni Cabiddu if (req->dlen != ctemplate[i].inlen) { 1892d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", 1893d7db7a88SGiovanni Cabiddu i + 1, algo, req->dlen); 1894d7db7a88SGiovanni Cabiddu ret = -EINVAL; 189502608e02SLaura Abbott kfree(input_vec); 1896d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1897d7db7a88SGiovanni Cabiddu goto out; 1898d7db7a88SGiovanni Cabiddu } 1899d7db7a88SGiovanni Cabiddu 1900a9943a0aSGiovanni Cabiddu if (memcmp(input_vec, decomp_out, req->dlen)) { 1901d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Compression test %d failed for %s\n", 1902d7db7a88SGiovanni Cabiddu i + 1, algo); 1903d7db7a88SGiovanni Cabiddu hexdump(output, req->dlen); 1904d7db7a88SGiovanni Cabiddu ret = -EINVAL; 190502608e02SLaura Abbott kfree(input_vec); 1906d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1907d7db7a88SGiovanni Cabiddu goto out; 1908d7db7a88SGiovanni Cabiddu } 1909d7db7a88SGiovanni Cabiddu 191002608e02SLaura Abbott kfree(input_vec); 1911d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1912d7db7a88SGiovanni Cabiddu } 1913d7db7a88SGiovanni Cabiddu 1914d7db7a88SGiovanni Cabiddu for (i = 0; i < dtcount; i++) { 1915d7db7a88SGiovanni Cabiddu unsigned int dlen = COMP_BUF_SIZE; 1916d7db7a88SGiovanni Cabiddu int ilen = dtemplate[i].inlen; 191702608e02SLaura Abbott void *input_vec; 1918d7db7a88SGiovanni Cabiddu 1919d2110224SEric Biggers input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL); 192002608e02SLaura Abbott if (!input_vec) { 192102608e02SLaura Abbott ret = -ENOMEM; 192202608e02SLaura Abbott goto out; 192302608e02SLaura Abbott } 192402608e02SLaura Abbott 1925eb095593SEric Biggers memset(output, 0, dlen); 19267f397136SGilad Ben-Yossef crypto_init_wait(&wait); 192702608e02SLaura Abbott sg_init_one(&src, input_vec, ilen); 1928d7db7a88SGiovanni Cabiddu sg_init_one(&dst, output, dlen); 1929d7db7a88SGiovanni Cabiddu 1930d7db7a88SGiovanni Cabiddu req = acomp_request_alloc(tfm); 1931d7db7a88SGiovanni Cabiddu if (!req) { 1932d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: request alloc failed for %s\n", 1933d7db7a88SGiovanni Cabiddu algo); 193402608e02SLaura Abbott kfree(input_vec); 1935d7db7a88SGiovanni Cabiddu ret = -ENOMEM; 1936d7db7a88SGiovanni Cabiddu goto out; 1937d7db7a88SGiovanni Cabiddu } 1938d7db7a88SGiovanni Cabiddu 1939d7db7a88SGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 1940d7db7a88SGiovanni Cabiddu acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 19417f397136SGilad Ben-Yossef crypto_req_done, &wait); 1942d7db7a88SGiovanni Cabiddu 19437f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 1944d7db7a88SGiovanni Cabiddu if (ret) { 1945d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n", 1946d7db7a88SGiovanni Cabiddu i + 1, algo, -ret); 194702608e02SLaura Abbott kfree(input_vec); 1948d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1949d7db7a88SGiovanni Cabiddu goto out; 1950d7db7a88SGiovanni Cabiddu } 1951d7db7a88SGiovanni Cabiddu 1952d7db7a88SGiovanni Cabiddu if (req->dlen != dtemplate[i].outlen) { 1953d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n", 1954d7db7a88SGiovanni Cabiddu i + 1, algo, req->dlen); 1955d7db7a88SGiovanni Cabiddu ret = -EINVAL; 195602608e02SLaura Abbott kfree(input_vec); 1957d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1958d7db7a88SGiovanni Cabiddu goto out; 1959d7db7a88SGiovanni Cabiddu } 1960d7db7a88SGiovanni Cabiddu 1961d7db7a88SGiovanni Cabiddu if (memcmp(output, dtemplate[i].output, req->dlen)) { 1962d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Decompression test %d failed for %s\n", 1963d7db7a88SGiovanni Cabiddu i + 1, algo); 1964d7db7a88SGiovanni Cabiddu hexdump(output, req->dlen); 1965d7db7a88SGiovanni Cabiddu ret = -EINVAL; 196602608e02SLaura Abbott kfree(input_vec); 1967d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1968d7db7a88SGiovanni Cabiddu goto out; 1969d7db7a88SGiovanni Cabiddu } 1970d7db7a88SGiovanni Cabiddu 197102608e02SLaura Abbott kfree(input_vec); 1972d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1973d7db7a88SGiovanni Cabiddu } 1974d7db7a88SGiovanni Cabiddu 1975d7db7a88SGiovanni Cabiddu ret = 0; 1976d7db7a88SGiovanni Cabiddu 1977d7db7a88SGiovanni Cabiddu out: 1978a9943a0aSGiovanni Cabiddu kfree(decomp_out); 1979eb095593SEric Biggers kfree(output); 1980d7db7a88SGiovanni Cabiddu return ret; 1981d7db7a88SGiovanni Cabiddu } 1982d7db7a88SGiovanni Cabiddu 1983b13b1e0cSEric Biggers static int test_cprng(struct crypto_rng *tfm, 1984b13b1e0cSEric Biggers const struct cprng_testvec *template, 19857647d6ceSJarod Wilson unsigned int tcount) 19867647d6ceSJarod Wilson { 19877647d6ceSJarod Wilson const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); 1988fa4ef8a6SFelipe Contreras int err = 0, i, j, seedsize; 19897647d6ceSJarod Wilson u8 *seed; 19907647d6ceSJarod Wilson char result[32]; 19917647d6ceSJarod Wilson 19927647d6ceSJarod Wilson seedsize = crypto_rng_seedsize(tfm); 19937647d6ceSJarod Wilson 19947647d6ceSJarod Wilson seed = kmalloc(seedsize, GFP_KERNEL); 19957647d6ceSJarod Wilson if (!seed) { 19967647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to allocate seed space " 19977647d6ceSJarod Wilson "for %s\n", algo); 19987647d6ceSJarod Wilson return -ENOMEM; 19997647d6ceSJarod Wilson } 20007647d6ceSJarod Wilson 20017647d6ceSJarod Wilson for (i = 0; i < tcount; i++) { 20027647d6ceSJarod Wilson memset(result, 0, 32); 20037647d6ceSJarod Wilson 20047647d6ceSJarod Wilson memcpy(seed, template[i].v, template[i].vlen); 20057647d6ceSJarod Wilson memcpy(seed + template[i].vlen, template[i].key, 20067647d6ceSJarod Wilson template[i].klen); 20077647d6ceSJarod Wilson memcpy(seed + template[i].vlen + template[i].klen, 20087647d6ceSJarod Wilson template[i].dt, template[i].dtlen); 20097647d6ceSJarod Wilson 20107647d6ceSJarod Wilson err = crypto_rng_reset(tfm, seed, seedsize); 20117647d6ceSJarod Wilson if (err) { 20127647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to reset rng " 20137647d6ceSJarod Wilson "for %s\n", algo); 20147647d6ceSJarod Wilson goto out; 20157647d6ceSJarod Wilson } 20167647d6ceSJarod Wilson 20177647d6ceSJarod Wilson for (j = 0; j < template[i].loops; j++) { 20187647d6ceSJarod Wilson err = crypto_rng_get_bytes(tfm, result, 20197647d6ceSJarod Wilson template[i].rlen); 202019e60e13SStephan Mueller if (err < 0) { 20217647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to obtain " 20227647d6ceSJarod Wilson "the correct amount of random data for " 202319e60e13SStephan Mueller "%s (requested %d)\n", algo, 202419e60e13SStephan Mueller template[i].rlen); 20257647d6ceSJarod Wilson goto out; 20267647d6ceSJarod Wilson } 20277647d6ceSJarod Wilson } 20287647d6ceSJarod Wilson 20297647d6ceSJarod Wilson err = memcmp(result, template[i].result, 20307647d6ceSJarod Wilson template[i].rlen); 20317647d6ceSJarod Wilson if (err) { 20327647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Test %d failed for %s\n", 20337647d6ceSJarod Wilson i, algo); 20347647d6ceSJarod Wilson hexdump(result, template[i].rlen); 20357647d6ceSJarod Wilson err = -EINVAL; 20367647d6ceSJarod Wilson goto out; 20377647d6ceSJarod Wilson } 20387647d6ceSJarod Wilson } 20397647d6ceSJarod Wilson 20407647d6ceSJarod Wilson out: 20417647d6ceSJarod Wilson kfree(seed); 20427647d6ceSJarod Wilson return err; 20437647d6ceSJarod Wilson } 20447647d6ceSJarod Wilson 2045da7f033dSHerbert Xu static int alg_test_cipher(const struct alg_test_desc *desc, 2046da7f033dSHerbert Xu const char *driver, u32 type, u32 mask) 2047da7f033dSHerbert Xu { 204892a4c9feSEric Biggers const struct cipher_test_suite *suite = &desc->suite.cipher; 20491aa4ecd9SHerbert Xu struct crypto_cipher *tfm; 205092a4c9feSEric Biggers int err; 2051da7f033dSHerbert Xu 2052eed93e0cSHerbert Xu tfm = crypto_alloc_cipher(driver, type, mask); 2053da7f033dSHerbert Xu if (IS_ERR(tfm)) { 2054da7f033dSHerbert Xu printk(KERN_ERR "alg: cipher: Failed to load transform for " 2055da7f033dSHerbert Xu "%s: %ld\n", driver, PTR_ERR(tfm)); 2056da7f033dSHerbert Xu return PTR_ERR(tfm); 2057da7f033dSHerbert Xu } 2058da7f033dSHerbert Xu 205992a4c9feSEric Biggers err = test_cipher(tfm, ENCRYPT, suite->vecs, suite->count); 206092a4c9feSEric Biggers if (!err) 206192a4c9feSEric Biggers err = test_cipher(tfm, DECRYPT, suite->vecs, suite->count); 2062da7f033dSHerbert Xu 20631aa4ecd9SHerbert Xu crypto_free_cipher(tfm); 20641aa4ecd9SHerbert Xu return err; 20651aa4ecd9SHerbert Xu } 20661aa4ecd9SHerbert Xu 2067da7f033dSHerbert Xu static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, 2068da7f033dSHerbert Xu u32 type, u32 mask) 2069da7f033dSHerbert Xu { 2070d7db7a88SGiovanni Cabiddu struct crypto_comp *comp; 2071d7db7a88SGiovanni Cabiddu struct crypto_acomp *acomp; 2072da7f033dSHerbert Xu int err; 2073d7db7a88SGiovanni Cabiddu u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK; 2074da7f033dSHerbert Xu 2075d7db7a88SGiovanni Cabiddu if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) { 2076d7db7a88SGiovanni Cabiddu acomp = crypto_alloc_acomp(driver, type, mask); 2077d7db7a88SGiovanni Cabiddu if (IS_ERR(acomp)) { 2078d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Failed to load transform for %s: %ld\n", 2079d7db7a88SGiovanni Cabiddu driver, PTR_ERR(acomp)); 2080d7db7a88SGiovanni Cabiddu return PTR_ERR(acomp); 2081d7db7a88SGiovanni Cabiddu } 2082d7db7a88SGiovanni Cabiddu err = test_acomp(acomp, desc->suite.comp.comp.vecs, 2083d7db7a88SGiovanni Cabiddu desc->suite.comp.decomp.vecs, 2084d7db7a88SGiovanni Cabiddu desc->suite.comp.comp.count, 2085d7db7a88SGiovanni Cabiddu desc->suite.comp.decomp.count); 2086d7db7a88SGiovanni Cabiddu crypto_free_acomp(acomp); 2087d7db7a88SGiovanni Cabiddu } else { 2088d7db7a88SGiovanni Cabiddu comp = crypto_alloc_comp(driver, type, mask); 2089d7db7a88SGiovanni Cabiddu if (IS_ERR(comp)) { 2090d7db7a88SGiovanni Cabiddu pr_err("alg: comp: Failed to load transform for %s: %ld\n", 2091d7db7a88SGiovanni Cabiddu driver, PTR_ERR(comp)); 2092d7db7a88SGiovanni Cabiddu return PTR_ERR(comp); 2093da7f033dSHerbert Xu } 2094da7f033dSHerbert Xu 2095d7db7a88SGiovanni Cabiddu err = test_comp(comp, desc->suite.comp.comp.vecs, 2096da7f033dSHerbert Xu desc->suite.comp.decomp.vecs, 2097da7f033dSHerbert Xu desc->suite.comp.comp.count, 2098da7f033dSHerbert Xu desc->suite.comp.decomp.count); 2099da7f033dSHerbert Xu 2100d7db7a88SGiovanni Cabiddu crypto_free_comp(comp); 2101d7db7a88SGiovanni Cabiddu } 2102da7f033dSHerbert Xu return err; 2103da7f033dSHerbert Xu } 2104da7f033dSHerbert Xu 21058e3ee85eSHerbert Xu static int alg_test_crc32c(const struct alg_test_desc *desc, 21068e3ee85eSHerbert Xu const char *driver, u32 type, u32 mask) 21078e3ee85eSHerbert Xu { 21088e3ee85eSHerbert Xu struct crypto_shash *tfm; 2109cb9dde88SEric Biggers __le32 val; 21108e3ee85eSHerbert Xu int err; 21118e3ee85eSHerbert Xu 21128e3ee85eSHerbert Xu err = alg_test_hash(desc, driver, type, mask); 21138e3ee85eSHerbert Xu if (err) 2114eb5e6730SEric Biggers return err; 21158e3ee85eSHerbert Xu 2116eed93e0cSHerbert Xu tfm = crypto_alloc_shash(driver, type, mask); 21178e3ee85eSHerbert Xu if (IS_ERR(tfm)) { 2118eb5e6730SEric Biggers if (PTR_ERR(tfm) == -ENOENT) { 2119eb5e6730SEric Biggers /* 2120eb5e6730SEric Biggers * This crc32c implementation is only available through 2121eb5e6730SEric Biggers * ahash API, not the shash API, so the remaining part 2122eb5e6730SEric Biggers * of the test is not applicable to it. 2123eb5e6730SEric Biggers */ 2124eb5e6730SEric Biggers return 0; 2125eb5e6730SEric Biggers } 21268e3ee85eSHerbert Xu printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: " 21278e3ee85eSHerbert Xu "%ld\n", driver, PTR_ERR(tfm)); 2128eb5e6730SEric Biggers return PTR_ERR(tfm); 21298e3ee85eSHerbert Xu } 21308e3ee85eSHerbert Xu 21318e3ee85eSHerbert Xu do { 21324c5c3024SJan-Simon Möller SHASH_DESC_ON_STACK(shash, tfm); 21334c5c3024SJan-Simon Möller u32 *ctx = (u32 *)shash_desc_ctx(shash); 21348e3ee85eSHerbert Xu 21354c5c3024SJan-Simon Möller shash->tfm = tfm; 21364c5c3024SJan-Simon Möller shash->flags = 0; 21378e3ee85eSHerbert Xu 2138cb9dde88SEric Biggers *ctx = 420553207; 21394c5c3024SJan-Simon Möller err = crypto_shash_final(shash, (u8 *)&val); 21408e3ee85eSHerbert Xu if (err) { 21418e3ee85eSHerbert Xu printk(KERN_ERR "alg: crc32c: Operation failed for " 21428e3ee85eSHerbert Xu "%s: %d\n", driver, err); 21438e3ee85eSHerbert Xu break; 21448e3ee85eSHerbert Xu } 21458e3ee85eSHerbert Xu 2146cb9dde88SEric Biggers if (val != cpu_to_le32(~420553207)) { 2147cb9dde88SEric Biggers pr_err("alg: crc32c: Test failed for %s: %u\n", 2148cb9dde88SEric Biggers driver, le32_to_cpu(val)); 21498e3ee85eSHerbert Xu err = -EINVAL; 21508e3ee85eSHerbert Xu } 21518e3ee85eSHerbert Xu } while (0); 21528e3ee85eSHerbert Xu 21538e3ee85eSHerbert Xu crypto_free_shash(tfm); 21548e3ee85eSHerbert Xu 21558e3ee85eSHerbert Xu return err; 21568e3ee85eSHerbert Xu } 21578e3ee85eSHerbert Xu 21587647d6ceSJarod Wilson static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, 21597647d6ceSJarod Wilson u32 type, u32 mask) 21607647d6ceSJarod Wilson { 21617647d6ceSJarod Wilson struct crypto_rng *rng; 21627647d6ceSJarod Wilson int err; 21637647d6ceSJarod Wilson 2164eed93e0cSHerbert Xu rng = crypto_alloc_rng(driver, type, mask); 21657647d6ceSJarod Wilson if (IS_ERR(rng)) { 21667647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " 21677647d6ceSJarod Wilson "%ld\n", driver, PTR_ERR(rng)); 21687647d6ceSJarod Wilson return PTR_ERR(rng); 21697647d6ceSJarod Wilson } 21707647d6ceSJarod Wilson 21717647d6ceSJarod Wilson err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count); 21727647d6ceSJarod Wilson 21737647d6ceSJarod Wilson crypto_free_rng(rng); 21747647d6ceSJarod Wilson 21757647d6ceSJarod Wilson return err; 21767647d6ceSJarod Wilson } 21777647d6ceSJarod Wilson 217864d1cdfbSStephan Mueller 2179b13b1e0cSEric Biggers static int drbg_cavs_test(const struct drbg_testvec *test, int pr, 218064d1cdfbSStephan Mueller const char *driver, u32 type, u32 mask) 218164d1cdfbSStephan Mueller { 218264d1cdfbSStephan Mueller int ret = -EAGAIN; 218364d1cdfbSStephan Mueller struct crypto_rng *drng; 218464d1cdfbSStephan Mueller struct drbg_test_data test_data; 218564d1cdfbSStephan Mueller struct drbg_string addtl, pers, testentropy; 218664d1cdfbSStephan Mueller unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL); 218764d1cdfbSStephan Mueller 218864d1cdfbSStephan Mueller if (!buf) 218964d1cdfbSStephan Mueller return -ENOMEM; 219064d1cdfbSStephan Mueller 2191eed93e0cSHerbert Xu drng = crypto_alloc_rng(driver, type, mask); 219264d1cdfbSStephan Mueller if (IS_ERR(drng)) { 219364d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " 219464d1cdfbSStephan Mueller "%s\n", driver); 219564d1cdfbSStephan Mueller kzfree(buf); 219664d1cdfbSStephan Mueller return -ENOMEM; 219764d1cdfbSStephan Mueller } 219864d1cdfbSStephan Mueller 219964d1cdfbSStephan Mueller test_data.testentropy = &testentropy; 220064d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entropy, test->entropylen); 220164d1cdfbSStephan Mueller drbg_string_fill(&pers, test->pers, test->perslen); 220264d1cdfbSStephan Mueller ret = crypto_drbg_reset_test(drng, &pers, &test_data); 220364d1cdfbSStephan Mueller if (ret) { 220464d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: Failed to reset rng\n"); 220564d1cdfbSStephan Mueller goto outbuf; 220664d1cdfbSStephan Mueller } 220764d1cdfbSStephan Mueller 220864d1cdfbSStephan Mueller drbg_string_fill(&addtl, test->addtla, test->addtllen); 220964d1cdfbSStephan Mueller if (pr) { 221064d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entpra, test->entprlen); 221164d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl_test(drng, 221264d1cdfbSStephan Mueller buf, test->expectedlen, &addtl, &test_data); 221364d1cdfbSStephan Mueller } else { 221464d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl(drng, 221564d1cdfbSStephan Mueller buf, test->expectedlen, &addtl); 221664d1cdfbSStephan Mueller } 221719e60e13SStephan Mueller if (ret < 0) { 221864d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not obtain random data for " 221964d1cdfbSStephan Mueller "driver %s\n", driver); 222064d1cdfbSStephan Mueller goto outbuf; 222164d1cdfbSStephan Mueller } 222264d1cdfbSStephan Mueller 222364d1cdfbSStephan Mueller drbg_string_fill(&addtl, test->addtlb, test->addtllen); 222464d1cdfbSStephan Mueller if (pr) { 222564d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entprb, test->entprlen); 222664d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl_test(drng, 222764d1cdfbSStephan Mueller buf, test->expectedlen, &addtl, &test_data); 222864d1cdfbSStephan Mueller } else { 222964d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl(drng, 223064d1cdfbSStephan Mueller buf, test->expectedlen, &addtl); 223164d1cdfbSStephan Mueller } 223219e60e13SStephan Mueller if (ret < 0) { 223364d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not obtain random data for " 223464d1cdfbSStephan Mueller "driver %s\n", driver); 223564d1cdfbSStephan Mueller goto outbuf; 223664d1cdfbSStephan Mueller } 223764d1cdfbSStephan Mueller 223864d1cdfbSStephan Mueller ret = memcmp(test->expected, buf, test->expectedlen); 223964d1cdfbSStephan Mueller 224064d1cdfbSStephan Mueller outbuf: 224164d1cdfbSStephan Mueller crypto_free_rng(drng); 224264d1cdfbSStephan Mueller kzfree(buf); 224364d1cdfbSStephan Mueller return ret; 224464d1cdfbSStephan Mueller } 224564d1cdfbSStephan Mueller 224664d1cdfbSStephan Mueller 224764d1cdfbSStephan Mueller static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, 224864d1cdfbSStephan Mueller u32 type, u32 mask) 224964d1cdfbSStephan Mueller { 225064d1cdfbSStephan Mueller int err = 0; 225164d1cdfbSStephan Mueller int pr = 0; 225264d1cdfbSStephan Mueller int i = 0; 2253b13b1e0cSEric Biggers const struct drbg_testvec *template = desc->suite.drbg.vecs; 225464d1cdfbSStephan Mueller unsigned int tcount = desc->suite.drbg.count; 225564d1cdfbSStephan Mueller 225664d1cdfbSStephan Mueller if (0 == memcmp(driver, "drbg_pr_", 8)) 225764d1cdfbSStephan Mueller pr = 1; 225864d1cdfbSStephan Mueller 225964d1cdfbSStephan Mueller for (i = 0; i < tcount; i++) { 226064d1cdfbSStephan Mueller err = drbg_cavs_test(&template[i], pr, driver, type, mask); 226164d1cdfbSStephan Mueller if (err) { 226264d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: Test %d failed for %s\n", 226364d1cdfbSStephan Mueller i, driver); 226464d1cdfbSStephan Mueller err = -EINVAL; 226564d1cdfbSStephan Mueller break; 226664d1cdfbSStephan Mueller } 226764d1cdfbSStephan Mueller } 226864d1cdfbSStephan Mueller return err; 226964d1cdfbSStephan Mueller 227064d1cdfbSStephan Mueller } 227164d1cdfbSStephan Mueller 2272b13b1e0cSEric Biggers static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, 2273802c7f1cSSalvatore Benedetto const char *alg) 2274802c7f1cSSalvatore Benedetto { 2275802c7f1cSSalvatore Benedetto struct kpp_request *req; 2276802c7f1cSSalvatore Benedetto void *input_buf = NULL; 2277802c7f1cSSalvatore Benedetto void *output_buf = NULL; 227847d3fd39STudor-Dan Ambarus void *a_public = NULL; 227947d3fd39STudor-Dan Ambarus void *a_ss = NULL; 228047d3fd39STudor-Dan Ambarus void *shared_secret = NULL; 22817f397136SGilad Ben-Yossef struct crypto_wait wait; 2282802c7f1cSSalvatore Benedetto unsigned int out_len_max; 2283802c7f1cSSalvatore Benedetto int err = -ENOMEM; 2284802c7f1cSSalvatore Benedetto struct scatterlist src, dst; 2285802c7f1cSSalvatore Benedetto 2286802c7f1cSSalvatore Benedetto req = kpp_request_alloc(tfm, GFP_KERNEL); 2287802c7f1cSSalvatore Benedetto if (!req) 2288802c7f1cSSalvatore Benedetto return err; 2289802c7f1cSSalvatore Benedetto 22907f397136SGilad Ben-Yossef crypto_init_wait(&wait); 2291802c7f1cSSalvatore Benedetto 2292802c7f1cSSalvatore Benedetto err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size); 2293802c7f1cSSalvatore Benedetto if (err < 0) 2294802c7f1cSSalvatore Benedetto goto free_req; 2295802c7f1cSSalvatore Benedetto 2296802c7f1cSSalvatore Benedetto out_len_max = crypto_kpp_maxsize(tfm); 2297802c7f1cSSalvatore Benedetto output_buf = kzalloc(out_len_max, GFP_KERNEL); 2298802c7f1cSSalvatore Benedetto if (!output_buf) { 2299802c7f1cSSalvatore Benedetto err = -ENOMEM; 2300802c7f1cSSalvatore Benedetto goto free_req; 2301802c7f1cSSalvatore Benedetto } 2302802c7f1cSSalvatore Benedetto 2303802c7f1cSSalvatore Benedetto /* Use appropriate parameter as base */ 2304802c7f1cSSalvatore Benedetto kpp_request_set_input(req, NULL, 0); 2305802c7f1cSSalvatore Benedetto sg_init_one(&dst, output_buf, out_len_max); 2306802c7f1cSSalvatore Benedetto kpp_request_set_output(req, &dst, out_len_max); 2307802c7f1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 23087f397136SGilad Ben-Yossef crypto_req_done, &wait); 2309802c7f1cSSalvatore Benedetto 231047d3fd39STudor-Dan Ambarus /* Compute party A's public key */ 23117f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait); 2312802c7f1cSSalvatore Benedetto if (err) { 231347d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: generate public key test failed. err %d\n", 2314802c7f1cSSalvatore Benedetto alg, err); 2315802c7f1cSSalvatore Benedetto goto free_output; 2316802c7f1cSSalvatore Benedetto } 231747d3fd39STudor-Dan Ambarus 231847d3fd39STudor-Dan Ambarus if (vec->genkey) { 231947d3fd39STudor-Dan Ambarus /* Save party A's public key */ 2320e3d90e52SChristopher Diaz Riveros a_public = kmemdup(sg_virt(req->dst), out_len_max, GFP_KERNEL); 232147d3fd39STudor-Dan Ambarus if (!a_public) { 232247d3fd39STudor-Dan Ambarus err = -ENOMEM; 232347d3fd39STudor-Dan Ambarus goto free_output; 232447d3fd39STudor-Dan Ambarus } 232547d3fd39STudor-Dan Ambarus } else { 2326802c7f1cSSalvatore Benedetto /* Verify calculated public key */ 2327802c7f1cSSalvatore Benedetto if (memcmp(vec->expected_a_public, sg_virt(req->dst), 2328802c7f1cSSalvatore Benedetto vec->expected_a_public_size)) { 232947d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n", 2330802c7f1cSSalvatore Benedetto alg); 2331802c7f1cSSalvatore Benedetto err = -EINVAL; 2332802c7f1cSSalvatore Benedetto goto free_output; 2333802c7f1cSSalvatore Benedetto } 233447d3fd39STudor-Dan Ambarus } 2335802c7f1cSSalvatore Benedetto 2336802c7f1cSSalvatore Benedetto /* Calculate shared secret key by using counter part (b) public key. */ 2337e3d90e52SChristopher Diaz Riveros input_buf = kmemdup(vec->b_public, vec->b_public_size, GFP_KERNEL); 2338802c7f1cSSalvatore Benedetto if (!input_buf) { 2339802c7f1cSSalvatore Benedetto err = -ENOMEM; 2340802c7f1cSSalvatore Benedetto goto free_output; 2341802c7f1cSSalvatore Benedetto } 2342802c7f1cSSalvatore Benedetto 2343802c7f1cSSalvatore Benedetto sg_init_one(&src, input_buf, vec->b_public_size); 2344802c7f1cSSalvatore Benedetto sg_init_one(&dst, output_buf, out_len_max); 2345802c7f1cSSalvatore Benedetto kpp_request_set_input(req, &src, vec->b_public_size); 2346802c7f1cSSalvatore Benedetto kpp_request_set_output(req, &dst, out_len_max); 2347802c7f1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 23487f397136SGilad Ben-Yossef crypto_req_done, &wait); 23497f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait); 2350802c7f1cSSalvatore Benedetto if (err) { 235147d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n", 2352802c7f1cSSalvatore Benedetto alg, err); 2353802c7f1cSSalvatore Benedetto goto free_all; 2354802c7f1cSSalvatore Benedetto } 235547d3fd39STudor-Dan Ambarus 235647d3fd39STudor-Dan Ambarus if (vec->genkey) { 235747d3fd39STudor-Dan Ambarus /* Save the shared secret obtained by party A */ 2358e3d90e52SChristopher Diaz Riveros a_ss = kmemdup(sg_virt(req->dst), vec->expected_ss_size, GFP_KERNEL); 235947d3fd39STudor-Dan Ambarus if (!a_ss) { 236047d3fd39STudor-Dan Ambarus err = -ENOMEM; 236147d3fd39STudor-Dan Ambarus goto free_all; 236247d3fd39STudor-Dan Ambarus } 236347d3fd39STudor-Dan Ambarus 236447d3fd39STudor-Dan Ambarus /* 236547d3fd39STudor-Dan Ambarus * Calculate party B's shared secret by using party A's 236647d3fd39STudor-Dan Ambarus * public key. 236747d3fd39STudor-Dan Ambarus */ 236847d3fd39STudor-Dan Ambarus err = crypto_kpp_set_secret(tfm, vec->b_secret, 236947d3fd39STudor-Dan Ambarus vec->b_secret_size); 237047d3fd39STudor-Dan Ambarus if (err < 0) 237147d3fd39STudor-Dan Ambarus goto free_all; 237247d3fd39STudor-Dan Ambarus 237347d3fd39STudor-Dan Ambarus sg_init_one(&src, a_public, vec->expected_a_public_size); 237447d3fd39STudor-Dan Ambarus sg_init_one(&dst, output_buf, out_len_max); 237547d3fd39STudor-Dan Ambarus kpp_request_set_input(req, &src, vec->expected_a_public_size); 237647d3fd39STudor-Dan Ambarus kpp_request_set_output(req, &dst, out_len_max); 237747d3fd39STudor-Dan Ambarus kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 23787f397136SGilad Ben-Yossef crypto_req_done, &wait); 23797f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), 23807f397136SGilad Ben-Yossef &wait); 238147d3fd39STudor-Dan Ambarus if (err) { 238247d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", 238347d3fd39STudor-Dan Ambarus alg, err); 238447d3fd39STudor-Dan Ambarus goto free_all; 238547d3fd39STudor-Dan Ambarus } 238647d3fd39STudor-Dan Ambarus 238747d3fd39STudor-Dan Ambarus shared_secret = a_ss; 238847d3fd39STudor-Dan Ambarus } else { 238947d3fd39STudor-Dan Ambarus shared_secret = (void *)vec->expected_ss; 239047d3fd39STudor-Dan Ambarus } 239147d3fd39STudor-Dan Ambarus 2392802c7f1cSSalvatore Benedetto /* 2393802c7f1cSSalvatore Benedetto * verify shared secret from which the user will derive 2394802c7f1cSSalvatore Benedetto * secret key by executing whatever hash it has chosen 2395802c7f1cSSalvatore Benedetto */ 239647d3fd39STudor-Dan Ambarus if (memcmp(shared_secret, sg_virt(req->dst), 2397802c7f1cSSalvatore Benedetto vec->expected_ss_size)) { 2398802c7f1cSSalvatore Benedetto pr_err("alg: %s: compute shared secret test failed. Invalid output\n", 2399802c7f1cSSalvatore Benedetto alg); 2400802c7f1cSSalvatore Benedetto err = -EINVAL; 2401802c7f1cSSalvatore Benedetto } 2402802c7f1cSSalvatore Benedetto 2403802c7f1cSSalvatore Benedetto free_all: 240447d3fd39STudor-Dan Ambarus kfree(a_ss); 2405802c7f1cSSalvatore Benedetto kfree(input_buf); 2406802c7f1cSSalvatore Benedetto free_output: 240747d3fd39STudor-Dan Ambarus kfree(a_public); 2408802c7f1cSSalvatore Benedetto kfree(output_buf); 2409802c7f1cSSalvatore Benedetto free_req: 2410802c7f1cSSalvatore Benedetto kpp_request_free(req); 2411802c7f1cSSalvatore Benedetto return err; 2412802c7f1cSSalvatore Benedetto } 2413802c7f1cSSalvatore Benedetto 2414802c7f1cSSalvatore Benedetto static int test_kpp(struct crypto_kpp *tfm, const char *alg, 2415b13b1e0cSEric Biggers const struct kpp_testvec *vecs, unsigned int tcount) 2416802c7f1cSSalvatore Benedetto { 2417802c7f1cSSalvatore Benedetto int ret, i; 2418802c7f1cSSalvatore Benedetto 2419802c7f1cSSalvatore Benedetto for (i = 0; i < tcount; i++) { 2420802c7f1cSSalvatore Benedetto ret = do_test_kpp(tfm, vecs++, alg); 2421802c7f1cSSalvatore Benedetto if (ret) { 2422802c7f1cSSalvatore Benedetto pr_err("alg: %s: test failed on vector %d, err=%d\n", 2423802c7f1cSSalvatore Benedetto alg, i + 1, ret); 2424802c7f1cSSalvatore Benedetto return ret; 2425802c7f1cSSalvatore Benedetto } 2426802c7f1cSSalvatore Benedetto } 2427802c7f1cSSalvatore Benedetto return 0; 2428802c7f1cSSalvatore Benedetto } 2429802c7f1cSSalvatore Benedetto 2430802c7f1cSSalvatore Benedetto static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, 2431802c7f1cSSalvatore Benedetto u32 type, u32 mask) 2432802c7f1cSSalvatore Benedetto { 2433802c7f1cSSalvatore Benedetto struct crypto_kpp *tfm; 2434802c7f1cSSalvatore Benedetto int err = 0; 2435802c7f1cSSalvatore Benedetto 2436eed93e0cSHerbert Xu tfm = crypto_alloc_kpp(driver, type, mask); 2437802c7f1cSSalvatore Benedetto if (IS_ERR(tfm)) { 2438802c7f1cSSalvatore Benedetto pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", 2439802c7f1cSSalvatore Benedetto driver, PTR_ERR(tfm)); 2440802c7f1cSSalvatore Benedetto return PTR_ERR(tfm); 2441802c7f1cSSalvatore Benedetto } 2442802c7f1cSSalvatore Benedetto if (desc->suite.kpp.vecs) 2443802c7f1cSSalvatore Benedetto err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs, 2444802c7f1cSSalvatore Benedetto desc->suite.kpp.count); 2445802c7f1cSSalvatore Benedetto 2446802c7f1cSSalvatore Benedetto crypto_free_kpp(tfm); 2447802c7f1cSSalvatore Benedetto return err; 2448802c7f1cSSalvatore Benedetto } 2449802c7f1cSSalvatore Benedetto 245050d2b643SHerbert Xu static int test_akcipher_one(struct crypto_akcipher *tfm, 2451b13b1e0cSEric Biggers const struct akcipher_testvec *vecs) 2452946cc463STadeusz Struk { 2453df27b26fSHerbert Xu char *xbuf[XBUFSIZE]; 2454946cc463STadeusz Struk struct akcipher_request *req; 2455946cc463STadeusz Struk void *outbuf_enc = NULL; 2456946cc463STadeusz Struk void *outbuf_dec = NULL; 24577f397136SGilad Ben-Yossef struct crypto_wait wait; 2458946cc463STadeusz Struk unsigned int out_len_max, out_len = 0; 2459946cc463STadeusz Struk int err = -ENOMEM; 246022287b0bSTadeusz Struk struct scatterlist src, dst, src_tab[2]; 24610507de94SVitaly Chikunov const char *m, *c; 24620507de94SVitaly Chikunov unsigned int m_size, c_size; 24630507de94SVitaly Chikunov const char *op; 2464946cc463STadeusz Struk 2465df27b26fSHerbert Xu if (testmgr_alloc_buf(xbuf)) 2466df27b26fSHerbert Xu return err; 2467df27b26fSHerbert Xu 2468946cc463STadeusz Struk req = akcipher_request_alloc(tfm, GFP_KERNEL); 2469946cc463STadeusz Struk if (!req) 2470df27b26fSHerbert Xu goto free_xbuf; 2471946cc463STadeusz Struk 24727f397136SGilad Ben-Yossef crypto_init_wait(&wait); 247322287b0bSTadeusz Struk 247422287b0bSTadeusz Struk if (vecs->public_key_vec) 247522287b0bSTadeusz Struk err = crypto_akcipher_set_pub_key(tfm, vecs->key, 247622287b0bSTadeusz Struk vecs->key_len); 247722287b0bSTadeusz Struk else 247822287b0bSTadeusz Struk err = crypto_akcipher_set_priv_key(tfm, vecs->key, 247922287b0bSTadeusz Struk vecs->key_len); 2480946cc463STadeusz Struk if (err) 2481946cc463STadeusz Struk goto free_req; 2482946cc463STadeusz Struk 248357763f5eSSalvatore Benedetto err = -ENOMEM; 248422287b0bSTadeusz Struk out_len_max = crypto_akcipher_maxsize(tfm); 24850507de94SVitaly Chikunov 24860507de94SVitaly Chikunov /* 24870507de94SVitaly Chikunov * First run test which do not require a private key, such as 24880507de94SVitaly Chikunov * encrypt or verify. 24890507de94SVitaly Chikunov */ 2490946cc463STadeusz Struk outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); 2491946cc463STadeusz Struk if (!outbuf_enc) 2492946cc463STadeusz Struk goto free_req; 2493946cc463STadeusz Struk 24940507de94SVitaly Chikunov if (!vecs->siggen_sigver_test) { 24950507de94SVitaly Chikunov m = vecs->m; 24960507de94SVitaly Chikunov m_size = vecs->m_size; 24970507de94SVitaly Chikunov c = vecs->c; 24980507de94SVitaly Chikunov c_size = vecs->c_size; 24990507de94SVitaly Chikunov op = "encrypt"; 25000507de94SVitaly Chikunov } else { 25010507de94SVitaly Chikunov /* Swap args so we could keep plaintext (digest) 25020507de94SVitaly Chikunov * in vecs->m, and cooked signature in vecs->c. 25030507de94SVitaly Chikunov */ 25040507de94SVitaly Chikunov m = vecs->c; /* signature */ 25050507de94SVitaly Chikunov m_size = vecs->c_size; 25060507de94SVitaly Chikunov c = vecs->m; /* digest */ 25070507de94SVitaly Chikunov c_size = vecs->m_size; 25080507de94SVitaly Chikunov op = "verify"; 25090507de94SVitaly Chikunov } 2510df27b26fSHerbert Xu 25110507de94SVitaly Chikunov if (WARN_ON(m_size > PAGE_SIZE)) 25120507de94SVitaly Chikunov goto free_all; 25130507de94SVitaly Chikunov memcpy(xbuf[0], m, m_size); 2514df27b26fSHerbert Xu 251522287b0bSTadeusz Struk sg_init_table(src_tab, 2); 2516df27b26fSHerbert Xu sg_set_buf(&src_tab[0], xbuf[0], 8); 25170507de94SVitaly Chikunov sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8); 251822287b0bSTadeusz Struk sg_init_one(&dst, outbuf_enc, out_len_max); 25190507de94SVitaly Chikunov akcipher_request_set_crypt(req, src_tab, &dst, m_size, 252022287b0bSTadeusz Struk out_len_max); 2521946cc463STadeusz Struk akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 25227f397136SGilad Ben-Yossef crypto_req_done, &wait); 2523946cc463STadeusz Struk 25247f397136SGilad Ben-Yossef err = crypto_wait_req(vecs->siggen_sigver_test ? 25250507de94SVitaly Chikunov /* Run asymmetric signature verification */ 25260507de94SVitaly Chikunov crypto_akcipher_verify(req) : 25271207107cSStephan Mueller /* Run asymmetric encrypt */ 25287f397136SGilad Ben-Yossef crypto_akcipher_encrypt(req), &wait); 2529946cc463STadeusz Struk if (err) { 25300507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 2531946cc463STadeusz Struk goto free_all; 2532946cc463STadeusz Struk } 25330507de94SVitaly Chikunov if (req->dst_len != c_size) { 25340507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output len\n", 25350507de94SVitaly Chikunov op); 2536946cc463STadeusz Struk err = -EINVAL; 2537946cc463STadeusz Struk goto free_all; 2538946cc463STadeusz Struk } 2539946cc463STadeusz Struk /* verify that encrypted message is equal to expected */ 25400507de94SVitaly Chikunov if (memcmp(c, outbuf_enc, c_size)) { 25410507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 25420507de94SVitaly Chikunov hexdump(outbuf_enc, c_size); 2543946cc463STadeusz Struk err = -EINVAL; 2544946cc463STadeusz Struk goto free_all; 2545946cc463STadeusz Struk } 25460507de94SVitaly Chikunov 25470507de94SVitaly Chikunov /* 25480507de94SVitaly Chikunov * Don't invoke (decrypt or sign) test which require a private key 25490507de94SVitaly Chikunov * for vectors with only a public key. 25500507de94SVitaly Chikunov */ 2551946cc463STadeusz Struk if (vecs->public_key_vec) { 2552946cc463STadeusz Struk err = 0; 2553946cc463STadeusz Struk goto free_all; 2554946cc463STadeusz Struk } 2555946cc463STadeusz Struk outbuf_dec = kzalloc(out_len_max, GFP_KERNEL); 2556946cc463STadeusz Struk if (!outbuf_dec) { 2557946cc463STadeusz Struk err = -ENOMEM; 2558946cc463STadeusz Struk goto free_all; 2559946cc463STadeusz Struk } 2560df27b26fSHerbert Xu 25610507de94SVitaly Chikunov op = vecs->siggen_sigver_test ? "sign" : "decrypt"; 25620507de94SVitaly Chikunov if (WARN_ON(c_size > PAGE_SIZE)) 2563df27b26fSHerbert Xu goto free_all; 25640507de94SVitaly Chikunov memcpy(xbuf[0], c, c_size); 2565df27b26fSHerbert Xu 25660507de94SVitaly Chikunov sg_init_one(&src, xbuf[0], c_size); 256722287b0bSTadeusz Struk sg_init_one(&dst, outbuf_dec, out_len_max); 25687f397136SGilad Ben-Yossef crypto_init_wait(&wait); 25690507de94SVitaly Chikunov akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max); 2570946cc463STadeusz Struk 25717f397136SGilad Ben-Yossef err = crypto_wait_req(vecs->siggen_sigver_test ? 25720507de94SVitaly Chikunov /* Run asymmetric signature generation */ 25730507de94SVitaly Chikunov crypto_akcipher_sign(req) : 25741207107cSStephan Mueller /* Run asymmetric decrypt */ 25757f397136SGilad Ben-Yossef crypto_akcipher_decrypt(req), &wait); 2576946cc463STadeusz Struk if (err) { 25770507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 2578946cc463STadeusz Struk goto free_all; 2579946cc463STadeusz Struk } 2580946cc463STadeusz Struk out_len = req->dst_len; 25810507de94SVitaly Chikunov if (out_len < m_size) { 25820507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output len %u\n", 25830507de94SVitaly Chikunov op, out_len); 2584946cc463STadeusz Struk err = -EINVAL; 2585946cc463STadeusz Struk goto free_all; 2586946cc463STadeusz Struk } 2587946cc463STadeusz Struk /* verify that decrypted message is equal to the original msg */ 25880507de94SVitaly Chikunov if (memchr_inv(outbuf_dec, 0, out_len - m_size) || 25890507de94SVitaly Chikunov memcmp(m, outbuf_dec + out_len - m_size, m_size)) { 25900507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 259150d2b643SHerbert Xu hexdump(outbuf_dec, out_len); 2592946cc463STadeusz Struk err = -EINVAL; 2593946cc463STadeusz Struk } 2594946cc463STadeusz Struk free_all: 2595946cc463STadeusz Struk kfree(outbuf_dec); 2596946cc463STadeusz Struk kfree(outbuf_enc); 2597946cc463STadeusz Struk free_req: 2598946cc463STadeusz Struk akcipher_request_free(req); 2599df27b26fSHerbert Xu free_xbuf: 2600df27b26fSHerbert Xu testmgr_free_buf(xbuf); 2601946cc463STadeusz Struk return err; 2602946cc463STadeusz Struk } 2603946cc463STadeusz Struk 260450d2b643SHerbert Xu static int test_akcipher(struct crypto_akcipher *tfm, const char *alg, 2605b13b1e0cSEric Biggers const struct akcipher_testvec *vecs, 2606b13b1e0cSEric Biggers unsigned int tcount) 2607946cc463STadeusz Struk { 260815226e48SHerbert Xu const char *algo = 260915226e48SHerbert Xu crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm)); 2610946cc463STadeusz Struk int ret, i; 2611946cc463STadeusz Struk 2612946cc463STadeusz Struk for (i = 0; i < tcount; i++) { 261350d2b643SHerbert Xu ret = test_akcipher_one(tfm, vecs++); 261450d2b643SHerbert Xu if (!ret) 261550d2b643SHerbert Xu continue; 261650d2b643SHerbert Xu 261715226e48SHerbert Xu pr_err("alg: akcipher: test %d failed for %s, err=%d\n", 261815226e48SHerbert Xu i + 1, algo, ret); 2619946cc463STadeusz Struk return ret; 2620946cc463STadeusz Struk } 2621946cc463STadeusz Struk return 0; 2622946cc463STadeusz Struk } 2623946cc463STadeusz Struk 2624946cc463STadeusz Struk static int alg_test_akcipher(const struct alg_test_desc *desc, 2625946cc463STadeusz Struk const char *driver, u32 type, u32 mask) 2626946cc463STadeusz Struk { 2627946cc463STadeusz Struk struct crypto_akcipher *tfm; 2628946cc463STadeusz Struk int err = 0; 2629946cc463STadeusz Struk 2630eed93e0cSHerbert Xu tfm = crypto_alloc_akcipher(driver, type, mask); 2631946cc463STadeusz Struk if (IS_ERR(tfm)) { 2632946cc463STadeusz Struk pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", 2633946cc463STadeusz Struk driver, PTR_ERR(tfm)); 2634946cc463STadeusz Struk return PTR_ERR(tfm); 2635946cc463STadeusz Struk } 2636946cc463STadeusz Struk if (desc->suite.akcipher.vecs) 2637946cc463STadeusz Struk err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs, 2638946cc463STadeusz Struk desc->suite.akcipher.count); 2639946cc463STadeusz Struk 2640946cc463STadeusz Struk crypto_free_akcipher(tfm); 2641946cc463STadeusz Struk return err; 2642946cc463STadeusz Struk } 2643946cc463STadeusz Struk 2644863b557aSYouquan, Song static int alg_test_null(const struct alg_test_desc *desc, 2645863b557aSYouquan, Song const char *driver, u32 type, u32 mask) 2646863b557aSYouquan, Song { 2647863b557aSYouquan, Song return 0; 2648863b557aSYouquan, Song } 2649863b557aSYouquan, Song 265021c8e720SArd Biesheuvel #define __VECS(tv) { .vecs = tv, .count = ARRAY_SIZE(tv) } 265121c8e720SArd Biesheuvel 2652da7f033dSHerbert Xu /* Please keep this list sorted by algorithm name. */ 2653da7f033dSHerbert Xu static const struct alg_test_desc alg_test_descs[] = { 2654da7f033dSHerbert Xu { 2655059c2a4dSEric Biggers .alg = "adiantum(xchacha12,aes)", 2656059c2a4dSEric Biggers .test = alg_test_skcipher, 2657059c2a4dSEric Biggers .suite = { 2658059c2a4dSEric Biggers .cipher = __VECS(adiantum_xchacha12_aes_tv_template) 2659059c2a4dSEric Biggers }, 2660059c2a4dSEric Biggers }, { 2661059c2a4dSEric Biggers .alg = "adiantum(xchacha20,aes)", 2662059c2a4dSEric Biggers .test = alg_test_skcipher, 2663059c2a4dSEric Biggers .suite = { 2664059c2a4dSEric Biggers .cipher = __VECS(adiantum_xchacha20_aes_tv_template) 2665059c2a4dSEric Biggers }, 2666059c2a4dSEric Biggers }, { 2667b87dc203SOndrej Mosnacek .alg = "aegis128", 2668b87dc203SOndrej Mosnacek .test = alg_test_aead, 2669b87dc203SOndrej Mosnacek .suite = { 2670a0d608eeSEric Biggers .aead = __VECS(aegis128_tv_template) 2671b87dc203SOndrej Mosnacek } 2672b87dc203SOndrej Mosnacek }, { 2673b87dc203SOndrej Mosnacek .alg = "aegis128l", 2674b87dc203SOndrej Mosnacek .test = alg_test_aead, 2675b87dc203SOndrej Mosnacek .suite = { 2676a0d608eeSEric Biggers .aead = __VECS(aegis128l_tv_template) 2677b87dc203SOndrej Mosnacek } 2678b87dc203SOndrej Mosnacek }, { 2679b87dc203SOndrej Mosnacek .alg = "aegis256", 2680b87dc203SOndrej Mosnacek .test = alg_test_aead, 2681b87dc203SOndrej Mosnacek .suite = { 2682a0d608eeSEric Biggers .aead = __VECS(aegis256_tv_template) 2683b87dc203SOndrej Mosnacek } 2684b87dc203SOndrej Mosnacek }, { 2685e08ca2daSJarod Wilson .alg = "ansi_cprng", 2686e08ca2daSJarod Wilson .test = alg_test_cprng, 2687e08ca2daSJarod Wilson .suite = { 268821c8e720SArd Biesheuvel .cprng = __VECS(ansi_cprng_aes_tv_template) 2689e08ca2daSJarod Wilson } 2690e08ca2daSJarod Wilson }, { 2691bca4feb0SHoria Geanta .alg = "authenc(hmac(md5),ecb(cipher_null))", 2692bca4feb0SHoria Geanta .test = alg_test_aead, 2693bca4feb0SHoria Geanta .suite = { 2694a0d608eeSEric Biggers .aead = __VECS(hmac_md5_ecb_cipher_null_tv_template) 2695bca4feb0SHoria Geanta } 2696bca4feb0SHoria Geanta }, { 2697a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(aes))", 2698e46e9a46SHoria Geanta .test = alg_test_aead, 2699bcf741cbSHerbert Xu .fips_allowed = 1, 2700e46e9a46SHoria Geanta .suite = { 2701a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_aes_cbc_tv_temp) 27025208ed2cSNitesh Lal } 27035208ed2cSNitesh Lal }, { 2704a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(des))", 27055208ed2cSNitesh Lal .test = alg_test_aead, 27065208ed2cSNitesh Lal .suite = { 2707a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_des_cbc_tv_temp) 27085208ed2cSNitesh Lal } 27095208ed2cSNitesh Lal }, { 2710a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(des3_ede))", 27115208ed2cSNitesh Lal .test = alg_test_aead, 2712ed1afac9SMarcus Meissner .fips_allowed = 1, 27135208ed2cSNitesh Lal .suite = { 2714a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp) 2715e46e9a46SHoria Geanta } 2716e46e9a46SHoria Geanta }, { 2717fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha1),ctr(aes))", 2718fb16abc2SMarcus Meissner .test = alg_test_null, 2719fb16abc2SMarcus Meissner .fips_allowed = 1, 2720fb16abc2SMarcus Meissner }, { 2721bca4feb0SHoria Geanta .alg = "authenc(hmac(sha1),ecb(cipher_null))", 2722bca4feb0SHoria Geanta .test = alg_test_aead, 2723bca4feb0SHoria Geanta .suite = { 2724a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_ecb_cipher_null_tv_temp) 27255208ed2cSNitesh Lal } 27265208ed2cSNitesh Lal }, { 27278888690eSMarcus Meissner .alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 27288888690eSMarcus Meissner .test = alg_test_null, 27298888690eSMarcus Meissner .fips_allowed = 1, 27308888690eSMarcus Meissner }, { 2731a4198fd4SHerbert Xu .alg = "authenc(hmac(sha224),cbc(des))", 27325208ed2cSNitesh Lal .test = alg_test_aead, 27335208ed2cSNitesh Lal .suite = { 2734a0d608eeSEric Biggers .aead = __VECS(hmac_sha224_des_cbc_tv_temp) 27355208ed2cSNitesh Lal } 27365208ed2cSNitesh Lal }, { 2737a4198fd4SHerbert Xu .alg = "authenc(hmac(sha224),cbc(des3_ede))", 27385208ed2cSNitesh Lal .test = alg_test_aead, 2739ed1afac9SMarcus Meissner .fips_allowed = 1, 27405208ed2cSNitesh Lal .suite = { 2741a0d608eeSEric Biggers .aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp) 2742bca4feb0SHoria Geanta } 2743bca4feb0SHoria Geanta }, { 2744a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(aes))", 2745e46e9a46SHoria Geanta .test = alg_test_aead, 2746ed1afac9SMarcus Meissner .fips_allowed = 1, 2747e46e9a46SHoria Geanta .suite = { 2748a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_aes_cbc_tv_temp) 27495208ed2cSNitesh Lal } 27505208ed2cSNitesh Lal }, { 2751a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(des))", 27525208ed2cSNitesh Lal .test = alg_test_aead, 27535208ed2cSNitesh Lal .suite = { 2754a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_des_cbc_tv_temp) 27555208ed2cSNitesh Lal } 27565208ed2cSNitesh Lal }, { 2757a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(des3_ede))", 27585208ed2cSNitesh Lal .test = alg_test_aead, 2759ed1afac9SMarcus Meissner .fips_allowed = 1, 27605208ed2cSNitesh Lal .suite = { 2761a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp) 27625208ed2cSNitesh Lal } 27635208ed2cSNitesh Lal }, { 2764fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha256),ctr(aes))", 2765fb16abc2SMarcus Meissner .test = alg_test_null, 2766fb16abc2SMarcus Meissner .fips_allowed = 1, 2767fb16abc2SMarcus Meissner }, { 27688888690eSMarcus Meissner .alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 27698888690eSMarcus Meissner .test = alg_test_null, 27708888690eSMarcus Meissner .fips_allowed = 1, 27718888690eSMarcus Meissner }, { 2772a4198fd4SHerbert Xu .alg = "authenc(hmac(sha384),cbc(des))", 27735208ed2cSNitesh Lal .test = alg_test_aead, 27745208ed2cSNitesh Lal .suite = { 2775a0d608eeSEric Biggers .aead = __VECS(hmac_sha384_des_cbc_tv_temp) 27765208ed2cSNitesh Lal } 27775208ed2cSNitesh Lal }, { 2778a4198fd4SHerbert Xu .alg = "authenc(hmac(sha384),cbc(des3_ede))", 27795208ed2cSNitesh Lal .test = alg_test_aead, 2780ed1afac9SMarcus Meissner .fips_allowed = 1, 27815208ed2cSNitesh Lal .suite = { 2782a0d608eeSEric Biggers .aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp) 2783e46e9a46SHoria Geanta } 2784e46e9a46SHoria Geanta }, { 2785fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha384),ctr(aes))", 2786fb16abc2SMarcus Meissner .test = alg_test_null, 2787fb16abc2SMarcus Meissner .fips_allowed = 1, 2788fb16abc2SMarcus Meissner }, { 27898888690eSMarcus Meissner .alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 27908888690eSMarcus Meissner .test = alg_test_null, 27918888690eSMarcus Meissner .fips_allowed = 1, 27928888690eSMarcus Meissner }, { 2793a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(aes))", 2794ed1afac9SMarcus Meissner .fips_allowed = 1, 2795e46e9a46SHoria Geanta .test = alg_test_aead, 2796e46e9a46SHoria Geanta .suite = { 2797a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_aes_cbc_tv_temp) 27985208ed2cSNitesh Lal } 27995208ed2cSNitesh Lal }, { 2800a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(des))", 28015208ed2cSNitesh Lal .test = alg_test_aead, 28025208ed2cSNitesh Lal .suite = { 2803a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_des_cbc_tv_temp) 28045208ed2cSNitesh Lal } 28055208ed2cSNitesh Lal }, { 2806a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(des3_ede))", 28075208ed2cSNitesh Lal .test = alg_test_aead, 2808ed1afac9SMarcus Meissner .fips_allowed = 1, 28095208ed2cSNitesh Lal .suite = { 2810a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp) 2811e46e9a46SHoria Geanta } 2812e46e9a46SHoria Geanta }, { 2813fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha512),ctr(aes))", 2814fb16abc2SMarcus Meissner .test = alg_test_null, 2815fb16abc2SMarcus Meissner .fips_allowed = 1, 2816fb16abc2SMarcus Meissner }, { 28178888690eSMarcus Meissner .alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 28188888690eSMarcus Meissner .test = alg_test_null, 28198888690eSMarcus Meissner .fips_allowed = 1, 28208888690eSMarcus Meissner }, { 2821da7f033dSHerbert Xu .alg = "cbc(aes)", 28221aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2823a1915d51SJarod Wilson .fips_allowed = 1, 2824da7f033dSHerbert Xu .suite = { 282592a4c9feSEric Biggers .cipher = __VECS(aes_cbc_tv_template) 282692a4c9feSEric Biggers }, 2827da7f033dSHerbert Xu }, { 2828da7f033dSHerbert Xu .alg = "cbc(anubis)", 28291aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2830da7f033dSHerbert Xu .suite = { 283192a4c9feSEric Biggers .cipher = __VECS(anubis_cbc_tv_template) 283292a4c9feSEric Biggers }, 2833da7f033dSHerbert Xu }, { 2834da7f033dSHerbert Xu .alg = "cbc(blowfish)", 28351aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2836da7f033dSHerbert Xu .suite = { 283792a4c9feSEric Biggers .cipher = __VECS(bf_cbc_tv_template) 283892a4c9feSEric Biggers }, 2839da7f033dSHerbert Xu }, { 2840da7f033dSHerbert Xu .alg = "cbc(camellia)", 28411aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2842da7f033dSHerbert Xu .suite = { 284392a4c9feSEric Biggers .cipher = __VECS(camellia_cbc_tv_template) 284492a4c9feSEric Biggers }, 2845da7f033dSHerbert Xu }, { 2846a2c58260SJohannes Goetzfried .alg = "cbc(cast5)", 2847a2c58260SJohannes Goetzfried .test = alg_test_skcipher, 2848a2c58260SJohannes Goetzfried .suite = { 284992a4c9feSEric Biggers .cipher = __VECS(cast5_cbc_tv_template) 285092a4c9feSEric Biggers }, 2851a2c58260SJohannes Goetzfried }, { 28529b8b0405SJohannes Goetzfried .alg = "cbc(cast6)", 28539b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 28549b8b0405SJohannes Goetzfried .suite = { 285592a4c9feSEric Biggers .cipher = __VECS(cast6_cbc_tv_template) 285692a4c9feSEric Biggers }, 28579b8b0405SJohannes Goetzfried }, { 2858da7f033dSHerbert Xu .alg = "cbc(des)", 28591aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2860da7f033dSHerbert Xu .suite = { 286192a4c9feSEric Biggers .cipher = __VECS(des_cbc_tv_template) 286292a4c9feSEric Biggers }, 2863da7f033dSHerbert Xu }, { 2864da7f033dSHerbert Xu .alg = "cbc(des3_ede)", 28651aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2866a1915d51SJarod Wilson .fips_allowed = 1, 2867da7f033dSHerbert Xu .suite = { 286892a4c9feSEric Biggers .cipher = __VECS(des3_ede_cbc_tv_template) 286992a4c9feSEric Biggers }, 2870da7f033dSHerbert Xu }, { 2871a794d8d8SGilad Ben-Yossef /* Same as cbc(aes) except the key is stored in 2872a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 2873a794d8d8SGilad Ben-Yossef */ 2874a794d8d8SGilad Ben-Yossef .alg = "cbc(paes)", 2875a794d8d8SGilad Ben-Yossef .test = alg_test_null, 2876a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 2877a794d8d8SGilad Ben-Yossef }, { 28789d25917dSJussi Kivilinna .alg = "cbc(serpent)", 28799d25917dSJussi Kivilinna .test = alg_test_skcipher, 28809d25917dSJussi Kivilinna .suite = { 288192a4c9feSEric Biggers .cipher = __VECS(serpent_cbc_tv_template) 288292a4c9feSEric Biggers }, 28839d25917dSJussi Kivilinna }, { 288495ba5973SGilad Ben-Yossef .alg = "cbc(sm4)", 288595ba5973SGilad Ben-Yossef .test = alg_test_skcipher, 288695ba5973SGilad Ben-Yossef .suite = { 288795ba5973SGilad Ben-Yossef .cipher = __VECS(sm4_cbc_tv_template) 288895ba5973SGilad Ben-Yossef } 288995ba5973SGilad Ben-Yossef }, { 2890da7f033dSHerbert Xu .alg = "cbc(twofish)", 28911aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2892da7f033dSHerbert Xu .suite = { 289392a4c9feSEric Biggers .cipher = __VECS(tf_cbc_tv_template) 289492a4c9feSEric Biggers }, 2895da7f033dSHerbert Xu }, { 2896092acf06SArd Biesheuvel .alg = "cbcmac(aes)", 2897092acf06SArd Biesheuvel .fips_allowed = 1, 2898092acf06SArd Biesheuvel .test = alg_test_hash, 2899092acf06SArd Biesheuvel .suite = { 2900092acf06SArd Biesheuvel .hash = __VECS(aes_cbcmac_tv_template) 2901092acf06SArd Biesheuvel } 2902092acf06SArd Biesheuvel }, { 2903da7f033dSHerbert Xu .alg = "ccm(aes)", 2904da7f033dSHerbert Xu .test = alg_test_aead, 2905a1915d51SJarod Wilson .fips_allowed = 1, 2906da7f033dSHerbert Xu .suite = { 2907a0d608eeSEric Biggers .aead = __VECS(aes_ccm_tv_template) 2908da7f033dSHerbert Xu } 2909da7f033dSHerbert Xu }, { 29107da66670SDmitry Eremin-Solenikov .alg = "cfb(aes)", 29117da66670SDmitry Eremin-Solenikov .test = alg_test_skcipher, 29127da66670SDmitry Eremin-Solenikov .fips_allowed = 1, 29137da66670SDmitry Eremin-Solenikov .suite = { 29147da66670SDmitry Eremin-Solenikov .cipher = __VECS(aes_cfb_tv_template) 29157da66670SDmitry Eremin-Solenikov }, 29167da66670SDmitry Eremin-Solenikov }, { 29173590ebf2SMartin Willi .alg = "chacha20", 29183590ebf2SMartin Willi .test = alg_test_skcipher, 29193590ebf2SMartin Willi .suite = { 292092a4c9feSEric Biggers .cipher = __VECS(chacha20_tv_template) 292192a4c9feSEric Biggers }, 29223590ebf2SMartin Willi }, { 292393b5e86aSJussi Kivilinna .alg = "cmac(aes)", 29248f183751SStephan Mueller .fips_allowed = 1, 292593b5e86aSJussi Kivilinna .test = alg_test_hash, 292693b5e86aSJussi Kivilinna .suite = { 292721c8e720SArd Biesheuvel .hash = __VECS(aes_cmac128_tv_template) 292893b5e86aSJussi Kivilinna } 292993b5e86aSJussi Kivilinna }, { 293093b5e86aSJussi Kivilinna .alg = "cmac(des3_ede)", 29318f183751SStephan Mueller .fips_allowed = 1, 293293b5e86aSJussi Kivilinna .test = alg_test_hash, 293393b5e86aSJussi Kivilinna .suite = { 293421c8e720SArd Biesheuvel .hash = __VECS(des3_ede_cmac64_tv_template) 293593b5e86aSJussi Kivilinna } 293693b5e86aSJussi Kivilinna }, { 2937e448370dSJussi Kivilinna .alg = "compress_null", 2938e448370dSJussi Kivilinna .test = alg_test_null, 2939e448370dSJussi Kivilinna }, { 2940ebb3472fSArd Biesheuvel .alg = "crc32", 2941ebb3472fSArd Biesheuvel .test = alg_test_hash, 2942a8a34416SMilan Broz .fips_allowed = 1, 2943ebb3472fSArd Biesheuvel .suite = { 294421c8e720SArd Biesheuvel .hash = __VECS(crc32_tv_template) 2945ebb3472fSArd Biesheuvel } 2946ebb3472fSArd Biesheuvel }, { 2947da7f033dSHerbert Xu .alg = "crc32c", 29488e3ee85eSHerbert Xu .test = alg_test_crc32c, 2949a1915d51SJarod Wilson .fips_allowed = 1, 2950da7f033dSHerbert Xu .suite = { 295121c8e720SArd Biesheuvel .hash = __VECS(crc32c_tv_template) 2952da7f033dSHerbert Xu } 2953da7f033dSHerbert Xu }, { 295468411521SHerbert Xu .alg = "crct10dif", 295568411521SHerbert Xu .test = alg_test_hash, 295668411521SHerbert Xu .fips_allowed = 1, 295768411521SHerbert Xu .suite = { 295821c8e720SArd Biesheuvel .hash = __VECS(crct10dif_tv_template) 295968411521SHerbert Xu } 296068411521SHerbert Xu }, { 2961f7cb80f2SJarod Wilson .alg = "ctr(aes)", 2962f7cb80f2SJarod Wilson .test = alg_test_skcipher, 2963a1915d51SJarod Wilson .fips_allowed = 1, 2964f7cb80f2SJarod Wilson .suite = { 296592a4c9feSEric Biggers .cipher = __VECS(aes_ctr_tv_template) 2966f7cb80f2SJarod Wilson } 2967f7cb80f2SJarod Wilson }, { 296885b63e34SJussi Kivilinna .alg = "ctr(blowfish)", 296985b63e34SJussi Kivilinna .test = alg_test_skcipher, 297085b63e34SJussi Kivilinna .suite = { 297192a4c9feSEric Biggers .cipher = __VECS(bf_ctr_tv_template) 297285b63e34SJussi Kivilinna } 297385b63e34SJussi Kivilinna }, { 29740840605eSJussi Kivilinna .alg = "ctr(camellia)", 29750840605eSJussi Kivilinna .test = alg_test_skcipher, 29760840605eSJussi Kivilinna .suite = { 297792a4c9feSEric Biggers .cipher = __VECS(camellia_ctr_tv_template) 29780840605eSJussi Kivilinna } 29790840605eSJussi Kivilinna }, { 2980a2c58260SJohannes Goetzfried .alg = "ctr(cast5)", 2981a2c58260SJohannes Goetzfried .test = alg_test_skcipher, 2982a2c58260SJohannes Goetzfried .suite = { 298392a4c9feSEric Biggers .cipher = __VECS(cast5_ctr_tv_template) 2984a2c58260SJohannes Goetzfried } 2985a2c58260SJohannes Goetzfried }, { 29869b8b0405SJohannes Goetzfried .alg = "ctr(cast6)", 29879b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 29889b8b0405SJohannes Goetzfried .suite = { 298992a4c9feSEric Biggers .cipher = __VECS(cast6_ctr_tv_template) 29909b8b0405SJohannes Goetzfried } 29919b8b0405SJohannes Goetzfried }, { 29928163fc30SJussi Kivilinna .alg = "ctr(des)", 29938163fc30SJussi Kivilinna .test = alg_test_skcipher, 29948163fc30SJussi Kivilinna .suite = { 299592a4c9feSEric Biggers .cipher = __VECS(des_ctr_tv_template) 29968163fc30SJussi Kivilinna } 29978163fc30SJussi Kivilinna }, { 2998e080b17aSJussi Kivilinna .alg = "ctr(des3_ede)", 2999e080b17aSJussi Kivilinna .test = alg_test_skcipher, 30000d8da104SMarcelo Cerri .fips_allowed = 1, 3001e080b17aSJussi Kivilinna .suite = { 300292a4c9feSEric Biggers .cipher = __VECS(des3_ede_ctr_tv_template) 3003e080b17aSJussi Kivilinna } 3004e080b17aSJussi Kivilinna }, { 3005a794d8d8SGilad Ben-Yossef /* Same as ctr(aes) except the key is stored in 3006a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 3007a794d8d8SGilad Ben-Yossef */ 3008a794d8d8SGilad Ben-Yossef .alg = "ctr(paes)", 3009a794d8d8SGilad Ben-Yossef .test = alg_test_null, 3010a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 3011a794d8d8SGilad Ben-Yossef }, { 30129d25917dSJussi Kivilinna .alg = "ctr(serpent)", 30139d25917dSJussi Kivilinna .test = alg_test_skcipher, 30149d25917dSJussi Kivilinna .suite = { 301592a4c9feSEric Biggers .cipher = __VECS(serpent_ctr_tv_template) 30169d25917dSJussi Kivilinna } 30179d25917dSJussi Kivilinna }, { 301895ba5973SGilad Ben-Yossef .alg = "ctr(sm4)", 301995ba5973SGilad Ben-Yossef .test = alg_test_skcipher, 302095ba5973SGilad Ben-Yossef .suite = { 302195ba5973SGilad Ben-Yossef .cipher = __VECS(sm4_ctr_tv_template) 302295ba5973SGilad Ben-Yossef } 302395ba5973SGilad Ben-Yossef }, { 3024573da620SJussi Kivilinna .alg = "ctr(twofish)", 3025573da620SJussi Kivilinna .test = alg_test_skcipher, 3026573da620SJussi Kivilinna .suite = { 302792a4c9feSEric Biggers .cipher = __VECS(tf_ctr_tv_template) 3028573da620SJussi Kivilinna } 3029573da620SJussi Kivilinna }, { 3030da7f033dSHerbert Xu .alg = "cts(cbc(aes))", 30311aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3032196ad604SGilad Ben-Yossef .fips_allowed = 1, 3033da7f033dSHerbert Xu .suite = { 303492a4c9feSEric Biggers .cipher = __VECS(cts_mode_tv_template) 3035da7f033dSHerbert Xu } 3036da7f033dSHerbert Xu }, { 3037da7f033dSHerbert Xu .alg = "deflate", 3038da7f033dSHerbert Xu .test = alg_test_comp, 30390818904dSMilan Broz .fips_allowed = 1, 3040da7f033dSHerbert Xu .suite = { 3041da7f033dSHerbert Xu .comp = { 304221c8e720SArd Biesheuvel .comp = __VECS(deflate_comp_tv_template), 304321c8e720SArd Biesheuvel .decomp = __VECS(deflate_decomp_tv_template) 3044da7f033dSHerbert Xu } 3045da7f033dSHerbert Xu } 3046da7f033dSHerbert Xu }, { 3047802c7f1cSSalvatore Benedetto .alg = "dh", 3048802c7f1cSSalvatore Benedetto .test = alg_test_kpp, 3049802c7f1cSSalvatore Benedetto .fips_allowed = 1, 3050802c7f1cSSalvatore Benedetto .suite = { 305121c8e720SArd Biesheuvel .kpp = __VECS(dh_tv_template) 3052802c7f1cSSalvatore Benedetto } 3053802c7f1cSSalvatore Benedetto }, { 3054e448370dSJussi Kivilinna .alg = "digest_null", 3055e448370dSJussi Kivilinna .test = alg_test_null, 3056e448370dSJussi Kivilinna }, { 305764d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes128", 305864d1cdfbSStephan Mueller .test = alg_test_drbg, 305964d1cdfbSStephan Mueller .fips_allowed = 1, 306064d1cdfbSStephan Mueller .suite = { 306121c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes128_tv_template) 306264d1cdfbSStephan Mueller } 306364d1cdfbSStephan Mueller }, { 306464d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes192", 306564d1cdfbSStephan Mueller .test = alg_test_drbg, 306664d1cdfbSStephan Mueller .fips_allowed = 1, 306764d1cdfbSStephan Mueller .suite = { 306821c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes192_tv_template) 306964d1cdfbSStephan Mueller } 307064d1cdfbSStephan Mueller }, { 307164d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes256", 307264d1cdfbSStephan Mueller .test = alg_test_drbg, 307364d1cdfbSStephan Mueller .fips_allowed = 1, 307464d1cdfbSStephan Mueller .suite = { 307521c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes256_tv_template) 307664d1cdfbSStephan Mueller } 307764d1cdfbSStephan Mueller }, { 307864d1cdfbSStephan Mueller /* 307964d1cdfbSStephan Mueller * There is no need to specifically test the DRBG with every 308064d1cdfbSStephan Mueller * backend cipher -- covered by drbg_nopr_hmac_sha256 test 308164d1cdfbSStephan Mueller */ 308264d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha1", 308364d1cdfbSStephan Mueller .fips_allowed = 1, 308464d1cdfbSStephan Mueller .test = alg_test_null, 308564d1cdfbSStephan Mueller }, { 308664d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha256", 308764d1cdfbSStephan Mueller .test = alg_test_drbg, 308864d1cdfbSStephan Mueller .fips_allowed = 1, 308964d1cdfbSStephan Mueller .suite = { 309021c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_hmac_sha256_tv_template) 309164d1cdfbSStephan Mueller } 309264d1cdfbSStephan Mueller }, { 309364d1cdfbSStephan Mueller /* covered by drbg_nopr_hmac_sha256 test */ 309464d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha384", 309564d1cdfbSStephan Mueller .fips_allowed = 1, 309664d1cdfbSStephan Mueller .test = alg_test_null, 309764d1cdfbSStephan Mueller }, { 309864d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha512", 309964d1cdfbSStephan Mueller .test = alg_test_null, 310064d1cdfbSStephan Mueller .fips_allowed = 1, 310164d1cdfbSStephan Mueller }, { 310264d1cdfbSStephan Mueller .alg = "drbg_nopr_sha1", 310364d1cdfbSStephan Mueller .fips_allowed = 1, 310464d1cdfbSStephan Mueller .test = alg_test_null, 310564d1cdfbSStephan Mueller }, { 310664d1cdfbSStephan Mueller .alg = "drbg_nopr_sha256", 310764d1cdfbSStephan Mueller .test = alg_test_drbg, 310864d1cdfbSStephan Mueller .fips_allowed = 1, 310964d1cdfbSStephan Mueller .suite = { 311021c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_sha256_tv_template) 311164d1cdfbSStephan Mueller } 311264d1cdfbSStephan Mueller }, { 311364d1cdfbSStephan Mueller /* covered by drbg_nopr_sha256 test */ 311464d1cdfbSStephan Mueller .alg = "drbg_nopr_sha384", 311564d1cdfbSStephan Mueller .fips_allowed = 1, 311664d1cdfbSStephan Mueller .test = alg_test_null, 311764d1cdfbSStephan Mueller }, { 311864d1cdfbSStephan Mueller .alg = "drbg_nopr_sha512", 311964d1cdfbSStephan Mueller .fips_allowed = 1, 312064d1cdfbSStephan Mueller .test = alg_test_null, 312164d1cdfbSStephan Mueller }, { 312264d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes128", 312364d1cdfbSStephan Mueller .test = alg_test_drbg, 312464d1cdfbSStephan Mueller .fips_allowed = 1, 312564d1cdfbSStephan Mueller .suite = { 312621c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_ctr_aes128_tv_template) 312764d1cdfbSStephan Mueller } 312864d1cdfbSStephan Mueller }, { 312964d1cdfbSStephan Mueller /* covered by drbg_pr_ctr_aes128 test */ 313064d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes192", 313164d1cdfbSStephan Mueller .fips_allowed = 1, 313264d1cdfbSStephan Mueller .test = alg_test_null, 313364d1cdfbSStephan Mueller }, { 313464d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes256", 313564d1cdfbSStephan Mueller .fips_allowed = 1, 313664d1cdfbSStephan Mueller .test = alg_test_null, 313764d1cdfbSStephan Mueller }, { 313864d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha1", 313964d1cdfbSStephan Mueller .fips_allowed = 1, 314064d1cdfbSStephan Mueller .test = alg_test_null, 314164d1cdfbSStephan Mueller }, { 314264d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha256", 314364d1cdfbSStephan Mueller .test = alg_test_drbg, 314464d1cdfbSStephan Mueller .fips_allowed = 1, 314564d1cdfbSStephan Mueller .suite = { 314621c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_hmac_sha256_tv_template) 314764d1cdfbSStephan Mueller } 314864d1cdfbSStephan Mueller }, { 314964d1cdfbSStephan Mueller /* covered by drbg_pr_hmac_sha256 test */ 315064d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha384", 315164d1cdfbSStephan Mueller .fips_allowed = 1, 315264d1cdfbSStephan Mueller .test = alg_test_null, 315364d1cdfbSStephan Mueller }, { 315464d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha512", 315564d1cdfbSStephan Mueller .test = alg_test_null, 315664d1cdfbSStephan Mueller .fips_allowed = 1, 315764d1cdfbSStephan Mueller }, { 315864d1cdfbSStephan Mueller .alg = "drbg_pr_sha1", 315964d1cdfbSStephan Mueller .fips_allowed = 1, 316064d1cdfbSStephan Mueller .test = alg_test_null, 316164d1cdfbSStephan Mueller }, { 316264d1cdfbSStephan Mueller .alg = "drbg_pr_sha256", 316364d1cdfbSStephan Mueller .test = alg_test_drbg, 316464d1cdfbSStephan Mueller .fips_allowed = 1, 316564d1cdfbSStephan Mueller .suite = { 316621c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_sha256_tv_template) 316764d1cdfbSStephan Mueller } 316864d1cdfbSStephan Mueller }, { 316964d1cdfbSStephan Mueller /* covered by drbg_pr_sha256 test */ 317064d1cdfbSStephan Mueller .alg = "drbg_pr_sha384", 317164d1cdfbSStephan Mueller .fips_allowed = 1, 317264d1cdfbSStephan Mueller .test = alg_test_null, 317364d1cdfbSStephan Mueller }, { 317464d1cdfbSStephan Mueller .alg = "drbg_pr_sha512", 317564d1cdfbSStephan Mueller .fips_allowed = 1, 317664d1cdfbSStephan Mueller .test = alg_test_null, 317764d1cdfbSStephan Mueller }, { 3178da7f033dSHerbert Xu .alg = "ecb(aes)", 31791aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3180a1915d51SJarod Wilson .fips_allowed = 1, 3181da7f033dSHerbert Xu .suite = { 318292a4c9feSEric Biggers .cipher = __VECS(aes_tv_template) 3183da7f033dSHerbert Xu } 3184da7f033dSHerbert Xu }, { 3185da7f033dSHerbert Xu .alg = "ecb(anubis)", 31861aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3187da7f033dSHerbert Xu .suite = { 318892a4c9feSEric Biggers .cipher = __VECS(anubis_tv_template) 3189da7f033dSHerbert Xu } 3190da7f033dSHerbert Xu }, { 3191da7f033dSHerbert Xu .alg = "ecb(arc4)", 31921aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3193da7f033dSHerbert Xu .suite = { 319492a4c9feSEric Biggers .cipher = __VECS(arc4_tv_template) 3195da7f033dSHerbert Xu } 3196da7f033dSHerbert Xu }, { 3197da7f033dSHerbert Xu .alg = "ecb(blowfish)", 31981aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3199da7f033dSHerbert Xu .suite = { 320092a4c9feSEric Biggers .cipher = __VECS(bf_tv_template) 3201da7f033dSHerbert Xu } 3202da7f033dSHerbert Xu }, { 3203da7f033dSHerbert Xu .alg = "ecb(camellia)", 32041aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3205da7f033dSHerbert Xu .suite = { 320692a4c9feSEric Biggers .cipher = __VECS(camellia_tv_template) 3207da7f033dSHerbert Xu } 3208da7f033dSHerbert Xu }, { 3209da7f033dSHerbert Xu .alg = "ecb(cast5)", 32101aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3211da7f033dSHerbert Xu .suite = { 321292a4c9feSEric Biggers .cipher = __VECS(cast5_tv_template) 3213da7f033dSHerbert Xu } 3214da7f033dSHerbert Xu }, { 3215da7f033dSHerbert Xu .alg = "ecb(cast6)", 32161aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3217da7f033dSHerbert Xu .suite = { 321892a4c9feSEric Biggers .cipher = __VECS(cast6_tv_template) 3219da7f033dSHerbert Xu } 3220da7f033dSHerbert Xu }, { 3221e448370dSJussi Kivilinna .alg = "ecb(cipher_null)", 3222e448370dSJussi Kivilinna .test = alg_test_null, 32236175ca2bSMilan Broz .fips_allowed = 1, 3224e448370dSJussi Kivilinna }, { 3225da7f033dSHerbert Xu .alg = "ecb(des)", 32261aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3227da7f033dSHerbert Xu .suite = { 322892a4c9feSEric Biggers .cipher = __VECS(des_tv_template) 3229da7f033dSHerbert Xu } 3230da7f033dSHerbert Xu }, { 3231da7f033dSHerbert Xu .alg = "ecb(des3_ede)", 32321aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3233a1915d51SJarod Wilson .fips_allowed = 1, 3234da7f033dSHerbert Xu .suite = { 323592a4c9feSEric Biggers .cipher = __VECS(des3_ede_tv_template) 3236da7f033dSHerbert Xu } 3237da7f033dSHerbert Xu }, { 323866e5bd00SJussi Kivilinna .alg = "ecb(fcrypt)", 323966e5bd00SJussi Kivilinna .test = alg_test_skcipher, 324066e5bd00SJussi Kivilinna .suite = { 324166e5bd00SJussi Kivilinna .cipher = { 324292a4c9feSEric Biggers .vecs = fcrypt_pcbc_tv_template, 324366e5bd00SJussi Kivilinna .count = 1 324466e5bd00SJussi Kivilinna } 324566e5bd00SJussi Kivilinna } 324666e5bd00SJussi Kivilinna }, { 3247da7f033dSHerbert Xu .alg = "ecb(khazad)", 32481aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3249da7f033dSHerbert Xu .suite = { 325092a4c9feSEric Biggers .cipher = __VECS(khazad_tv_template) 3251da7f033dSHerbert Xu } 3252da7f033dSHerbert Xu }, { 325315f47ce5SGilad Ben-Yossef /* Same as ecb(aes) except the key is stored in 325415f47ce5SGilad Ben-Yossef * hardware secure memory which we reference by index 325515f47ce5SGilad Ben-Yossef */ 325615f47ce5SGilad Ben-Yossef .alg = "ecb(paes)", 325715f47ce5SGilad Ben-Yossef .test = alg_test_null, 325815f47ce5SGilad Ben-Yossef .fips_allowed = 1, 325915f47ce5SGilad Ben-Yossef }, { 3260da7f033dSHerbert Xu .alg = "ecb(seed)", 32611aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3262da7f033dSHerbert Xu .suite = { 326392a4c9feSEric Biggers .cipher = __VECS(seed_tv_template) 3264da7f033dSHerbert Xu } 3265da7f033dSHerbert Xu }, { 3266da7f033dSHerbert Xu .alg = "ecb(serpent)", 32671aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3268da7f033dSHerbert Xu .suite = { 326992a4c9feSEric Biggers .cipher = __VECS(serpent_tv_template) 3270da7f033dSHerbert Xu } 3271da7f033dSHerbert Xu }, { 3272cd83a8a7SGilad Ben-Yossef .alg = "ecb(sm4)", 3273cd83a8a7SGilad Ben-Yossef .test = alg_test_skcipher, 3274cd83a8a7SGilad Ben-Yossef .suite = { 327592a4c9feSEric Biggers .cipher = __VECS(sm4_tv_template) 3276cd83a8a7SGilad Ben-Yossef } 3277cd83a8a7SGilad Ben-Yossef }, { 3278da7f033dSHerbert Xu .alg = "ecb(tea)", 32791aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3280da7f033dSHerbert Xu .suite = { 328192a4c9feSEric Biggers .cipher = __VECS(tea_tv_template) 3282da7f033dSHerbert Xu } 3283da7f033dSHerbert Xu }, { 3284da7f033dSHerbert Xu .alg = "ecb(tnepres)", 32851aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3286da7f033dSHerbert Xu .suite = { 328792a4c9feSEric Biggers .cipher = __VECS(tnepres_tv_template) 3288da7f033dSHerbert Xu } 3289da7f033dSHerbert Xu }, { 3290da7f033dSHerbert Xu .alg = "ecb(twofish)", 32911aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3292da7f033dSHerbert Xu .suite = { 329392a4c9feSEric Biggers .cipher = __VECS(tf_tv_template) 3294da7f033dSHerbert Xu } 3295da7f033dSHerbert Xu }, { 3296da7f033dSHerbert Xu .alg = "ecb(xeta)", 32971aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3298da7f033dSHerbert Xu .suite = { 329992a4c9feSEric Biggers .cipher = __VECS(xeta_tv_template) 3300da7f033dSHerbert Xu } 3301da7f033dSHerbert Xu }, { 3302da7f033dSHerbert Xu .alg = "ecb(xtea)", 33031aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3304da7f033dSHerbert Xu .suite = { 330592a4c9feSEric Biggers .cipher = __VECS(xtea_tv_template) 3306da7f033dSHerbert Xu } 3307da7f033dSHerbert Xu }, { 33083c4b2390SSalvatore Benedetto .alg = "ecdh", 33093c4b2390SSalvatore Benedetto .test = alg_test_kpp, 33103c4b2390SSalvatore Benedetto .fips_allowed = 1, 33113c4b2390SSalvatore Benedetto .suite = { 331221c8e720SArd Biesheuvel .kpp = __VECS(ecdh_tv_template) 33133c4b2390SSalvatore Benedetto } 33143c4b2390SSalvatore Benedetto }, { 3315da7f033dSHerbert Xu .alg = "gcm(aes)", 3316da7f033dSHerbert Xu .test = alg_test_aead, 3317a1915d51SJarod Wilson .fips_allowed = 1, 3318da7f033dSHerbert Xu .suite = { 3319a0d608eeSEric Biggers .aead = __VECS(aes_gcm_tv_template) 3320da7f033dSHerbert Xu } 3321da7f033dSHerbert Xu }, { 3322507069c9SYouquan, Song .alg = "ghash", 3323507069c9SYouquan, Song .test = alg_test_hash, 332418c0ebd2SJarod Wilson .fips_allowed = 1, 3325507069c9SYouquan, Song .suite = { 332621c8e720SArd Biesheuvel .hash = __VECS(ghash_tv_template) 3327507069c9SYouquan, Song } 3328507069c9SYouquan, Song }, { 3329da7f033dSHerbert Xu .alg = "hmac(md5)", 3330da7f033dSHerbert Xu .test = alg_test_hash, 3331da7f033dSHerbert Xu .suite = { 333221c8e720SArd Biesheuvel .hash = __VECS(hmac_md5_tv_template) 3333da7f033dSHerbert Xu } 3334da7f033dSHerbert Xu }, { 3335da7f033dSHerbert Xu .alg = "hmac(rmd128)", 3336da7f033dSHerbert Xu .test = alg_test_hash, 3337da7f033dSHerbert Xu .suite = { 333821c8e720SArd Biesheuvel .hash = __VECS(hmac_rmd128_tv_template) 3339da7f033dSHerbert Xu } 3340da7f033dSHerbert Xu }, { 3341da7f033dSHerbert Xu .alg = "hmac(rmd160)", 3342da7f033dSHerbert Xu .test = alg_test_hash, 3343da7f033dSHerbert Xu .suite = { 334421c8e720SArd Biesheuvel .hash = __VECS(hmac_rmd160_tv_template) 3345da7f033dSHerbert Xu } 3346da7f033dSHerbert Xu }, { 3347da7f033dSHerbert Xu .alg = "hmac(sha1)", 3348da7f033dSHerbert Xu .test = alg_test_hash, 3349a1915d51SJarod Wilson .fips_allowed = 1, 3350da7f033dSHerbert Xu .suite = { 335121c8e720SArd Biesheuvel .hash = __VECS(hmac_sha1_tv_template) 3352da7f033dSHerbert Xu } 3353da7f033dSHerbert Xu }, { 3354da7f033dSHerbert Xu .alg = "hmac(sha224)", 3355da7f033dSHerbert Xu .test = alg_test_hash, 3356a1915d51SJarod Wilson .fips_allowed = 1, 3357da7f033dSHerbert Xu .suite = { 335821c8e720SArd Biesheuvel .hash = __VECS(hmac_sha224_tv_template) 3359da7f033dSHerbert Xu } 3360da7f033dSHerbert Xu }, { 3361da7f033dSHerbert Xu .alg = "hmac(sha256)", 3362da7f033dSHerbert Xu .test = alg_test_hash, 3363a1915d51SJarod Wilson .fips_allowed = 1, 3364da7f033dSHerbert Xu .suite = { 336521c8e720SArd Biesheuvel .hash = __VECS(hmac_sha256_tv_template) 3366da7f033dSHerbert Xu } 3367da7f033dSHerbert Xu }, { 336898eca72fSraveendra padasalagi .alg = "hmac(sha3-224)", 336998eca72fSraveendra padasalagi .test = alg_test_hash, 337098eca72fSraveendra padasalagi .fips_allowed = 1, 337198eca72fSraveendra padasalagi .suite = { 337221c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_224_tv_template) 337398eca72fSraveendra padasalagi } 337498eca72fSraveendra padasalagi }, { 337598eca72fSraveendra padasalagi .alg = "hmac(sha3-256)", 337698eca72fSraveendra padasalagi .test = alg_test_hash, 337798eca72fSraveendra padasalagi .fips_allowed = 1, 337898eca72fSraveendra padasalagi .suite = { 337921c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_256_tv_template) 338098eca72fSraveendra padasalagi } 338198eca72fSraveendra padasalagi }, { 338298eca72fSraveendra padasalagi .alg = "hmac(sha3-384)", 338398eca72fSraveendra padasalagi .test = alg_test_hash, 338498eca72fSraveendra padasalagi .fips_allowed = 1, 338598eca72fSraveendra padasalagi .suite = { 338621c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_384_tv_template) 338798eca72fSraveendra padasalagi } 338898eca72fSraveendra padasalagi }, { 338998eca72fSraveendra padasalagi .alg = "hmac(sha3-512)", 339098eca72fSraveendra padasalagi .test = alg_test_hash, 339198eca72fSraveendra padasalagi .fips_allowed = 1, 339298eca72fSraveendra padasalagi .suite = { 339321c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_512_tv_template) 339498eca72fSraveendra padasalagi } 339598eca72fSraveendra padasalagi }, { 3396da7f033dSHerbert Xu .alg = "hmac(sha384)", 3397da7f033dSHerbert Xu .test = alg_test_hash, 3398a1915d51SJarod Wilson .fips_allowed = 1, 3399da7f033dSHerbert Xu .suite = { 340021c8e720SArd Biesheuvel .hash = __VECS(hmac_sha384_tv_template) 3401da7f033dSHerbert Xu } 3402da7f033dSHerbert Xu }, { 3403da7f033dSHerbert Xu .alg = "hmac(sha512)", 3404da7f033dSHerbert Xu .test = alg_test_hash, 3405a1915d51SJarod Wilson .fips_allowed = 1, 3406da7f033dSHerbert Xu .suite = { 340721c8e720SArd Biesheuvel .hash = __VECS(hmac_sha512_tv_template) 3408da7f033dSHerbert Xu } 3409da7f033dSHerbert Xu }, { 341025a0b9d4SVitaly Chikunov .alg = "hmac(streebog256)", 341125a0b9d4SVitaly Chikunov .test = alg_test_hash, 341225a0b9d4SVitaly Chikunov .suite = { 341325a0b9d4SVitaly Chikunov .hash = __VECS(hmac_streebog256_tv_template) 341425a0b9d4SVitaly Chikunov } 341525a0b9d4SVitaly Chikunov }, { 341625a0b9d4SVitaly Chikunov .alg = "hmac(streebog512)", 341725a0b9d4SVitaly Chikunov .test = alg_test_hash, 341825a0b9d4SVitaly Chikunov .suite = { 341925a0b9d4SVitaly Chikunov .hash = __VECS(hmac_streebog512_tv_template) 342025a0b9d4SVitaly Chikunov } 342125a0b9d4SVitaly Chikunov }, { 3422bb5530e4SStephan Mueller .alg = "jitterentropy_rng", 3423bb5530e4SStephan Mueller .fips_allowed = 1, 3424bb5530e4SStephan Mueller .test = alg_test_null, 3425bb5530e4SStephan Mueller }, { 342635351988SStephan Mueller .alg = "kw(aes)", 342735351988SStephan Mueller .test = alg_test_skcipher, 342835351988SStephan Mueller .fips_allowed = 1, 342935351988SStephan Mueller .suite = { 343092a4c9feSEric Biggers .cipher = __VECS(aes_kw_tv_template) 343135351988SStephan Mueller } 343235351988SStephan Mueller }, { 3433da7f033dSHerbert Xu .alg = "lrw(aes)", 34341aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3435da7f033dSHerbert Xu .suite = { 343692a4c9feSEric Biggers .cipher = __VECS(aes_lrw_tv_template) 3437da7f033dSHerbert Xu } 3438da7f033dSHerbert Xu }, { 34390840605eSJussi Kivilinna .alg = "lrw(camellia)", 34400840605eSJussi Kivilinna .test = alg_test_skcipher, 34410840605eSJussi Kivilinna .suite = { 344292a4c9feSEric Biggers .cipher = __VECS(camellia_lrw_tv_template) 34430840605eSJussi Kivilinna } 34440840605eSJussi Kivilinna }, { 34459b8b0405SJohannes Goetzfried .alg = "lrw(cast6)", 34469b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 34479b8b0405SJohannes Goetzfried .suite = { 344892a4c9feSEric Biggers .cipher = __VECS(cast6_lrw_tv_template) 34499b8b0405SJohannes Goetzfried } 34509b8b0405SJohannes Goetzfried }, { 3451d7bfc0faSJussi Kivilinna .alg = "lrw(serpent)", 3452d7bfc0faSJussi Kivilinna .test = alg_test_skcipher, 3453d7bfc0faSJussi Kivilinna .suite = { 345492a4c9feSEric Biggers .cipher = __VECS(serpent_lrw_tv_template) 3455d7bfc0faSJussi Kivilinna } 3456d7bfc0faSJussi Kivilinna }, { 34570b2a1551SJussi Kivilinna .alg = "lrw(twofish)", 34580b2a1551SJussi Kivilinna .test = alg_test_skcipher, 34590b2a1551SJussi Kivilinna .suite = { 346092a4c9feSEric Biggers .cipher = __VECS(tf_lrw_tv_template) 34610b2a1551SJussi Kivilinna } 34620b2a1551SJussi Kivilinna }, { 34631443cc9bSKOVACS Krisztian .alg = "lz4", 34641443cc9bSKOVACS Krisztian .test = alg_test_comp, 34651443cc9bSKOVACS Krisztian .fips_allowed = 1, 34661443cc9bSKOVACS Krisztian .suite = { 34671443cc9bSKOVACS Krisztian .comp = { 346821c8e720SArd Biesheuvel .comp = __VECS(lz4_comp_tv_template), 346921c8e720SArd Biesheuvel .decomp = __VECS(lz4_decomp_tv_template) 34701443cc9bSKOVACS Krisztian } 34711443cc9bSKOVACS Krisztian } 34721443cc9bSKOVACS Krisztian }, { 34731443cc9bSKOVACS Krisztian .alg = "lz4hc", 34741443cc9bSKOVACS Krisztian .test = alg_test_comp, 34751443cc9bSKOVACS Krisztian .fips_allowed = 1, 34761443cc9bSKOVACS Krisztian .suite = { 34771443cc9bSKOVACS Krisztian .comp = { 347821c8e720SArd Biesheuvel .comp = __VECS(lz4hc_comp_tv_template), 347921c8e720SArd Biesheuvel .decomp = __VECS(lz4hc_decomp_tv_template) 34801443cc9bSKOVACS Krisztian } 34811443cc9bSKOVACS Krisztian } 34821443cc9bSKOVACS Krisztian }, { 3483da7f033dSHerbert Xu .alg = "lzo", 3484da7f033dSHerbert Xu .test = alg_test_comp, 34850818904dSMilan Broz .fips_allowed = 1, 3486da7f033dSHerbert Xu .suite = { 3487da7f033dSHerbert Xu .comp = { 348821c8e720SArd Biesheuvel .comp = __VECS(lzo_comp_tv_template), 348921c8e720SArd Biesheuvel .decomp = __VECS(lzo_decomp_tv_template) 3490da7f033dSHerbert Xu } 3491da7f033dSHerbert Xu } 3492da7f033dSHerbert Xu }, { 3493da7f033dSHerbert Xu .alg = "md4", 3494da7f033dSHerbert Xu .test = alg_test_hash, 3495da7f033dSHerbert Xu .suite = { 349621c8e720SArd Biesheuvel .hash = __VECS(md4_tv_template) 3497da7f033dSHerbert Xu } 3498da7f033dSHerbert Xu }, { 3499da7f033dSHerbert Xu .alg = "md5", 3500da7f033dSHerbert Xu .test = alg_test_hash, 3501da7f033dSHerbert Xu .suite = { 350221c8e720SArd Biesheuvel .hash = __VECS(md5_tv_template) 3503da7f033dSHerbert Xu } 3504da7f033dSHerbert Xu }, { 3505da7f033dSHerbert Xu .alg = "michael_mic", 3506da7f033dSHerbert Xu .test = alg_test_hash, 3507da7f033dSHerbert Xu .suite = { 350821c8e720SArd Biesheuvel .hash = __VECS(michael_mic_tv_template) 3509da7f033dSHerbert Xu } 3510da7f033dSHerbert Xu }, { 35114feb4c59SOndrej Mosnacek .alg = "morus1280", 35124feb4c59SOndrej Mosnacek .test = alg_test_aead, 35134feb4c59SOndrej Mosnacek .suite = { 3514a0d608eeSEric Biggers .aead = __VECS(morus1280_tv_template) 35154feb4c59SOndrej Mosnacek } 35164feb4c59SOndrej Mosnacek }, { 35174feb4c59SOndrej Mosnacek .alg = "morus640", 35184feb4c59SOndrej Mosnacek .test = alg_test_aead, 35194feb4c59SOndrej Mosnacek .suite = { 3520a0d608eeSEric Biggers .aead = __VECS(morus640_tv_template) 35214feb4c59SOndrej Mosnacek } 35224feb4c59SOndrej Mosnacek }, { 352326609a21SEric Biggers .alg = "nhpoly1305", 352426609a21SEric Biggers .test = alg_test_hash, 352526609a21SEric Biggers .suite = { 352626609a21SEric Biggers .hash = __VECS(nhpoly1305_tv_template) 352726609a21SEric Biggers } 352826609a21SEric Biggers }, { 3529ba0e14acSPuneet Saxena .alg = "ofb(aes)", 3530ba0e14acSPuneet Saxena .test = alg_test_skcipher, 3531ba0e14acSPuneet Saxena .fips_allowed = 1, 3532ba0e14acSPuneet Saxena .suite = { 353392a4c9feSEric Biggers .cipher = __VECS(aes_ofb_tv_template) 3534ba0e14acSPuneet Saxena } 3535ba0e14acSPuneet Saxena }, { 3536a794d8d8SGilad Ben-Yossef /* Same as ofb(aes) except the key is stored in 3537a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 3538a794d8d8SGilad Ben-Yossef */ 3539a794d8d8SGilad Ben-Yossef .alg = "ofb(paes)", 3540a794d8d8SGilad Ben-Yossef .test = alg_test_null, 3541a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 3542a794d8d8SGilad Ben-Yossef }, { 3543da7f033dSHerbert Xu .alg = "pcbc(fcrypt)", 35441aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3545da7f033dSHerbert Xu .suite = { 354692a4c9feSEric Biggers .cipher = __VECS(fcrypt_pcbc_tv_template) 3547da7f033dSHerbert Xu } 3548da7f033dSHerbert Xu }, { 35491207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha224)", 35501207107cSStephan Mueller .test = alg_test_null, 35511207107cSStephan Mueller .fips_allowed = 1, 35521207107cSStephan Mueller }, { 35531207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha256)", 35541207107cSStephan Mueller .test = alg_test_akcipher, 35551207107cSStephan Mueller .fips_allowed = 1, 35561207107cSStephan Mueller .suite = { 35571207107cSStephan Mueller .akcipher = __VECS(pkcs1pad_rsa_tv_template) 35581207107cSStephan Mueller } 35591207107cSStephan Mueller }, { 35601207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha384)", 35611207107cSStephan Mueller .test = alg_test_null, 35621207107cSStephan Mueller .fips_allowed = 1, 35631207107cSStephan Mueller }, { 35641207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha512)", 35651207107cSStephan Mueller .test = alg_test_null, 35661207107cSStephan Mueller .fips_allowed = 1, 35671207107cSStephan Mueller }, { 3568eee9dc61SMartin Willi .alg = "poly1305", 3569eee9dc61SMartin Willi .test = alg_test_hash, 3570eee9dc61SMartin Willi .suite = { 357121c8e720SArd Biesheuvel .hash = __VECS(poly1305_tv_template) 3572eee9dc61SMartin Willi } 3573eee9dc61SMartin Willi }, { 3574da7f033dSHerbert Xu .alg = "rfc3686(ctr(aes))", 35751aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3576a1915d51SJarod Wilson .fips_allowed = 1, 3577da7f033dSHerbert Xu .suite = { 357892a4c9feSEric Biggers .cipher = __VECS(aes_ctr_rfc3686_tv_template) 3579da7f033dSHerbert Xu } 3580da7f033dSHerbert Xu }, { 35813f31a740SHerbert Xu .alg = "rfc4106(gcm(aes))", 358269435b94SAdrian Hoban .test = alg_test_aead, 3583db71f29aSJarod Wilson .fips_allowed = 1, 358469435b94SAdrian Hoban .suite = { 3585a0d608eeSEric Biggers .aead = __VECS(aes_gcm_rfc4106_tv_template) 358669435b94SAdrian Hoban } 358769435b94SAdrian Hoban }, { 3588544c436aSHerbert Xu .alg = "rfc4309(ccm(aes))", 35895d667322SJarod Wilson .test = alg_test_aead, 3590a1915d51SJarod Wilson .fips_allowed = 1, 35915d667322SJarod Wilson .suite = { 3592a0d608eeSEric Biggers .aead = __VECS(aes_ccm_rfc4309_tv_template) 35935d667322SJarod Wilson } 35945d667322SJarod Wilson }, { 3595bb68745eSHerbert Xu .alg = "rfc4543(gcm(aes))", 3596e9b7441aSJussi Kivilinna .test = alg_test_aead, 3597e9b7441aSJussi Kivilinna .suite = { 3598a0d608eeSEric Biggers .aead = __VECS(aes_gcm_rfc4543_tv_template) 3599e9b7441aSJussi Kivilinna } 3600e9b7441aSJussi Kivilinna }, { 3601af2b76b5SMartin Willi .alg = "rfc7539(chacha20,poly1305)", 3602af2b76b5SMartin Willi .test = alg_test_aead, 3603af2b76b5SMartin Willi .suite = { 3604a0d608eeSEric Biggers .aead = __VECS(rfc7539_tv_template) 3605af2b76b5SMartin Willi } 3606af2b76b5SMartin Willi }, { 36075900758dSMartin Willi .alg = "rfc7539esp(chacha20,poly1305)", 36085900758dSMartin Willi .test = alg_test_aead, 36095900758dSMartin Willi .suite = { 3610a0d608eeSEric Biggers .aead = __VECS(rfc7539esp_tv_template) 36115900758dSMartin Willi } 36125900758dSMartin Willi }, { 3613da7f033dSHerbert Xu .alg = "rmd128", 3614da7f033dSHerbert Xu .test = alg_test_hash, 3615da7f033dSHerbert Xu .suite = { 361621c8e720SArd Biesheuvel .hash = __VECS(rmd128_tv_template) 3617da7f033dSHerbert Xu } 3618da7f033dSHerbert Xu }, { 3619da7f033dSHerbert Xu .alg = "rmd160", 3620da7f033dSHerbert Xu .test = alg_test_hash, 3621da7f033dSHerbert Xu .suite = { 362221c8e720SArd Biesheuvel .hash = __VECS(rmd160_tv_template) 3623da7f033dSHerbert Xu } 3624da7f033dSHerbert Xu }, { 3625da7f033dSHerbert Xu .alg = "rmd256", 3626da7f033dSHerbert Xu .test = alg_test_hash, 3627da7f033dSHerbert Xu .suite = { 362821c8e720SArd Biesheuvel .hash = __VECS(rmd256_tv_template) 3629da7f033dSHerbert Xu } 3630da7f033dSHerbert Xu }, { 3631da7f033dSHerbert Xu .alg = "rmd320", 3632da7f033dSHerbert Xu .test = alg_test_hash, 3633da7f033dSHerbert Xu .suite = { 363421c8e720SArd Biesheuvel .hash = __VECS(rmd320_tv_template) 3635da7f033dSHerbert Xu } 3636da7f033dSHerbert Xu }, { 3637946cc463STadeusz Struk .alg = "rsa", 3638946cc463STadeusz Struk .test = alg_test_akcipher, 3639946cc463STadeusz Struk .fips_allowed = 1, 3640946cc463STadeusz Struk .suite = { 364121c8e720SArd Biesheuvel .akcipher = __VECS(rsa_tv_template) 3642946cc463STadeusz Struk } 3643946cc463STadeusz Struk }, { 3644da7f033dSHerbert Xu .alg = "salsa20", 36451aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3646da7f033dSHerbert Xu .suite = { 364792a4c9feSEric Biggers .cipher = __VECS(salsa20_stream_tv_template) 3648da7f033dSHerbert Xu } 3649da7f033dSHerbert Xu }, { 3650da7f033dSHerbert Xu .alg = "sha1", 3651da7f033dSHerbert Xu .test = alg_test_hash, 3652a1915d51SJarod Wilson .fips_allowed = 1, 3653da7f033dSHerbert Xu .suite = { 365421c8e720SArd Biesheuvel .hash = __VECS(sha1_tv_template) 3655da7f033dSHerbert Xu } 3656da7f033dSHerbert Xu }, { 3657da7f033dSHerbert Xu .alg = "sha224", 3658da7f033dSHerbert Xu .test = alg_test_hash, 3659a1915d51SJarod Wilson .fips_allowed = 1, 3660da7f033dSHerbert Xu .suite = { 366121c8e720SArd Biesheuvel .hash = __VECS(sha224_tv_template) 3662da7f033dSHerbert Xu } 3663da7f033dSHerbert Xu }, { 3664da7f033dSHerbert Xu .alg = "sha256", 3665da7f033dSHerbert Xu .test = alg_test_hash, 3666a1915d51SJarod Wilson .fips_allowed = 1, 3667da7f033dSHerbert Xu .suite = { 366821c8e720SArd Biesheuvel .hash = __VECS(sha256_tv_template) 3669da7f033dSHerbert Xu } 3670da7f033dSHerbert Xu }, { 367179cc6ab8Sraveendra padasalagi .alg = "sha3-224", 367279cc6ab8Sraveendra padasalagi .test = alg_test_hash, 367379cc6ab8Sraveendra padasalagi .fips_allowed = 1, 367479cc6ab8Sraveendra padasalagi .suite = { 367521c8e720SArd Biesheuvel .hash = __VECS(sha3_224_tv_template) 367679cc6ab8Sraveendra padasalagi } 367779cc6ab8Sraveendra padasalagi }, { 367879cc6ab8Sraveendra padasalagi .alg = "sha3-256", 367979cc6ab8Sraveendra padasalagi .test = alg_test_hash, 368079cc6ab8Sraveendra padasalagi .fips_allowed = 1, 368179cc6ab8Sraveendra padasalagi .suite = { 368221c8e720SArd Biesheuvel .hash = __VECS(sha3_256_tv_template) 368379cc6ab8Sraveendra padasalagi } 368479cc6ab8Sraveendra padasalagi }, { 368579cc6ab8Sraveendra padasalagi .alg = "sha3-384", 368679cc6ab8Sraveendra padasalagi .test = alg_test_hash, 368779cc6ab8Sraveendra padasalagi .fips_allowed = 1, 368879cc6ab8Sraveendra padasalagi .suite = { 368921c8e720SArd Biesheuvel .hash = __VECS(sha3_384_tv_template) 369079cc6ab8Sraveendra padasalagi } 369179cc6ab8Sraveendra padasalagi }, { 369279cc6ab8Sraveendra padasalagi .alg = "sha3-512", 369379cc6ab8Sraveendra padasalagi .test = alg_test_hash, 369479cc6ab8Sraveendra padasalagi .fips_allowed = 1, 369579cc6ab8Sraveendra padasalagi .suite = { 369621c8e720SArd Biesheuvel .hash = __VECS(sha3_512_tv_template) 369779cc6ab8Sraveendra padasalagi } 369879cc6ab8Sraveendra padasalagi }, { 3699da7f033dSHerbert Xu .alg = "sha384", 3700da7f033dSHerbert Xu .test = alg_test_hash, 3701a1915d51SJarod Wilson .fips_allowed = 1, 3702da7f033dSHerbert Xu .suite = { 370321c8e720SArd Biesheuvel .hash = __VECS(sha384_tv_template) 3704da7f033dSHerbert Xu } 3705da7f033dSHerbert Xu }, { 3706da7f033dSHerbert Xu .alg = "sha512", 3707da7f033dSHerbert Xu .test = alg_test_hash, 3708a1915d51SJarod Wilson .fips_allowed = 1, 3709da7f033dSHerbert Xu .suite = { 371021c8e720SArd Biesheuvel .hash = __VECS(sha512_tv_template) 3711da7f033dSHerbert Xu } 3712da7f033dSHerbert Xu }, { 3713b7e27530SGilad Ben-Yossef .alg = "sm3", 3714b7e27530SGilad Ben-Yossef .test = alg_test_hash, 3715b7e27530SGilad Ben-Yossef .suite = { 3716b7e27530SGilad Ben-Yossef .hash = __VECS(sm3_tv_template) 3717b7e27530SGilad Ben-Yossef } 3718b7e27530SGilad Ben-Yossef }, { 371925a0b9d4SVitaly Chikunov .alg = "streebog256", 372025a0b9d4SVitaly Chikunov .test = alg_test_hash, 372125a0b9d4SVitaly Chikunov .suite = { 372225a0b9d4SVitaly Chikunov .hash = __VECS(streebog256_tv_template) 372325a0b9d4SVitaly Chikunov } 372425a0b9d4SVitaly Chikunov }, { 372525a0b9d4SVitaly Chikunov .alg = "streebog512", 372625a0b9d4SVitaly Chikunov .test = alg_test_hash, 372725a0b9d4SVitaly Chikunov .suite = { 372825a0b9d4SVitaly Chikunov .hash = __VECS(streebog512_tv_template) 372925a0b9d4SVitaly Chikunov } 373025a0b9d4SVitaly Chikunov }, { 3731da7f033dSHerbert Xu .alg = "tgr128", 3732da7f033dSHerbert Xu .test = alg_test_hash, 3733da7f033dSHerbert Xu .suite = { 373421c8e720SArd Biesheuvel .hash = __VECS(tgr128_tv_template) 3735da7f033dSHerbert Xu } 3736da7f033dSHerbert Xu }, { 3737da7f033dSHerbert Xu .alg = "tgr160", 3738da7f033dSHerbert Xu .test = alg_test_hash, 3739da7f033dSHerbert Xu .suite = { 374021c8e720SArd Biesheuvel .hash = __VECS(tgr160_tv_template) 3741da7f033dSHerbert Xu } 3742da7f033dSHerbert Xu }, { 3743da7f033dSHerbert Xu .alg = "tgr192", 3744da7f033dSHerbert Xu .test = alg_test_hash, 3745da7f033dSHerbert Xu .suite = { 374621c8e720SArd Biesheuvel .hash = __VECS(tgr192_tv_template) 3747da7f033dSHerbert Xu } 3748da7f033dSHerbert Xu }, { 3749ed331adaSEric Biggers .alg = "vmac64(aes)", 3750ed331adaSEric Biggers .test = alg_test_hash, 3751ed331adaSEric Biggers .suite = { 3752ed331adaSEric Biggers .hash = __VECS(vmac64_aes_tv_template) 3753ed331adaSEric Biggers } 3754ed331adaSEric Biggers }, { 3755da7f033dSHerbert Xu .alg = "wp256", 3756da7f033dSHerbert Xu .test = alg_test_hash, 3757da7f033dSHerbert Xu .suite = { 375821c8e720SArd Biesheuvel .hash = __VECS(wp256_tv_template) 3759da7f033dSHerbert Xu } 3760da7f033dSHerbert Xu }, { 3761da7f033dSHerbert Xu .alg = "wp384", 3762da7f033dSHerbert Xu .test = alg_test_hash, 3763da7f033dSHerbert Xu .suite = { 376421c8e720SArd Biesheuvel .hash = __VECS(wp384_tv_template) 3765da7f033dSHerbert Xu } 3766da7f033dSHerbert Xu }, { 3767da7f033dSHerbert Xu .alg = "wp512", 3768da7f033dSHerbert Xu .test = alg_test_hash, 3769da7f033dSHerbert Xu .suite = { 377021c8e720SArd Biesheuvel .hash = __VECS(wp512_tv_template) 3771da7f033dSHerbert Xu } 3772da7f033dSHerbert Xu }, { 3773da7f033dSHerbert Xu .alg = "xcbc(aes)", 3774da7f033dSHerbert Xu .test = alg_test_hash, 3775da7f033dSHerbert Xu .suite = { 377621c8e720SArd Biesheuvel .hash = __VECS(aes_xcbc128_tv_template) 3777da7f033dSHerbert Xu } 3778da7f033dSHerbert Xu }, { 3779aa762409SEric Biggers .alg = "xchacha12", 3780aa762409SEric Biggers .test = alg_test_skcipher, 3781aa762409SEric Biggers .suite = { 3782aa762409SEric Biggers .cipher = __VECS(xchacha12_tv_template) 3783aa762409SEric Biggers }, 3784aa762409SEric Biggers }, { 3785de61d7aeSEric Biggers .alg = "xchacha20", 3786de61d7aeSEric Biggers .test = alg_test_skcipher, 3787de61d7aeSEric Biggers .suite = { 3788de61d7aeSEric Biggers .cipher = __VECS(xchacha20_tv_template) 3789de61d7aeSEric Biggers }, 3790de61d7aeSEric Biggers }, { 3791da7f033dSHerbert Xu .alg = "xts(aes)", 37921aa4ecd9SHerbert Xu .test = alg_test_skcipher, 37932918aa8dSJarod Wilson .fips_allowed = 1, 3794da7f033dSHerbert Xu .suite = { 379592a4c9feSEric Biggers .cipher = __VECS(aes_xts_tv_template) 3796da7f033dSHerbert Xu } 37970c01aed5SGeert Uytterhoeven }, { 37980840605eSJussi Kivilinna .alg = "xts(camellia)", 37990840605eSJussi Kivilinna .test = alg_test_skcipher, 38000840605eSJussi Kivilinna .suite = { 380192a4c9feSEric Biggers .cipher = __VECS(camellia_xts_tv_template) 38020840605eSJussi Kivilinna } 38030840605eSJussi Kivilinna }, { 38049b8b0405SJohannes Goetzfried .alg = "xts(cast6)", 38059b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 38069b8b0405SJohannes Goetzfried .suite = { 380792a4c9feSEric Biggers .cipher = __VECS(cast6_xts_tv_template) 38089b8b0405SJohannes Goetzfried } 38099b8b0405SJohannes Goetzfried }, { 381015f47ce5SGilad Ben-Yossef /* Same as xts(aes) except the key is stored in 381115f47ce5SGilad Ben-Yossef * hardware secure memory which we reference by index 381215f47ce5SGilad Ben-Yossef */ 381315f47ce5SGilad Ben-Yossef .alg = "xts(paes)", 381415f47ce5SGilad Ben-Yossef .test = alg_test_null, 381515f47ce5SGilad Ben-Yossef .fips_allowed = 1, 381615f47ce5SGilad Ben-Yossef }, { 381718be20b9SJussi Kivilinna .alg = "xts(serpent)", 381818be20b9SJussi Kivilinna .test = alg_test_skcipher, 381918be20b9SJussi Kivilinna .suite = { 382092a4c9feSEric Biggers .cipher = __VECS(serpent_xts_tv_template) 382118be20b9SJussi Kivilinna } 382218be20b9SJussi Kivilinna }, { 3823aed265b9SJussi Kivilinna .alg = "xts(twofish)", 3824aed265b9SJussi Kivilinna .test = alg_test_skcipher, 3825aed265b9SJussi Kivilinna .suite = { 382692a4c9feSEric Biggers .cipher = __VECS(tf_xts_tv_template) 3827aed265b9SJussi Kivilinna } 3828a368f43dSGiovanni Cabiddu }, { 382915f47ce5SGilad Ben-Yossef .alg = "xts4096(paes)", 383015f47ce5SGilad Ben-Yossef .test = alg_test_null, 383115f47ce5SGilad Ben-Yossef .fips_allowed = 1, 383215f47ce5SGilad Ben-Yossef }, { 383315f47ce5SGilad Ben-Yossef .alg = "xts512(paes)", 383415f47ce5SGilad Ben-Yossef .test = alg_test_null, 383515f47ce5SGilad Ben-Yossef .fips_allowed = 1, 383615f47ce5SGilad Ben-Yossef }, { 3837a368f43dSGiovanni Cabiddu .alg = "zlib-deflate", 3838a368f43dSGiovanni Cabiddu .test = alg_test_comp, 3839a368f43dSGiovanni Cabiddu .fips_allowed = 1, 3840a368f43dSGiovanni Cabiddu .suite = { 3841a368f43dSGiovanni Cabiddu .comp = { 3842a368f43dSGiovanni Cabiddu .comp = __VECS(zlib_deflate_comp_tv_template), 3843a368f43dSGiovanni Cabiddu .decomp = __VECS(zlib_deflate_decomp_tv_template) 3844a368f43dSGiovanni Cabiddu } 3845a368f43dSGiovanni Cabiddu } 3846d28fc3dbSNick Terrell }, { 3847d28fc3dbSNick Terrell .alg = "zstd", 3848d28fc3dbSNick Terrell .test = alg_test_comp, 3849d28fc3dbSNick Terrell .fips_allowed = 1, 3850d28fc3dbSNick Terrell .suite = { 3851d28fc3dbSNick Terrell .comp = { 3852d28fc3dbSNick Terrell .comp = __VECS(zstd_comp_tv_template), 3853d28fc3dbSNick Terrell .decomp = __VECS(zstd_decomp_tv_template) 3854d28fc3dbSNick Terrell } 3855d28fc3dbSNick Terrell } 3856da7f033dSHerbert Xu } 3857da7f033dSHerbert Xu }; 3858da7f033dSHerbert Xu 38593f47a03dSEric Biggers static void alg_check_test_descs_order(void) 38605714758bSJussi Kivilinna { 38615714758bSJussi Kivilinna int i; 38625714758bSJussi Kivilinna 38635714758bSJussi Kivilinna for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) { 38645714758bSJussi Kivilinna int diff = strcmp(alg_test_descs[i - 1].alg, 38655714758bSJussi Kivilinna alg_test_descs[i].alg); 38665714758bSJussi Kivilinna 38675714758bSJussi Kivilinna if (WARN_ON(diff > 0)) { 38685714758bSJussi Kivilinna pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n", 38695714758bSJussi Kivilinna alg_test_descs[i - 1].alg, 38705714758bSJussi Kivilinna alg_test_descs[i].alg); 38715714758bSJussi Kivilinna } 38725714758bSJussi Kivilinna 38735714758bSJussi Kivilinna if (WARN_ON(diff == 0)) { 38745714758bSJussi Kivilinna pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n", 38755714758bSJussi Kivilinna alg_test_descs[i].alg); 38765714758bSJussi Kivilinna } 38775714758bSJussi Kivilinna } 38785714758bSJussi Kivilinna } 38795714758bSJussi Kivilinna 38803f47a03dSEric Biggers static void alg_check_testvec_configs(void) 38813f47a03dSEric Biggers { 38824e7babbaSEric Biggers int i; 38834e7babbaSEric Biggers 38844e7babbaSEric Biggers for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) 38854e7babbaSEric Biggers WARN_ON(!valid_testvec_config( 38864e7babbaSEric Biggers &default_cipher_testvec_configs[i])); 38874cc2dcf9SEric Biggers 38884cc2dcf9SEric Biggers for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) 38894cc2dcf9SEric Biggers WARN_ON(!valid_testvec_config( 38904cc2dcf9SEric Biggers &default_hash_testvec_configs[i])); 38913f47a03dSEric Biggers } 38923f47a03dSEric Biggers 38933f47a03dSEric Biggers static void testmgr_onetime_init(void) 38943f47a03dSEric Biggers { 38953f47a03dSEric Biggers alg_check_test_descs_order(); 38963f47a03dSEric Biggers alg_check_testvec_configs(); 38975b2706a4SEric Biggers 38985b2706a4SEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 38995b2706a4SEric Biggers pr_warn("alg: extra crypto tests enabled. This is intended for developer use only.\n"); 39005b2706a4SEric Biggers #endif 39013f47a03dSEric Biggers } 39023f47a03dSEric Biggers 39031aa4ecd9SHerbert Xu static int alg_find_test(const char *alg) 3904da7f033dSHerbert Xu { 3905da7f033dSHerbert Xu int start = 0; 3906da7f033dSHerbert Xu int end = ARRAY_SIZE(alg_test_descs); 3907da7f033dSHerbert Xu 3908da7f033dSHerbert Xu while (start < end) { 3909da7f033dSHerbert Xu int i = (start + end) / 2; 3910da7f033dSHerbert Xu int diff = strcmp(alg_test_descs[i].alg, alg); 3911da7f033dSHerbert Xu 3912da7f033dSHerbert Xu if (diff > 0) { 3913da7f033dSHerbert Xu end = i; 3914da7f033dSHerbert Xu continue; 3915da7f033dSHerbert Xu } 3916da7f033dSHerbert Xu 3917da7f033dSHerbert Xu if (diff < 0) { 3918da7f033dSHerbert Xu start = i + 1; 3919da7f033dSHerbert Xu continue; 3920da7f033dSHerbert Xu } 3921da7f033dSHerbert Xu 39221aa4ecd9SHerbert Xu return i; 3923da7f033dSHerbert Xu } 3924da7f033dSHerbert Xu 39251aa4ecd9SHerbert Xu return -1; 39261aa4ecd9SHerbert Xu } 39271aa4ecd9SHerbert Xu 39281aa4ecd9SHerbert Xu int alg_test(const char *driver, const char *alg, u32 type, u32 mask) 39291aa4ecd9SHerbert Xu { 39301aa4ecd9SHerbert Xu int i; 3931a68f6610SHerbert Xu int j; 3932d12d6b6dSNeil Horman int rc; 39331aa4ecd9SHerbert Xu 39349e5c9fe4SRichard W.M. Jones if (!fips_enabled && notests) { 39359e5c9fe4SRichard W.M. Jones printk_once(KERN_INFO "alg: self-tests disabled\n"); 39369e5c9fe4SRichard W.M. Jones return 0; 39379e5c9fe4SRichard W.M. Jones } 39389e5c9fe4SRichard W.M. Jones 39393f47a03dSEric Biggers DO_ONCE(testmgr_onetime_init); 39405714758bSJussi Kivilinna 39411aa4ecd9SHerbert Xu if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) { 39421aa4ecd9SHerbert Xu char nalg[CRYPTO_MAX_ALG_NAME]; 39431aa4ecd9SHerbert Xu 39441aa4ecd9SHerbert Xu if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >= 39451aa4ecd9SHerbert Xu sizeof(nalg)) 39461aa4ecd9SHerbert Xu return -ENAMETOOLONG; 39471aa4ecd9SHerbert Xu 39481aa4ecd9SHerbert Xu i = alg_find_test(nalg); 39491aa4ecd9SHerbert Xu if (i < 0) 39501aa4ecd9SHerbert Xu goto notest; 39511aa4ecd9SHerbert Xu 3952a3bef3a3SJarod Wilson if (fips_enabled && !alg_test_descs[i].fips_allowed) 3953a3bef3a3SJarod Wilson goto non_fips_alg; 3954a3bef3a3SJarod Wilson 3955941fb328SJarod Wilson rc = alg_test_cipher(alg_test_descs + i, driver, type, mask); 3956941fb328SJarod Wilson goto test_done; 39571aa4ecd9SHerbert Xu } 39581aa4ecd9SHerbert Xu 39591aa4ecd9SHerbert Xu i = alg_find_test(alg); 3960a68f6610SHerbert Xu j = alg_find_test(driver); 3961a68f6610SHerbert Xu if (i < 0 && j < 0) 39621aa4ecd9SHerbert Xu goto notest; 39631aa4ecd9SHerbert Xu 3964a68f6610SHerbert Xu if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) || 3965a68f6610SHerbert Xu (j >= 0 && !alg_test_descs[j].fips_allowed))) 3966a3bef3a3SJarod Wilson goto non_fips_alg; 3967a3bef3a3SJarod Wilson 3968a68f6610SHerbert Xu rc = 0; 3969a68f6610SHerbert Xu if (i >= 0) 3970a68f6610SHerbert Xu rc |= alg_test_descs[i].test(alg_test_descs + i, driver, 39711aa4ecd9SHerbert Xu type, mask); 3972032c8cacSCristian Stoica if (j >= 0 && j != i) 3973a68f6610SHerbert Xu rc |= alg_test_descs[j].test(alg_test_descs + j, driver, 3974a68f6610SHerbert Xu type, mask); 3975a68f6610SHerbert Xu 3976941fb328SJarod Wilson test_done: 3977d12d6b6dSNeil Horman if (fips_enabled && rc) 3978d12d6b6dSNeil Horman panic("%s: %s alg self test failed in fips mode!\n", driver, alg); 3979d12d6b6dSNeil Horman 398029ecd4abSJarod Wilson if (fips_enabled && !rc) 39813e8cffd4SMasanari Iida pr_info("alg: self-tests for %s (%s) passed\n", driver, alg); 398229ecd4abSJarod Wilson 3983d12d6b6dSNeil Horman return rc; 39841aa4ecd9SHerbert Xu 39851aa4ecd9SHerbert Xu notest: 3986da7f033dSHerbert Xu printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); 3987da7f033dSHerbert Xu return 0; 3988a3bef3a3SJarod Wilson non_fips_alg: 3989a3bef3a3SJarod Wilson return -EINVAL; 3990da7f033dSHerbert Xu } 39910b767f96SAlexander Shishkin 3992326a6346SHerbert Xu #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */ 39930b767f96SAlexander Shishkin 3994da7f033dSHerbert Xu EXPORT_SYMBOL_GPL(alg_test); 3995