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 15384e7babbaSEric Biggers /* Check for the correct output (ciphertext or plaintext) */ 15394e7babbaSEric Biggers err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext, 15404e7babbaSEric Biggers vec->len, 0, true); 15414e7babbaSEric Biggers if (err == -EOVERFLOW) { 15424e7babbaSEric Biggers pr_err("alg: skcipher: %s %s overran dst buffer on test vector %u, cfg=\"%s\"\n", 15434e7babbaSEric Biggers driver, op, vec_num, cfg->name); 15444e7babbaSEric Biggers return err; 15454e7babbaSEric Biggers } 15464e7babbaSEric Biggers if (err) { 15474e7babbaSEric Biggers pr_err("alg: skcipher: %s %s test failed (wrong result) on test vector %u, cfg=\"%s\"\n", 15484e7babbaSEric Biggers driver, op, vec_num, cfg->name); 15494e7babbaSEric Biggers return err; 15504e7babbaSEric Biggers } 155108d6af8cSJussi Kivilinna 15524e7babbaSEric Biggers /* If applicable, check that the algorithm generated the correct IV */ 15534e7babbaSEric Biggers if (vec->generates_iv && enc && memcmp(iv, vec->iv, ivsize) != 0) { 15544e7babbaSEric Biggers pr_err("alg: skcipher: %s %s test failed (wrong output IV) on test vector %u, cfg=\"%s\"\n", 15554e7babbaSEric Biggers driver, op, vec_num, cfg->name); 15564e7babbaSEric Biggers hexdump(iv, ivsize); 15574e7babbaSEric Biggers return -EINVAL; 15583a338f20SJussi Kivilinna } 15593a338f20SJussi Kivilinna 15603a338f20SJussi Kivilinna return 0; 156108d6af8cSJussi Kivilinna } 156208d6af8cSJussi Kivilinna 15634e7babbaSEric Biggers static int test_skcipher_vec(const char *driver, int enc, 15644e7babbaSEric Biggers const struct cipher_testvec *vec, 15654e7babbaSEric Biggers unsigned int vec_num, 15664e7babbaSEric Biggers struct skcipher_request *req, 15674e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 15684e7babbaSEric Biggers { 15694e7babbaSEric Biggers unsigned int i; 15704e7babbaSEric Biggers int err; 15714e7babbaSEric Biggers 15724e7babbaSEric Biggers if (fips_enabled && vec->fips_skip) 15734e7babbaSEric Biggers return 0; 15744e7babbaSEric Biggers 15754e7babbaSEric Biggers for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) { 15764e7babbaSEric Biggers err = test_skcipher_vec_cfg(driver, enc, vec, vec_num, 15774e7babbaSEric Biggers &default_cipher_testvec_configs[i], 15784e7babbaSEric Biggers req, tsgls); 15794e7babbaSEric Biggers if (err) 15804e7babbaSEric Biggers return err; 15814e7babbaSEric Biggers } 15824e7babbaSEric Biggers 15834e7babbaSEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 15844e7babbaSEric Biggers if (!noextratests) { 15854e7babbaSEric Biggers struct testvec_config cfg; 15864e7babbaSEric Biggers char cfgname[TESTVEC_CONFIG_NAMELEN]; 15874e7babbaSEric Biggers 15884e7babbaSEric Biggers for (i = 0; i < fuzz_iterations; i++) { 15894e7babbaSEric Biggers generate_random_testvec_config(&cfg, cfgname, 15904e7babbaSEric Biggers sizeof(cfgname)); 15914e7babbaSEric Biggers err = test_skcipher_vec_cfg(driver, enc, vec, vec_num, 15924e7babbaSEric Biggers &cfg, req, tsgls); 15934e7babbaSEric Biggers if (err) 15944e7babbaSEric Biggers return err; 15954e7babbaSEric Biggers } 15964e7babbaSEric Biggers } 15974e7babbaSEric Biggers #endif 15984e7babbaSEric Biggers return 0; 15994e7babbaSEric Biggers } 16004e7babbaSEric Biggers 16014e7babbaSEric Biggers static int test_skcipher(const char *driver, int enc, 16024e7babbaSEric Biggers const struct cipher_test_suite *suite, 16034e7babbaSEric Biggers struct skcipher_request *req, 16044e7babbaSEric Biggers struct cipher_test_sglists *tsgls) 16054e7babbaSEric Biggers { 16064e7babbaSEric Biggers unsigned int i; 16074e7babbaSEric Biggers int err; 16084e7babbaSEric Biggers 16094e7babbaSEric Biggers for (i = 0; i < suite->count; i++) { 16104e7babbaSEric Biggers err = test_skcipher_vec(driver, enc, &suite->vecs[i], i, req, 16114e7babbaSEric Biggers tsgls); 16124e7babbaSEric Biggers if (err) 16134e7babbaSEric Biggers return err; 16144e7babbaSEric Biggers } 16154e7babbaSEric Biggers return 0; 16164e7babbaSEric Biggers } 16174e7babbaSEric Biggers 16184e7babbaSEric Biggers static int alg_test_skcipher(const struct alg_test_desc *desc, 16194e7babbaSEric Biggers const char *driver, u32 type, u32 mask) 16204e7babbaSEric Biggers { 16214e7babbaSEric Biggers const struct cipher_test_suite *suite = &desc->suite.cipher; 16224e7babbaSEric Biggers struct crypto_skcipher *tfm; 16234e7babbaSEric Biggers struct skcipher_request *req = NULL; 16244e7babbaSEric Biggers struct cipher_test_sglists *tsgls = NULL; 16254e7babbaSEric Biggers int err; 16264e7babbaSEric Biggers 16274e7babbaSEric Biggers if (suite->count <= 0) { 16284e7babbaSEric Biggers pr_err("alg: skcipher: empty test suite for %s\n", driver); 16294e7babbaSEric Biggers return -EINVAL; 16304e7babbaSEric Biggers } 16314e7babbaSEric Biggers 16324e7babbaSEric Biggers tfm = crypto_alloc_skcipher(driver, type, mask); 16334e7babbaSEric Biggers if (IS_ERR(tfm)) { 16344e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", 16354e7babbaSEric Biggers driver, PTR_ERR(tfm)); 16364e7babbaSEric Biggers return PTR_ERR(tfm); 16374e7babbaSEric Biggers } 16384e7babbaSEric Biggers 16394e7babbaSEric Biggers req = skcipher_request_alloc(tfm, GFP_KERNEL); 16404e7babbaSEric Biggers if (!req) { 16414e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate request for %s\n", 16424e7babbaSEric Biggers driver); 16434e7babbaSEric Biggers err = -ENOMEM; 16444e7babbaSEric Biggers goto out; 16454e7babbaSEric Biggers } 16464e7babbaSEric Biggers 16474e7babbaSEric Biggers tsgls = alloc_cipher_test_sglists(); 16484e7babbaSEric Biggers if (!tsgls) { 16494e7babbaSEric Biggers pr_err("alg: skcipher: failed to allocate test buffers for %s\n", 16504e7babbaSEric Biggers driver); 16514e7babbaSEric Biggers err = -ENOMEM; 16524e7babbaSEric Biggers goto out; 16534e7babbaSEric Biggers } 16544e7babbaSEric Biggers 16554e7babbaSEric Biggers err = test_skcipher(driver, ENCRYPT, suite, req, tsgls); 16564e7babbaSEric Biggers if (err) 16574e7babbaSEric Biggers goto out; 16584e7babbaSEric Biggers 16594e7babbaSEric Biggers err = test_skcipher(driver, DECRYPT, suite, req, tsgls); 16604e7babbaSEric Biggers out: 16614e7babbaSEric Biggers free_cipher_test_sglists(tsgls); 16624e7babbaSEric Biggers skcipher_request_free(req); 16634e7babbaSEric Biggers crypto_free_skcipher(tfm); 16644e7babbaSEric Biggers return err; 16654e7babbaSEric Biggers } 16664e7babbaSEric Biggers 1667b13b1e0cSEric Biggers static int test_comp(struct crypto_comp *tfm, 1668b13b1e0cSEric Biggers const struct comp_testvec *ctemplate, 1669b13b1e0cSEric Biggers const struct comp_testvec *dtemplate, 1670b13b1e0cSEric Biggers int ctcount, int dtcount) 1671da7f033dSHerbert Xu { 1672da7f033dSHerbert Xu const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm)); 167333607384SMahipal Challa char *output, *decomp_output; 1674da7f033dSHerbert Xu unsigned int i; 1675da7f033dSHerbert Xu int ret; 1676da7f033dSHerbert Xu 167733607384SMahipal Challa output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 167833607384SMahipal Challa if (!output) 167933607384SMahipal Challa return -ENOMEM; 168033607384SMahipal Challa 168133607384SMahipal Challa decomp_output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 168233607384SMahipal Challa if (!decomp_output) { 168333607384SMahipal Challa kfree(output); 168433607384SMahipal Challa return -ENOMEM; 168533607384SMahipal Challa } 168633607384SMahipal Challa 1687da7f033dSHerbert Xu for (i = 0; i < ctcount; i++) { 1688c79cf910SGeert Uytterhoeven int ilen; 1689c79cf910SGeert Uytterhoeven unsigned int dlen = COMP_BUF_SIZE; 1690da7f033dSHerbert Xu 169122a8118dSMichael Schupikov memset(output, 0, COMP_BUF_SIZE); 169222a8118dSMichael Schupikov memset(decomp_output, 0, COMP_BUF_SIZE); 1693da7f033dSHerbert Xu 1694da7f033dSHerbert Xu ilen = ctemplate[i].inlen; 1695da7f033dSHerbert Xu ret = crypto_comp_compress(tfm, ctemplate[i].input, 169633607384SMahipal Challa ilen, output, &dlen); 1697da7f033dSHerbert Xu if (ret) { 1698da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: compression failed " 1699da7f033dSHerbert Xu "on test %d for %s: ret=%d\n", i + 1, algo, 1700da7f033dSHerbert Xu -ret); 1701da7f033dSHerbert Xu goto out; 1702da7f033dSHerbert Xu } 1703da7f033dSHerbert Xu 170433607384SMahipal Challa ilen = dlen; 170533607384SMahipal Challa dlen = COMP_BUF_SIZE; 170633607384SMahipal Challa ret = crypto_comp_decompress(tfm, output, 170733607384SMahipal Challa ilen, decomp_output, &dlen); 170833607384SMahipal Challa if (ret) { 170933607384SMahipal Challa pr_err("alg: comp: compression failed: decompress: on test %d for %s failed: ret=%d\n", 171033607384SMahipal Challa i + 1, algo, -ret); 171133607384SMahipal Challa goto out; 171233607384SMahipal Challa } 171333607384SMahipal Challa 171433607384SMahipal Challa if (dlen != ctemplate[i].inlen) { 1715b812eb00SGeert Uytterhoeven printk(KERN_ERR "alg: comp: Compression test %d " 1716b812eb00SGeert Uytterhoeven "failed for %s: output len = %d\n", i + 1, algo, 1717b812eb00SGeert Uytterhoeven dlen); 1718b812eb00SGeert Uytterhoeven ret = -EINVAL; 1719b812eb00SGeert Uytterhoeven goto out; 1720b812eb00SGeert Uytterhoeven } 1721b812eb00SGeert Uytterhoeven 172233607384SMahipal Challa if (memcmp(decomp_output, ctemplate[i].input, 172333607384SMahipal Challa ctemplate[i].inlen)) { 172433607384SMahipal Challa pr_err("alg: comp: compression failed: output differs: on test %d for %s\n", 172533607384SMahipal Challa i + 1, algo); 172633607384SMahipal Challa hexdump(decomp_output, dlen); 1727da7f033dSHerbert Xu ret = -EINVAL; 1728da7f033dSHerbert Xu goto out; 1729da7f033dSHerbert Xu } 1730da7f033dSHerbert Xu } 1731da7f033dSHerbert Xu 1732da7f033dSHerbert Xu for (i = 0; i < dtcount; i++) { 1733c79cf910SGeert Uytterhoeven int ilen; 1734c79cf910SGeert Uytterhoeven unsigned int dlen = COMP_BUF_SIZE; 1735da7f033dSHerbert Xu 173622a8118dSMichael Schupikov memset(decomp_output, 0, COMP_BUF_SIZE); 1737da7f033dSHerbert Xu 1738da7f033dSHerbert Xu ilen = dtemplate[i].inlen; 1739da7f033dSHerbert Xu ret = crypto_comp_decompress(tfm, dtemplate[i].input, 174033607384SMahipal Challa ilen, decomp_output, &dlen); 1741da7f033dSHerbert Xu if (ret) { 1742da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: decompression failed " 1743da7f033dSHerbert Xu "on test %d for %s: ret=%d\n", i + 1, algo, 1744da7f033dSHerbert Xu -ret); 1745da7f033dSHerbert Xu goto out; 1746da7f033dSHerbert Xu } 1747da7f033dSHerbert Xu 1748b812eb00SGeert Uytterhoeven if (dlen != dtemplate[i].outlen) { 1749b812eb00SGeert Uytterhoeven printk(KERN_ERR "alg: comp: Decompression test %d " 1750b812eb00SGeert Uytterhoeven "failed for %s: output len = %d\n", i + 1, algo, 1751b812eb00SGeert Uytterhoeven dlen); 1752b812eb00SGeert Uytterhoeven ret = -EINVAL; 1753b812eb00SGeert Uytterhoeven goto out; 1754b812eb00SGeert Uytterhoeven } 1755b812eb00SGeert Uytterhoeven 175633607384SMahipal Challa if (memcmp(decomp_output, dtemplate[i].output, dlen)) { 1757da7f033dSHerbert Xu printk(KERN_ERR "alg: comp: Decompression test %d " 1758da7f033dSHerbert Xu "failed for %s\n", i + 1, algo); 175933607384SMahipal Challa hexdump(decomp_output, dlen); 1760da7f033dSHerbert Xu ret = -EINVAL; 1761da7f033dSHerbert Xu goto out; 1762da7f033dSHerbert Xu } 1763da7f033dSHerbert Xu } 1764da7f033dSHerbert Xu 1765da7f033dSHerbert Xu ret = 0; 1766da7f033dSHerbert Xu 1767da7f033dSHerbert Xu out: 176833607384SMahipal Challa kfree(decomp_output); 176933607384SMahipal Challa kfree(output); 1770da7f033dSHerbert Xu return ret; 1771da7f033dSHerbert Xu } 1772da7f033dSHerbert Xu 1773b13b1e0cSEric Biggers static int test_acomp(struct crypto_acomp *tfm, 1774b13b1e0cSEric Biggers const struct comp_testvec *ctemplate, 1775b13b1e0cSEric Biggers const struct comp_testvec *dtemplate, 1776b13b1e0cSEric Biggers int ctcount, int dtcount) 1777d7db7a88SGiovanni Cabiddu { 1778d7db7a88SGiovanni Cabiddu const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm)); 1779d7db7a88SGiovanni Cabiddu unsigned int i; 1780a9943a0aSGiovanni Cabiddu char *output, *decomp_out; 1781d7db7a88SGiovanni Cabiddu int ret; 1782d7db7a88SGiovanni Cabiddu struct scatterlist src, dst; 1783d7db7a88SGiovanni Cabiddu struct acomp_req *req; 17847f397136SGilad Ben-Yossef struct crypto_wait wait; 1785d7db7a88SGiovanni Cabiddu 1786eb095593SEric Biggers output = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 1787eb095593SEric Biggers if (!output) 1788eb095593SEric Biggers return -ENOMEM; 1789eb095593SEric Biggers 1790a9943a0aSGiovanni Cabiddu decomp_out = kmalloc(COMP_BUF_SIZE, GFP_KERNEL); 1791a9943a0aSGiovanni Cabiddu if (!decomp_out) { 1792a9943a0aSGiovanni Cabiddu kfree(output); 1793a9943a0aSGiovanni Cabiddu return -ENOMEM; 1794a9943a0aSGiovanni Cabiddu } 1795a9943a0aSGiovanni Cabiddu 1796d7db7a88SGiovanni Cabiddu for (i = 0; i < ctcount; i++) { 1797d7db7a88SGiovanni Cabiddu unsigned int dlen = COMP_BUF_SIZE; 1798d7db7a88SGiovanni Cabiddu int ilen = ctemplate[i].inlen; 179902608e02SLaura Abbott void *input_vec; 1800d7db7a88SGiovanni Cabiddu 1801d2110224SEric Biggers input_vec = kmemdup(ctemplate[i].input, ilen, GFP_KERNEL); 180202608e02SLaura Abbott if (!input_vec) { 180302608e02SLaura Abbott ret = -ENOMEM; 180402608e02SLaura Abbott goto out; 180502608e02SLaura Abbott } 180602608e02SLaura Abbott 1807eb095593SEric Biggers memset(output, 0, dlen); 18087f397136SGilad Ben-Yossef crypto_init_wait(&wait); 180902608e02SLaura Abbott sg_init_one(&src, input_vec, ilen); 1810d7db7a88SGiovanni Cabiddu sg_init_one(&dst, output, dlen); 1811d7db7a88SGiovanni Cabiddu 1812d7db7a88SGiovanni Cabiddu req = acomp_request_alloc(tfm); 1813d7db7a88SGiovanni Cabiddu if (!req) { 1814d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: request alloc failed for %s\n", 1815d7db7a88SGiovanni Cabiddu algo); 181602608e02SLaura Abbott kfree(input_vec); 1817d7db7a88SGiovanni Cabiddu ret = -ENOMEM; 1818d7db7a88SGiovanni Cabiddu goto out; 1819d7db7a88SGiovanni Cabiddu } 1820d7db7a88SGiovanni Cabiddu 1821d7db7a88SGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 1822d7db7a88SGiovanni Cabiddu acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 18237f397136SGilad Ben-Yossef crypto_req_done, &wait); 1824d7db7a88SGiovanni Cabiddu 18257f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_compress(req), &wait); 1826d7db7a88SGiovanni Cabiddu if (ret) { 1827d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 1828d7db7a88SGiovanni Cabiddu i + 1, algo, -ret); 182902608e02SLaura Abbott kfree(input_vec); 1830d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1831d7db7a88SGiovanni Cabiddu goto out; 1832d7db7a88SGiovanni Cabiddu } 1833d7db7a88SGiovanni Cabiddu 1834a9943a0aSGiovanni Cabiddu ilen = req->dlen; 1835a9943a0aSGiovanni Cabiddu dlen = COMP_BUF_SIZE; 1836a9943a0aSGiovanni Cabiddu sg_init_one(&src, output, ilen); 1837a9943a0aSGiovanni Cabiddu sg_init_one(&dst, decomp_out, dlen); 18387f397136SGilad Ben-Yossef crypto_init_wait(&wait); 1839a9943a0aSGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 1840a9943a0aSGiovanni Cabiddu 18417f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 1842a9943a0aSGiovanni Cabiddu if (ret) { 1843a9943a0aSGiovanni Cabiddu pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 1844a9943a0aSGiovanni Cabiddu i + 1, algo, -ret); 1845a9943a0aSGiovanni Cabiddu kfree(input_vec); 1846a9943a0aSGiovanni Cabiddu acomp_request_free(req); 1847a9943a0aSGiovanni Cabiddu goto out; 1848a9943a0aSGiovanni Cabiddu } 1849a9943a0aSGiovanni Cabiddu 1850a9943a0aSGiovanni Cabiddu if (req->dlen != ctemplate[i].inlen) { 1851d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", 1852d7db7a88SGiovanni Cabiddu i + 1, algo, req->dlen); 1853d7db7a88SGiovanni Cabiddu ret = -EINVAL; 185402608e02SLaura Abbott kfree(input_vec); 1855d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1856d7db7a88SGiovanni Cabiddu goto out; 1857d7db7a88SGiovanni Cabiddu } 1858d7db7a88SGiovanni Cabiddu 1859a9943a0aSGiovanni Cabiddu if (memcmp(input_vec, decomp_out, req->dlen)) { 1860d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Compression test %d failed for %s\n", 1861d7db7a88SGiovanni Cabiddu i + 1, algo); 1862d7db7a88SGiovanni Cabiddu hexdump(output, req->dlen); 1863d7db7a88SGiovanni Cabiddu ret = -EINVAL; 186402608e02SLaura Abbott kfree(input_vec); 1865d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1866d7db7a88SGiovanni Cabiddu goto out; 1867d7db7a88SGiovanni Cabiddu } 1868d7db7a88SGiovanni Cabiddu 186902608e02SLaura Abbott kfree(input_vec); 1870d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1871d7db7a88SGiovanni Cabiddu } 1872d7db7a88SGiovanni Cabiddu 1873d7db7a88SGiovanni Cabiddu for (i = 0; i < dtcount; i++) { 1874d7db7a88SGiovanni Cabiddu unsigned int dlen = COMP_BUF_SIZE; 1875d7db7a88SGiovanni Cabiddu int ilen = dtemplate[i].inlen; 187602608e02SLaura Abbott void *input_vec; 1877d7db7a88SGiovanni Cabiddu 1878d2110224SEric Biggers input_vec = kmemdup(dtemplate[i].input, ilen, GFP_KERNEL); 187902608e02SLaura Abbott if (!input_vec) { 188002608e02SLaura Abbott ret = -ENOMEM; 188102608e02SLaura Abbott goto out; 188202608e02SLaura Abbott } 188302608e02SLaura Abbott 1884eb095593SEric Biggers memset(output, 0, dlen); 18857f397136SGilad Ben-Yossef crypto_init_wait(&wait); 188602608e02SLaura Abbott sg_init_one(&src, input_vec, ilen); 1887d7db7a88SGiovanni Cabiddu sg_init_one(&dst, output, dlen); 1888d7db7a88SGiovanni Cabiddu 1889d7db7a88SGiovanni Cabiddu req = acomp_request_alloc(tfm); 1890d7db7a88SGiovanni Cabiddu if (!req) { 1891d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: request alloc failed for %s\n", 1892d7db7a88SGiovanni Cabiddu algo); 189302608e02SLaura Abbott kfree(input_vec); 1894d7db7a88SGiovanni Cabiddu ret = -ENOMEM; 1895d7db7a88SGiovanni Cabiddu goto out; 1896d7db7a88SGiovanni Cabiddu } 1897d7db7a88SGiovanni Cabiddu 1898d7db7a88SGiovanni Cabiddu acomp_request_set_params(req, &src, &dst, ilen, dlen); 1899d7db7a88SGiovanni Cabiddu acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 19007f397136SGilad Ben-Yossef crypto_req_done, &wait); 1901d7db7a88SGiovanni Cabiddu 19027f397136SGilad Ben-Yossef ret = crypto_wait_req(crypto_acomp_decompress(req), &wait); 1903d7db7a88SGiovanni Cabiddu if (ret) { 1904d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n", 1905d7db7a88SGiovanni Cabiddu i + 1, algo, -ret); 190602608e02SLaura Abbott kfree(input_vec); 1907d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1908d7db7a88SGiovanni Cabiddu goto out; 1909d7db7a88SGiovanni Cabiddu } 1910d7db7a88SGiovanni Cabiddu 1911d7db7a88SGiovanni Cabiddu if (req->dlen != dtemplate[i].outlen) { 1912d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n", 1913d7db7a88SGiovanni Cabiddu i + 1, algo, req->dlen); 1914d7db7a88SGiovanni Cabiddu ret = -EINVAL; 191502608e02SLaura Abbott kfree(input_vec); 1916d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1917d7db7a88SGiovanni Cabiddu goto out; 1918d7db7a88SGiovanni Cabiddu } 1919d7db7a88SGiovanni Cabiddu 1920d7db7a88SGiovanni Cabiddu if (memcmp(output, dtemplate[i].output, req->dlen)) { 1921d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Decompression test %d failed for %s\n", 1922d7db7a88SGiovanni Cabiddu i + 1, algo); 1923d7db7a88SGiovanni Cabiddu hexdump(output, req->dlen); 1924d7db7a88SGiovanni Cabiddu ret = -EINVAL; 192502608e02SLaura Abbott kfree(input_vec); 1926d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1927d7db7a88SGiovanni Cabiddu goto out; 1928d7db7a88SGiovanni Cabiddu } 1929d7db7a88SGiovanni Cabiddu 193002608e02SLaura Abbott kfree(input_vec); 1931d7db7a88SGiovanni Cabiddu acomp_request_free(req); 1932d7db7a88SGiovanni Cabiddu } 1933d7db7a88SGiovanni Cabiddu 1934d7db7a88SGiovanni Cabiddu ret = 0; 1935d7db7a88SGiovanni Cabiddu 1936d7db7a88SGiovanni Cabiddu out: 1937a9943a0aSGiovanni Cabiddu kfree(decomp_out); 1938eb095593SEric Biggers kfree(output); 1939d7db7a88SGiovanni Cabiddu return ret; 1940d7db7a88SGiovanni Cabiddu } 1941d7db7a88SGiovanni Cabiddu 1942b13b1e0cSEric Biggers static int test_cprng(struct crypto_rng *tfm, 1943b13b1e0cSEric Biggers const struct cprng_testvec *template, 19447647d6ceSJarod Wilson unsigned int tcount) 19457647d6ceSJarod Wilson { 19467647d6ceSJarod Wilson const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); 1947fa4ef8a6SFelipe Contreras int err = 0, i, j, seedsize; 19487647d6ceSJarod Wilson u8 *seed; 19497647d6ceSJarod Wilson char result[32]; 19507647d6ceSJarod Wilson 19517647d6ceSJarod Wilson seedsize = crypto_rng_seedsize(tfm); 19527647d6ceSJarod Wilson 19537647d6ceSJarod Wilson seed = kmalloc(seedsize, GFP_KERNEL); 19547647d6ceSJarod Wilson if (!seed) { 19557647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to allocate seed space " 19567647d6ceSJarod Wilson "for %s\n", algo); 19577647d6ceSJarod Wilson return -ENOMEM; 19587647d6ceSJarod Wilson } 19597647d6ceSJarod Wilson 19607647d6ceSJarod Wilson for (i = 0; i < tcount; i++) { 19617647d6ceSJarod Wilson memset(result, 0, 32); 19627647d6ceSJarod Wilson 19637647d6ceSJarod Wilson memcpy(seed, template[i].v, template[i].vlen); 19647647d6ceSJarod Wilson memcpy(seed + template[i].vlen, template[i].key, 19657647d6ceSJarod Wilson template[i].klen); 19667647d6ceSJarod Wilson memcpy(seed + template[i].vlen + template[i].klen, 19677647d6ceSJarod Wilson template[i].dt, template[i].dtlen); 19687647d6ceSJarod Wilson 19697647d6ceSJarod Wilson err = crypto_rng_reset(tfm, seed, seedsize); 19707647d6ceSJarod Wilson if (err) { 19717647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to reset rng " 19727647d6ceSJarod Wilson "for %s\n", algo); 19737647d6ceSJarod Wilson goto out; 19747647d6ceSJarod Wilson } 19757647d6ceSJarod Wilson 19767647d6ceSJarod Wilson for (j = 0; j < template[i].loops; j++) { 19777647d6ceSJarod Wilson err = crypto_rng_get_bytes(tfm, result, 19787647d6ceSJarod Wilson template[i].rlen); 197919e60e13SStephan Mueller if (err < 0) { 19807647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to obtain " 19817647d6ceSJarod Wilson "the correct amount of random data for " 198219e60e13SStephan Mueller "%s (requested %d)\n", algo, 198319e60e13SStephan Mueller template[i].rlen); 19847647d6ceSJarod Wilson goto out; 19857647d6ceSJarod Wilson } 19867647d6ceSJarod Wilson } 19877647d6ceSJarod Wilson 19887647d6ceSJarod Wilson err = memcmp(result, template[i].result, 19897647d6ceSJarod Wilson template[i].rlen); 19907647d6ceSJarod Wilson if (err) { 19917647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Test %d failed for %s\n", 19927647d6ceSJarod Wilson i, algo); 19937647d6ceSJarod Wilson hexdump(result, template[i].rlen); 19947647d6ceSJarod Wilson err = -EINVAL; 19957647d6ceSJarod Wilson goto out; 19967647d6ceSJarod Wilson } 19977647d6ceSJarod Wilson } 19987647d6ceSJarod Wilson 19997647d6ceSJarod Wilson out: 20007647d6ceSJarod Wilson kfree(seed); 20017647d6ceSJarod Wilson return err; 20027647d6ceSJarod Wilson } 20037647d6ceSJarod Wilson 2004da7f033dSHerbert Xu static int alg_test_cipher(const struct alg_test_desc *desc, 2005da7f033dSHerbert Xu const char *driver, u32 type, u32 mask) 2006da7f033dSHerbert Xu { 200792a4c9feSEric Biggers const struct cipher_test_suite *suite = &desc->suite.cipher; 20081aa4ecd9SHerbert Xu struct crypto_cipher *tfm; 200992a4c9feSEric Biggers int err; 2010da7f033dSHerbert Xu 2011eed93e0cSHerbert Xu tfm = crypto_alloc_cipher(driver, type, mask); 2012da7f033dSHerbert Xu if (IS_ERR(tfm)) { 2013da7f033dSHerbert Xu printk(KERN_ERR "alg: cipher: Failed to load transform for " 2014da7f033dSHerbert Xu "%s: %ld\n", driver, PTR_ERR(tfm)); 2015da7f033dSHerbert Xu return PTR_ERR(tfm); 2016da7f033dSHerbert Xu } 2017da7f033dSHerbert Xu 201892a4c9feSEric Biggers err = test_cipher(tfm, ENCRYPT, suite->vecs, suite->count); 201992a4c9feSEric Biggers if (!err) 202092a4c9feSEric Biggers err = test_cipher(tfm, DECRYPT, suite->vecs, suite->count); 2021da7f033dSHerbert Xu 20221aa4ecd9SHerbert Xu crypto_free_cipher(tfm); 20231aa4ecd9SHerbert Xu return err; 20241aa4ecd9SHerbert Xu } 20251aa4ecd9SHerbert Xu 2026da7f033dSHerbert Xu static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, 2027da7f033dSHerbert Xu u32 type, u32 mask) 2028da7f033dSHerbert Xu { 2029d7db7a88SGiovanni Cabiddu struct crypto_comp *comp; 2030d7db7a88SGiovanni Cabiddu struct crypto_acomp *acomp; 2031da7f033dSHerbert Xu int err; 2032d7db7a88SGiovanni Cabiddu u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK; 2033da7f033dSHerbert Xu 2034d7db7a88SGiovanni Cabiddu if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) { 2035d7db7a88SGiovanni Cabiddu acomp = crypto_alloc_acomp(driver, type, mask); 2036d7db7a88SGiovanni Cabiddu if (IS_ERR(acomp)) { 2037d7db7a88SGiovanni Cabiddu pr_err("alg: acomp: Failed to load transform for %s: %ld\n", 2038d7db7a88SGiovanni Cabiddu driver, PTR_ERR(acomp)); 2039d7db7a88SGiovanni Cabiddu return PTR_ERR(acomp); 2040d7db7a88SGiovanni Cabiddu } 2041d7db7a88SGiovanni Cabiddu err = test_acomp(acomp, desc->suite.comp.comp.vecs, 2042d7db7a88SGiovanni Cabiddu desc->suite.comp.decomp.vecs, 2043d7db7a88SGiovanni Cabiddu desc->suite.comp.comp.count, 2044d7db7a88SGiovanni Cabiddu desc->suite.comp.decomp.count); 2045d7db7a88SGiovanni Cabiddu crypto_free_acomp(acomp); 2046d7db7a88SGiovanni Cabiddu } else { 2047d7db7a88SGiovanni Cabiddu comp = crypto_alloc_comp(driver, type, mask); 2048d7db7a88SGiovanni Cabiddu if (IS_ERR(comp)) { 2049d7db7a88SGiovanni Cabiddu pr_err("alg: comp: Failed to load transform for %s: %ld\n", 2050d7db7a88SGiovanni Cabiddu driver, PTR_ERR(comp)); 2051d7db7a88SGiovanni Cabiddu return PTR_ERR(comp); 2052da7f033dSHerbert Xu } 2053da7f033dSHerbert Xu 2054d7db7a88SGiovanni Cabiddu err = test_comp(comp, desc->suite.comp.comp.vecs, 2055da7f033dSHerbert Xu desc->suite.comp.decomp.vecs, 2056da7f033dSHerbert Xu desc->suite.comp.comp.count, 2057da7f033dSHerbert Xu desc->suite.comp.decomp.count); 2058da7f033dSHerbert Xu 2059d7db7a88SGiovanni Cabiddu crypto_free_comp(comp); 2060d7db7a88SGiovanni Cabiddu } 2061da7f033dSHerbert Xu return err; 2062da7f033dSHerbert Xu } 2063da7f033dSHerbert Xu 20648e3ee85eSHerbert Xu static int alg_test_crc32c(const struct alg_test_desc *desc, 20658e3ee85eSHerbert Xu const char *driver, u32 type, u32 mask) 20668e3ee85eSHerbert Xu { 20678e3ee85eSHerbert Xu struct crypto_shash *tfm; 2068cb9dde88SEric Biggers __le32 val; 20698e3ee85eSHerbert Xu int err; 20708e3ee85eSHerbert Xu 20718e3ee85eSHerbert Xu err = alg_test_hash(desc, driver, type, mask); 20728e3ee85eSHerbert Xu if (err) 2073eb5e6730SEric Biggers return err; 20748e3ee85eSHerbert Xu 2075eed93e0cSHerbert Xu tfm = crypto_alloc_shash(driver, type, mask); 20768e3ee85eSHerbert Xu if (IS_ERR(tfm)) { 2077eb5e6730SEric Biggers if (PTR_ERR(tfm) == -ENOENT) { 2078eb5e6730SEric Biggers /* 2079eb5e6730SEric Biggers * This crc32c implementation is only available through 2080eb5e6730SEric Biggers * ahash API, not the shash API, so the remaining part 2081eb5e6730SEric Biggers * of the test is not applicable to it. 2082eb5e6730SEric Biggers */ 2083eb5e6730SEric Biggers return 0; 2084eb5e6730SEric Biggers } 20858e3ee85eSHerbert Xu printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: " 20868e3ee85eSHerbert Xu "%ld\n", driver, PTR_ERR(tfm)); 2087eb5e6730SEric Biggers return PTR_ERR(tfm); 20888e3ee85eSHerbert Xu } 20898e3ee85eSHerbert Xu 20908e3ee85eSHerbert Xu do { 20914c5c3024SJan-Simon Möller SHASH_DESC_ON_STACK(shash, tfm); 20924c5c3024SJan-Simon Möller u32 *ctx = (u32 *)shash_desc_ctx(shash); 20938e3ee85eSHerbert Xu 20944c5c3024SJan-Simon Möller shash->tfm = tfm; 20954c5c3024SJan-Simon Möller shash->flags = 0; 20968e3ee85eSHerbert Xu 2097cb9dde88SEric Biggers *ctx = 420553207; 20984c5c3024SJan-Simon Möller err = crypto_shash_final(shash, (u8 *)&val); 20998e3ee85eSHerbert Xu if (err) { 21008e3ee85eSHerbert Xu printk(KERN_ERR "alg: crc32c: Operation failed for " 21018e3ee85eSHerbert Xu "%s: %d\n", driver, err); 21028e3ee85eSHerbert Xu break; 21038e3ee85eSHerbert Xu } 21048e3ee85eSHerbert Xu 2105cb9dde88SEric Biggers if (val != cpu_to_le32(~420553207)) { 2106cb9dde88SEric Biggers pr_err("alg: crc32c: Test failed for %s: %u\n", 2107cb9dde88SEric Biggers driver, le32_to_cpu(val)); 21088e3ee85eSHerbert Xu err = -EINVAL; 21098e3ee85eSHerbert Xu } 21108e3ee85eSHerbert Xu } while (0); 21118e3ee85eSHerbert Xu 21128e3ee85eSHerbert Xu crypto_free_shash(tfm); 21138e3ee85eSHerbert Xu 21148e3ee85eSHerbert Xu return err; 21158e3ee85eSHerbert Xu } 21168e3ee85eSHerbert Xu 21177647d6ceSJarod Wilson static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, 21187647d6ceSJarod Wilson u32 type, u32 mask) 21197647d6ceSJarod Wilson { 21207647d6ceSJarod Wilson struct crypto_rng *rng; 21217647d6ceSJarod Wilson int err; 21227647d6ceSJarod Wilson 2123eed93e0cSHerbert Xu rng = crypto_alloc_rng(driver, type, mask); 21247647d6ceSJarod Wilson if (IS_ERR(rng)) { 21257647d6ceSJarod Wilson printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " 21267647d6ceSJarod Wilson "%ld\n", driver, PTR_ERR(rng)); 21277647d6ceSJarod Wilson return PTR_ERR(rng); 21287647d6ceSJarod Wilson } 21297647d6ceSJarod Wilson 21307647d6ceSJarod Wilson err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count); 21317647d6ceSJarod Wilson 21327647d6ceSJarod Wilson crypto_free_rng(rng); 21337647d6ceSJarod Wilson 21347647d6ceSJarod Wilson return err; 21357647d6ceSJarod Wilson } 21367647d6ceSJarod Wilson 213764d1cdfbSStephan Mueller 2138b13b1e0cSEric Biggers static int drbg_cavs_test(const struct drbg_testvec *test, int pr, 213964d1cdfbSStephan Mueller const char *driver, u32 type, u32 mask) 214064d1cdfbSStephan Mueller { 214164d1cdfbSStephan Mueller int ret = -EAGAIN; 214264d1cdfbSStephan Mueller struct crypto_rng *drng; 214364d1cdfbSStephan Mueller struct drbg_test_data test_data; 214464d1cdfbSStephan Mueller struct drbg_string addtl, pers, testentropy; 214564d1cdfbSStephan Mueller unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL); 214664d1cdfbSStephan Mueller 214764d1cdfbSStephan Mueller if (!buf) 214864d1cdfbSStephan Mueller return -ENOMEM; 214964d1cdfbSStephan Mueller 2150eed93e0cSHerbert Xu drng = crypto_alloc_rng(driver, type, mask); 215164d1cdfbSStephan Mueller if (IS_ERR(drng)) { 215264d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " 215364d1cdfbSStephan Mueller "%s\n", driver); 215464d1cdfbSStephan Mueller kzfree(buf); 215564d1cdfbSStephan Mueller return -ENOMEM; 215664d1cdfbSStephan Mueller } 215764d1cdfbSStephan Mueller 215864d1cdfbSStephan Mueller test_data.testentropy = &testentropy; 215964d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entropy, test->entropylen); 216064d1cdfbSStephan Mueller drbg_string_fill(&pers, test->pers, test->perslen); 216164d1cdfbSStephan Mueller ret = crypto_drbg_reset_test(drng, &pers, &test_data); 216264d1cdfbSStephan Mueller if (ret) { 216364d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: Failed to reset rng\n"); 216464d1cdfbSStephan Mueller goto outbuf; 216564d1cdfbSStephan Mueller } 216664d1cdfbSStephan Mueller 216764d1cdfbSStephan Mueller drbg_string_fill(&addtl, test->addtla, test->addtllen); 216864d1cdfbSStephan Mueller if (pr) { 216964d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entpra, test->entprlen); 217064d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl_test(drng, 217164d1cdfbSStephan Mueller buf, test->expectedlen, &addtl, &test_data); 217264d1cdfbSStephan Mueller } else { 217364d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl(drng, 217464d1cdfbSStephan Mueller buf, test->expectedlen, &addtl); 217564d1cdfbSStephan Mueller } 217619e60e13SStephan Mueller if (ret < 0) { 217764d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not obtain random data for " 217864d1cdfbSStephan Mueller "driver %s\n", driver); 217964d1cdfbSStephan Mueller goto outbuf; 218064d1cdfbSStephan Mueller } 218164d1cdfbSStephan Mueller 218264d1cdfbSStephan Mueller drbg_string_fill(&addtl, test->addtlb, test->addtllen); 218364d1cdfbSStephan Mueller if (pr) { 218464d1cdfbSStephan Mueller drbg_string_fill(&testentropy, test->entprb, test->entprlen); 218564d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl_test(drng, 218664d1cdfbSStephan Mueller buf, test->expectedlen, &addtl, &test_data); 218764d1cdfbSStephan Mueller } else { 218864d1cdfbSStephan Mueller ret = crypto_drbg_get_bytes_addtl(drng, 218964d1cdfbSStephan Mueller buf, test->expectedlen, &addtl); 219064d1cdfbSStephan Mueller } 219119e60e13SStephan Mueller if (ret < 0) { 219264d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: could not obtain random data for " 219364d1cdfbSStephan Mueller "driver %s\n", driver); 219464d1cdfbSStephan Mueller goto outbuf; 219564d1cdfbSStephan Mueller } 219664d1cdfbSStephan Mueller 219764d1cdfbSStephan Mueller ret = memcmp(test->expected, buf, test->expectedlen); 219864d1cdfbSStephan Mueller 219964d1cdfbSStephan Mueller outbuf: 220064d1cdfbSStephan Mueller crypto_free_rng(drng); 220164d1cdfbSStephan Mueller kzfree(buf); 220264d1cdfbSStephan Mueller return ret; 220364d1cdfbSStephan Mueller } 220464d1cdfbSStephan Mueller 220564d1cdfbSStephan Mueller 220664d1cdfbSStephan Mueller static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, 220764d1cdfbSStephan Mueller u32 type, u32 mask) 220864d1cdfbSStephan Mueller { 220964d1cdfbSStephan Mueller int err = 0; 221064d1cdfbSStephan Mueller int pr = 0; 221164d1cdfbSStephan Mueller int i = 0; 2212b13b1e0cSEric Biggers const struct drbg_testvec *template = desc->suite.drbg.vecs; 221364d1cdfbSStephan Mueller unsigned int tcount = desc->suite.drbg.count; 221464d1cdfbSStephan Mueller 221564d1cdfbSStephan Mueller if (0 == memcmp(driver, "drbg_pr_", 8)) 221664d1cdfbSStephan Mueller pr = 1; 221764d1cdfbSStephan Mueller 221864d1cdfbSStephan Mueller for (i = 0; i < tcount; i++) { 221964d1cdfbSStephan Mueller err = drbg_cavs_test(&template[i], pr, driver, type, mask); 222064d1cdfbSStephan Mueller if (err) { 222164d1cdfbSStephan Mueller printk(KERN_ERR "alg: drbg: Test %d failed for %s\n", 222264d1cdfbSStephan Mueller i, driver); 222364d1cdfbSStephan Mueller err = -EINVAL; 222464d1cdfbSStephan Mueller break; 222564d1cdfbSStephan Mueller } 222664d1cdfbSStephan Mueller } 222764d1cdfbSStephan Mueller return err; 222864d1cdfbSStephan Mueller 222964d1cdfbSStephan Mueller } 223064d1cdfbSStephan Mueller 2231b13b1e0cSEric Biggers static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, 2232802c7f1cSSalvatore Benedetto const char *alg) 2233802c7f1cSSalvatore Benedetto { 2234802c7f1cSSalvatore Benedetto struct kpp_request *req; 2235802c7f1cSSalvatore Benedetto void *input_buf = NULL; 2236802c7f1cSSalvatore Benedetto void *output_buf = NULL; 223747d3fd39STudor-Dan Ambarus void *a_public = NULL; 223847d3fd39STudor-Dan Ambarus void *a_ss = NULL; 223947d3fd39STudor-Dan Ambarus void *shared_secret = NULL; 22407f397136SGilad Ben-Yossef struct crypto_wait wait; 2241802c7f1cSSalvatore Benedetto unsigned int out_len_max; 2242802c7f1cSSalvatore Benedetto int err = -ENOMEM; 2243802c7f1cSSalvatore Benedetto struct scatterlist src, dst; 2244802c7f1cSSalvatore Benedetto 2245802c7f1cSSalvatore Benedetto req = kpp_request_alloc(tfm, GFP_KERNEL); 2246802c7f1cSSalvatore Benedetto if (!req) 2247802c7f1cSSalvatore Benedetto return err; 2248802c7f1cSSalvatore Benedetto 22497f397136SGilad Ben-Yossef crypto_init_wait(&wait); 2250802c7f1cSSalvatore Benedetto 2251802c7f1cSSalvatore Benedetto err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size); 2252802c7f1cSSalvatore Benedetto if (err < 0) 2253802c7f1cSSalvatore Benedetto goto free_req; 2254802c7f1cSSalvatore Benedetto 2255802c7f1cSSalvatore Benedetto out_len_max = crypto_kpp_maxsize(tfm); 2256802c7f1cSSalvatore Benedetto output_buf = kzalloc(out_len_max, GFP_KERNEL); 2257802c7f1cSSalvatore Benedetto if (!output_buf) { 2258802c7f1cSSalvatore Benedetto err = -ENOMEM; 2259802c7f1cSSalvatore Benedetto goto free_req; 2260802c7f1cSSalvatore Benedetto } 2261802c7f1cSSalvatore Benedetto 2262802c7f1cSSalvatore Benedetto /* Use appropriate parameter as base */ 2263802c7f1cSSalvatore Benedetto kpp_request_set_input(req, NULL, 0); 2264802c7f1cSSalvatore Benedetto sg_init_one(&dst, output_buf, out_len_max); 2265802c7f1cSSalvatore Benedetto kpp_request_set_output(req, &dst, out_len_max); 2266802c7f1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 22677f397136SGilad Ben-Yossef crypto_req_done, &wait); 2268802c7f1cSSalvatore Benedetto 226947d3fd39STudor-Dan Ambarus /* Compute party A's public key */ 22707f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait); 2271802c7f1cSSalvatore Benedetto if (err) { 227247d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: generate public key test failed. err %d\n", 2273802c7f1cSSalvatore Benedetto alg, err); 2274802c7f1cSSalvatore Benedetto goto free_output; 2275802c7f1cSSalvatore Benedetto } 227647d3fd39STudor-Dan Ambarus 227747d3fd39STudor-Dan Ambarus if (vec->genkey) { 227847d3fd39STudor-Dan Ambarus /* Save party A's public key */ 2279e3d90e52SChristopher Diaz Riveros a_public = kmemdup(sg_virt(req->dst), out_len_max, GFP_KERNEL); 228047d3fd39STudor-Dan Ambarus if (!a_public) { 228147d3fd39STudor-Dan Ambarus err = -ENOMEM; 228247d3fd39STudor-Dan Ambarus goto free_output; 228347d3fd39STudor-Dan Ambarus } 228447d3fd39STudor-Dan Ambarus } else { 2285802c7f1cSSalvatore Benedetto /* Verify calculated public key */ 2286802c7f1cSSalvatore Benedetto if (memcmp(vec->expected_a_public, sg_virt(req->dst), 2287802c7f1cSSalvatore Benedetto vec->expected_a_public_size)) { 228847d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n", 2289802c7f1cSSalvatore Benedetto alg); 2290802c7f1cSSalvatore Benedetto err = -EINVAL; 2291802c7f1cSSalvatore Benedetto goto free_output; 2292802c7f1cSSalvatore Benedetto } 229347d3fd39STudor-Dan Ambarus } 2294802c7f1cSSalvatore Benedetto 2295802c7f1cSSalvatore Benedetto /* Calculate shared secret key by using counter part (b) public key. */ 2296e3d90e52SChristopher Diaz Riveros input_buf = kmemdup(vec->b_public, vec->b_public_size, GFP_KERNEL); 2297802c7f1cSSalvatore Benedetto if (!input_buf) { 2298802c7f1cSSalvatore Benedetto err = -ENOMEM; 2299802c7f1cSSalvatore Benedetto goto free_output; 2300802c7f1cSSalvatore Benedetto } 2301802c7f1cSSalvatore Benedetto 2302802c7f1cSSalvatore Benedetto sg_init_one(&src, input_buf, vec->b_public_size); 2303802c7f1cSSalvatore Benedetto sg_init_one(&dst, output_buf, out_len_max); 2304802c7f1cSSalvatore Benedetto kpp_request_set_input(req, &src, vec->b_public_size); 2305802c7f1cSSalvatore Benedetto kpp_request_set_output(req, &dst, out_len_max); 2306802c7f1cSSalvatore Benedetto kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 23077f397136SGilad Ben-Yossef crypto_req_done, &wait); 23087f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait); 2309802c7f1cSSalvatore Benedetto if (err) { 231047d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n", 2311802c7f1cSSalvatore Benedetto alg, err); 2312802c7f1cSSalvatore Benedetto goto free_all; 2313802c7f1cSSalvatore Benedetto } 231447d3fd39STudor-Dan Ambarus 231547d3fd39STudor-Dan Ambarus if (vec->genkey) { 231647d3fd39STudor-Dan Ambarus /* Save the shared secret obtained by party A */ 2317e3d90e52SChristopher Diaz Riveros a_ss = kmemdup(sg_virt(req->dst), vec->expected_ss_size, GFP_KERNEL); 231847d3fd39STudor-Dan Ambarus if (!a_ss) { 231947d3fd39STudor-Dan Ambarus err = -ENOMEM; 232047d3fd39STudor-Dan Ambarus goto free_all; 232147d3fd39STudor-Dan Ambarus } 232247d3fd39STudor-Dan Ambarus 232347d3fd39STudor-Dan Ambarus /* 232447d3fd39STudor-Dan Ambarus * Calculate party B's shared secret by using party A's 232547d3fd39STudor-Dan Ambarus * public key. 232647d3fd39STudor-Dan Ambarus */ 232747d3fd39STudor-Dan Ambarus err = crypto_kpp_set_secret(tfm, vec->b_secret, 232847d3fd39STudor-Dan Ambarus vec->b_secret_size); 232947d3fd39STudor-Dan Ambarus if (err < 0) 233047d3fd39STudor-Dan Ambarus goto free_all; 233147d3fd39STudor-Dan Ambarus 233247d3fd39STudor-Dan Ambarus sg_init_one(&src, a_public, vec->expected_a_public_size); 233347d3fd39STudor-Dan Ambarus sg_init_one(&dst, output_buf, out_len_max); 233447d3fd39STudor-Dan Ambarus kpp_request_set_input(req, &src, vec->expected_a_public_size); 233547d3fd39STudor-Dan Ambarus kpp_request_set_output(req, &dst, out_len_max); 233647d3fd39STudor-Dan Ambarus kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 23377f397136SGilad Ben-Yossef crypto_req_done, &wait); 23387f397136SGilad Ben-Yossef err = crypto_wait_req(crypto_kpp_compute_shared_secret(req), 23397f397136SGilad Ben-Yossef &wait); 234047d3fd39STudor-Dan Ambarus if (err) { 234147d3fd39STudor-Dan Ambarus pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", 234247d3fd39STudor-Dan Ambarus alg, err); 234347d3fd39STudor-Dan Ambarus goto free_all; 234447d3fd39STudor-Dan Ambarus } 234547d3fd39STudor-Dan Ambarus 234647d3fd39STudor-Dan Ambarus shared_secret = a_ss; 234747d3fd39STudor-Dan Ambarus } else { 234847d3fd39STudor-Dan Ambarus shared_secret = (void *)vec->expected_ss; 234947d3fd39STudor-Dan Ambarus } 235047d3fd39STudor-Dan Ambarus 2351802c7f1cSSalvatore Benedetto /* 2352802c7f1cSSalvatore Benedetto * verify shared secret from which the user will derive 2353802c7f1cSSalvatore Benedetto * secret key by executing whatever hash it has chosen 2354802c7f1cSSalvatore Benedetto */ 235547d3fd39STudor-Dan Ambarus if (memcmp(shared_secret, sg_virt(req->dst), 2356802c7f1cSSalvatore Benedetto vec->expected_ss_size)) { 2357802c7f1cSSalvatore Benedetto pr_err("alg: %s: compute shared secret test failed. Invalid output\n", 2358802c7f1cSSalvatore Benedetto alg); 2359802c7f1cSSalvatore Benedetto err = -EINVAL; 2360802c7f1cSSalvatore Benedetto } 2361802c7f1cSSalvatore Benedetto 2362802c7f1cSSalvatore Benedetto free_all: 236347d3fd39STudor-Dan Ambarus kfree(a_ss); 2364802c7f1cSSalvatore Benedetto kfree(input_buf); 2365802c7f1cSSalvatore Benedetto free_output: 236647d3fd39STudor-Dan Ambarus kfree(a_public); 2367802c7f1cSSalvatore Benedetto kfree(output_buf); 2368802c7f1cSSalvatore Benedetto free_req: 2369802c7f1cSSalvatore Benedetto kpp_request_free(req); 2370802c7f1cSSalvatore Benedetto return err; 2371802c7f1cSSalvatore Benedetto } 2372802c7f1cSSalvatore Benedetto 2373802c7f1cSSalvatore Benedetto static int test_kpp(struct crypto_kpp *tfm, const char *alg, 2374b13b1e0cSEric Biggers const struct kpp_testvec *vecs, unsigned int tcount) 2375802c7f1cSSalvatore Benedetto { 2376802c7f1cSSalvatore Benedetto int ret, i; 2377802c7f1cSSalvatore Benedetto 2378802c7f1cSSalvatore Benedetto for (i = 0; i < tcount; i++) { 2379802c7f1cSSalvatore Benedetto ret = do_test_kpp(tfm, vecs++, alg); 2380802c7f1cSSalvatore Benedetto if (ret) { 2381802c7f1cSSalvatore Benedetto pr_err("alg: %s: test failed on vector %d, err=%d\n", 2382802c7f1cSSalvatore Benedetto alg, i + 1, ret); 2383802c7f1cSSalvatore Benedetto return ret; 2384802c7f1cSSalvatore Benedetto } 2385802c7f1cSSalvatore Benedetto } 2386802c7f1cSSalvatore Benedetto return 0; 2387802c7f1cSSalvatore Benedetto } 2388802c7f1cSSalvatore Benedetto 2389802c7f1cSSalvatore Benedetto static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, 2390802c7f1cSSalvatore Benedetto u32 type, u32 mask) 2391802c7f1cSSalvatore Benedetto { 2392802c7f1cSSalvatore Benedetto struct crypto_kpp *tfm; 2393802c7f1cSSalvatore Benedetto int err = 0; 2394802c7f1cSSalvatore Benedetto 2395eed93e0cSHerbert Xu tfm = crypto_alloc_kpp(driver, type, mask); 2396802c7f1cSSalvatore Benedetto if (IS_ERR(tfm)) { 2397802c7f1cSSalvatore Benedetto pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", 2398802c7f1cSSalvatore Benedetto driver, PTR_ERR(tfm)); 2399802c7f1cSSalvatore Benedetto return PTR_ERR(tfm); 2400802c7f1cSSalvatore Benedetto } 2401802c7f1cSSalvatore Benedetto if (desc->suite.kpp.vecs) 2402802c7f1cSSalvatore Benedetto err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs, 2403802c7f1cSSalvatore Benedetto desc->suite.kpp.count); 2404802c7f1cSSalvatore Benedetto 2405802c7f1cSSalvatore Benedetto crypto_free_kpp(tfm); 2406802c7f1cSSalvatore Benedetto return err; 2407802c7f1cSSalvatore Benedetto } 2408802c7f1cSSalvatore Benedetto 240950d2b643SHerbert Xu static int test_akcipher_one(struct crypto_akcipher *tfm, 2410b13b1e0cSEric Biggers const struct akcipher_testvec *vecs) 2411946cc463STadeusz Struk { 2412df27b26fSHerbert Xu char *xbuf[XBUFSIZE]; 2413946cc463STadeusz Struk struct akcipher_request *req; 2414946cc463STadeusz Struk void *outbuf_enc = NULL; 2415946cc463STadeusz Struk void *outbuf_dec = NULL; 24167f397136SGilad Ben-Yossef struct crypto_wait wait; 2417946cc463STadeusz Struk unsigned int out_len_max, out_len = 0; 2418946cc463STadeusz Struk int err = -ENOMEM; 241922287b0bSTadeusz Struk struct scatterlist src, dst, src_tab[2]; 24200507de94SVitaly Chikunov const char *m, *c; 24210507de94SVitaly Chikunov unsigned int m_size, c_size; 24220507de94SVitaly Chikunov const char *op; 2423946cc463STadeusz Struk 2424df27b26fSHerbert Xu if (testmgr_alloc_buf(xbuf)) 2425df27b26fSHerbert Xu return err; 2426df27b26fSHerbert Xu 2427946cc463STadeusz Struk req = akcipher_request_alloc(tfm, GFP_KERNEL); 2428946cc463STadeusz Struk if (!req) 2429df27b26fSHerbert Xu goto free_xbuf; 2430946cc463STadeusz Struk 24317f397136SGilad Ben-Yossef crypto_init_wait(&wait); 243222287b0bSTadeusz Struk 243322287b0bSTadeusz Struk if (vecs->public_key_vec) 243422287b0bSTadeusz Struk err = crypto_akcipher_set_pub_key(tfm, vecs->key, 243522287b0bSTadeusz Struk vecs->key_len); 243622287b0bSTadeusz Struk else 243722287b0bSTadeusz Struk err = crypto_akcipher_set_priv_key(tfm, vecs->key, 243822287b0bSTadeusz Struk vecs->key_len); 2439946cc463STadeusz Struk if (err) 2440946cc463STadeusz Struk goto free_req; 2441946cc463STadeusz Struk 244257763f5eSSalvatore Benedetto err = -ENOMEM; 244322287b0bSTadeusz Struk out_len_max = crypto_akcipher_maxsize(tfm); 24440507de94SVitaly Chikunov 24450507de94SVitaly Chikunov /* 24460507de94SVitaly Chikunov * First run test which do not require a private key, such as 24470507de94SVitaly Chikunov * encrypt or verify. 24480507de94SVitaly Chikunov */ 2449946cc463STadeusz Struk outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); 2450946cc463STadeusz Struk if (!outbuf_enc) 2451946cc463STadeusz Struk goto free_req; 2452946cc463STadeusz Struk 24530507de94SVitaly Chikunov if (!vecs->siggen_sigver_test) { 24540507de94SVitaly Chikunov m = vecs->m; 24550507de94SVitaly Chikunov m_size = vecs->m_size; 24560507de94SVitaly Chikunov c = vecs->c; 24570507de94SVitaly Chikunov c_size = vecs->c_size; 24580507de94SVitaly Chikunov op = "encrypt"; 24590507de94SVitaly Chikunov } else { 24600507de94SVitaly Chikunov /* Swap args so we could keep plaintext (digest) 24610507de94SVitaly Chikunov * in vecs->m, and cooked signature in vecs->c. 24620507de94SVitaly Chikunov */ 24630507de94SVitaly Chikunov m = vecs->c; /* signature */ 24640507de94SVitaly Chikunov m_size = vecs->c_size; 24650507de94SVitaly Chikunov c = vecs->m; /* digest */ 24660507de94SVitaly Chikunov c_size = vecs->m_size; 24670507de94SVitaly Chikunov op = "verify"; 24680507de94SVitaly Chikunov } 2469df27b26fSHerbert Xu 24700507de94SVitaly Chikunov if (WARN_ON(m_size > PAGE_SIZE)) 24710507de94SVitaly Chikunov goto free_all; 24720507de94SVitaly Chikunov memcpy(xbuf[0], m, m_size); 2473df27b26fSHerbert Xu 247422287b0bSTadeusz Struk sg_init_table(src_tab, 2); 2475df27b26fSHerbert Xu sg_set_buf(&src_tab[0], xbuf[0], 8); 24760507de94SVitaly Chikunov sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8); 247722287b0bSTadeusz Struk sg_init_one(&dst, outbuf_enc, out_len_max); 24780507de94SVitaly Chikunov akcipher_request_set_crypt(req, src_tab, &dst, m_size, 247922287b0bSTadeusz Struk out_len_max); 2480946cc463STadeusz Struk akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 24817f397136SGilad Ben-Yossef crypto_req_done, &wait); 2482946cc463STadeusz Struk 24837f397136SGilad Ben-Yossef err = crypto_wait_req(vecs->siggen_sigver_test ? 24840507de94SVitaly Chikunov /* Run asymmetric signature verification */ 24850507de94SVitaly Chikunov crypto_akcipher_verify(req) : 24861207107cSStephan Mueller /* Run asymmetric encrypt */ 24877f397136SGilad Ben-Yossef crypto_akcipher_encrypt(req), &wait); 2488946cc463STadeusz Struk if (err) { 24890507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 2490946cc463STadeusz Struk goto free_all; 2491946cc463STadeusz Struk } 24920507de94SVitaly Chikunov if (req->dst_len != c_size) { 24930507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output len\n", 24940507de94SVitaly Chikunov op); 2495946cc463STadeusz Struk err = -EINVAL; 2496946cc463STadeusz Struk goto free_all; 2497946cc463STadeusz Struk } 2498946cc463STadeusz Struk /* verify that encrypted message is equal to expected */ 24990507de94SVitaly Chikunov if (memcmp(c, outbuf_enc, c_size)) { 25000507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 25010507de94SVitaly Chikunov hexdump(outbuf_enc, c_size); 2502946cc463STadeusz Struk err = -EINVAL; 2503946cc463STadeusz Struk goto free_all; 2504946cc463STadeusz Struk } 25050507de94SVitaly Chikunov 25060507de94SVitaly Chikunov /* 25070507de94SVitaly Chikunov * Don't invoke (decrypt or sign) test which require a private key 25080507de94SVitaly Chikunov * for vectors with only a public key. 25090507de94SVitaly Chikunov */ 2510946cc463STadeusz Struk if (vecs->public_key_vec) { 2511946cc463STadeusz Struk err = 0; 2512946cc463STadeusz Struk goto free_all; 2513946cc463STadeusz Struk } 2514946cc463STadeusz Struk outbuf_dec = kzalloc(out_len_max, GFP_KERNEL); 2515946cc463STadeusz Struk if (!outbuf_dec) { 2516946cc463STadeusz Struk err = -ENOMEM; 2517946cc463STadeusz Struk goto free_all; 2518946cc463STadeusz Struk } 2519df27b26fSHerbert Xu 25200507de94SVitaly Chikunov op = vecs->siggen_sigver_test ? "sign" : "decrypt"; 25210507de94SVitaly Chikunov if (WARN_ON(c_size > PAGE_SIZE)) 2522df27b26fSHerbert Xu goto free_all; 25230507de94SVitaly Chikunov memcpy(xbuf[0], c, c_size); 2524df27b26fSHerbert Xu 25250507de94SVitaly Chikunov sg_init_one(&src, xbuf[0], c_size); 252622287b0bSTadeusz Struk sg_init_one(&dst, outbuf_dec, out_len_max); 25277f397136SGilad Ben-Yossef crypto_init_wait(&wait); 25280507de94SVitaly Chikunov akcipher_request_set_crypt(req, &src, &dst, c_size, out_len_max); 2529946cc463STadeusz Struk 25307f397136SGilad Ben-Yossef err = crypto_wait_req(vecs->siggen_sigver_test ? 25310507de94SVitaly Chikunov /* Run asymmetric signature generation */ 25320507de94SVitaly Chikunov crypto_akcipher_sign(req) : 25331207107cSStephan Mueller /* Run asymmetric decrypt */ 25347f397136SGilad Ben-Yossef crypto_akcipher_decrypt(req), &wait); 2535946cc463STadeusz Struk if (err) { 25360507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 2537946cc463STadeusz Struk goto free_all; 2538946cc463STadeusz Struk } 2539946cc463STadeusz Struk out_len = req->dst_len; 25400507de94SVitaly Chikunov if (out_len < m_size) { 25410507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output len %u\n", 25420507de94SVitaly Chikunov op, out_len); 2543946cc463STadeusz Struk err = -EINVAL; 2544946cc463STadeusz Struk goto free_all; 2545946cc463STadeusz Struk } 2546946cc463STadeusz Struk /* verify that decrypted message is equal to the original msg */ 25470507de94SVitaly Chikunov if (memchr_inv(outbuf_dec, 0, out_len - m_size) || 25480507de94SVitaly Chikunov memcmp(m, outbuf_dec + out_len - m_size, m_size)) { 25490507de94SVitaly Chikunov pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 255050d2b643SHerbert Xu hexdump(outbuf_dec, out_len); 2551946cc463STadeusz Struk err = -EINVAL; 2552946cc463STadeusz Struk } 2553946cc463STadeusz Struk free_all: 2554946cc463STadeusz Struk kfree(outbuf_dec); 2555946cc463STadeusz Struk kfree(outbuf_enc); 2556946cc463STadeusz Struk free_req: 2557946cc463STadeusz Struk akcipher_request_free(req); 2558df27b26fSHerbert Xu free_xbuf: 2559df27b26fSHerbert Xu testmgr_free_buf(xbuf); 2560946cc463STadeusz Struk return err; 2561946cc463STadeusz Struk } 2562946cc463STadeusz Struk 256350d2b643SHerbert Xu static int test_akcipher(struct crypto_akcipher *tfm, const char *alg, 2564b13b1e0cSEric Biggers const struct akcipher_testvec *vecs, 2565b13b1e0cSEric Biggers unsigned int tcount) 2566946cc463STadeusz Struk { 256715226e48SHerbert Xu const char *algo = 256815226e48SHerbert Xu crypto_tfm_alg_driver_name(crypto_akcipher_tfm(tfm)); 2569946cc463STadeusz Struk int ret, i; 2570946cc463STadeusz Struk 2571946cc463STadeusz Struk for (i = 0; i < tcount; i++) { 257250d2b643SHerbert Xu ret = test_akcipher_one(tfm, vecs++); 257350d2b643SHerbert Xu if (!ret) 257450d2b643SHerbert Xu continue; 257550d2b643SHerbert Xu 257615226e48SHerbert Xu pr_err("alg: akcipher: test %d failed for %s, err=%d\n", 257715226e48SHerbert Xu i + 1, algo, ret); 2578946cc463STadeusz Struk return ret; 2579946cc463STadeusz Struk } 2580946cc463STadeusz Struk return 0; 2581946cc463STadeusz Struk } 2582946cc463STadeusz Struk 2583946cc463STadeusz Struk static int alg_test_akcipher(const struct alg_test_desc *desc, 2584946cc463STadeusz Struk const char *driver, u32 type, u32 mask) 2585946cc463STadeusz Struk { 2586946cc463STadeusz Struk struct crypto_akcipher *tfm; 2587946cc463STadeusz Struk int err = 0; 2588946cc463STadeusz Struk 2589eed93e0cSHerbert Xu tfm = crypto_alloc_akcipher(driver, type, mask); 2590946cc463STadeusz Struk if (IS_ERR(tfm)) { 2591946cc463STadeusz Struk pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", 2592946cc463STadeusz Struk driver, PTR_ERR(tfm)); 2593946cc463STadeusz Struk return PTR_ERR(tfm); 2594946cc463STadeusz Struk } 2595946cc463STadeusz Struk if (desc->suite.akcipher.vecs) 2596946cc463STadeusz Struk err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs, 2597946cc463STadeusz Struk desc->suite.akcipher.count); 2598946cc463STadeusz Struk 2599946cc463STadeusz Struk crypto_free_akcipher(tfm); 2600946cc463STadeusz Struk return err; 2601946cc463STadeusz Struk } 2602946cc463STadeusz Struk 2603863b557aSYouquan, Song static int alg_test_null(const struct alg_test_desc *desc, 2604863b557aSYouquan, Song const char *driver, u32 type, u32 mask) 2605863b557aSYouquan, Song { 2606863b557aSYouquan, Song return 0; 2607863b557aSYouquan, Song } 2608863b557aSYouquan, Song 260921c8e720SArd Biesheuvel #define __VECS(tv) { .vecs = tv, .count = ARRAY_SIZE(tv) } 261021c8e720SArd Biesheuvel 2611da7f033dSHerbert Xu /* Please keep this list sorted by algorithm name. */ 2612da7f033dSHerbert Xu static const struct alg_test_desc alg_test_descs[] = { 2613da7f033dSHerbert Xu { 2614059c2a4dSEric Biggers .alg = "adiantum(xchacha12,aes)", 2615059c2a4dSEric Biggers .test = alg_test_skcipher, 2616059c2a4dSEric Biggers .suite = { 2617059c2a4dSEric Biggers .cipher = __VECS(adiantum_xchacha12_aes_tv_template) 2618059c2a4dSEric Biggers }, 2619059c2a4dSEric Biggers }, { 2620059c2a4dSEric Biggers .alg = "adiantum(xchacha20,aes)", 2621059c2a4dSEric Biggers .test = alg_test_skcipher, 2622059c2a4dSEric Biggers .suite = { 2623059c2a4dSEric Biggers .cipher = __VECS(adiantum_xchacha20_aes_tv_template) 2624059c2a4dSEric Biggers }, 2625059c2a4dSEric Biggers }, { 2626b87dc203SOndrej Mosnacek .alg = "aegis128", 2627b87dc203SOndrej Mosnacek .test = alg_test_aead, 2628b87dc203SOndrej Mosnacek .suite = { 2629a0d608eeSEric Biggers .aead = __VECS(aegis128_tv_template) 2630b87dc203SOndrej Mosnacek } 2631b87dc203SOndrej Mosnacek }, { 2632b87dc203SOndrej Mosnacek .alg = "aegis128l", 2633b87dc203SOndrej Mosnacek .test = alg_test_aead, 2634b87dc203SOndrej Mosnacek .suite = { 2635a0d608eeSEric Biggers .aead = __VECS(aegis128l_tv_template) 2636b87dc203SOndrej Mosnacek } 2637b87dc203SOndrej Mosnacek }, { 2638b87dc203SOndrej Mosnacek .alg = "aegis256", 2639b87dc203SOndrej Mosnacek .test = alg_test_aead, 2640b87dc203SOndrej Mosnacek .suite = { 2641a0d608eeSEric Biggers .aead = __VECS(aegis256_tv_template) 2642b87dc203SOndrej Mosnacek } 2643b87dc203SOndrej Mosnacek }, { 2644e08ca2daSJarod Wilson .alg = "ansi_cprng", 2645e08ca2daSJarod Wilson .test = alg_test_cprng, 2646e08ca2daSJarod Wilson .suite = { 264721c8e720SArd Biesheuvel .cprng = __VECS(ansi_cprng_aes_tv_template) 2648e08ca2daSJarod Wilson } 2649e08ca2daSJarod Wilson }, { 2650bca4feb0SHoria Geanta .alg = "authenc(hmac(md5),ecb(cipher_null))", 2651bca4feb0SHoria Geanta .test = alg_test_aead, 2652bca4feb0SHoria Geanta .suite = { 2653a0d608eeSEric Biggers .aead = __VECS(hmac_md5_ecb_cipher_null_tv_template) 2654bca4feb0SHoria Geanta } 2655bca4feb0SHoria Geanta }, { 2656a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(aes))", 2657e46e9a46SHoria Geanta .test = alg_test_aead, 2658bcf741cbSHerbert Xu .fips_allowed = 1, 2659e46e9a46SHoria Geanta .suite = { 2660a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_aes_cbc_tv_temp) 26615208ed2cSNitesh Lal } 26625208ed2cSNitesh Lal }, { 2663a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(des))", 26645208ed2cSNitesh Lal .test = alg_test_aead, 26655208ed2cSNitesh Lal .suite = { 2666a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_des_cbc_tv_temp) 26675208ed2cSNitesh Lal } 26685208ed2cSNitesh Lal }, { 2669a4198fd4SHerbert Xu .alg = "authenc(hmac(sha1),cbc(des3_ede))", 26705208ed2cSNitesh Lal .test = alg_test_aead, 2671ed1afac9SMarcus Meissner .fips_allowed = 1, 26725208ed2cSNitesh Lal .suite = { 2673a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp) 2674e46e9a46SHoria Geanta } 2675e46e9a46SHoria Geanta }, { 2676fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha1),ctr(aes))", 2677fb16abc2SMarcus Meissner .test = alg_test_null, 2678fb16abc2SMarcus Meissner .fips_allowed = 1, 2679fb16abc2SMarcus Meissner }, { 2680bca4feb0SHoria Geanta .alg = "authenc(hmac(sha1),ecb(cipher_null))", 2681bca4feb0SHoria Geanta .test = alg_test_aead, 2682bca4feb0SHoria Geanta .suite = { 2683a0d608eeSEric Biggers .aead = __VECS(hmac_sha1_ecb_cipher_null_tv_temp) 26845208ed2cSNitesh Lal } 26855208ed2cSNitesh Lal }, { 26868888690eSMarcus Meissner .alg = "authenc(hmac(sha1),rfc3686(ctr(aes)))", 26878888690eSMarcus Meissner .test = alg_test_null, 26888888690eSMarcus Meissner .fips_allowed = 1, 26898888690eSMarcus Meissner }, { 2690a4198fd4SHerbert Xu .alg = "authenc(hmac(sha224),cbc(des))", 26915208ed2cSNitesh Lal .test = alg_test_aead, 26925208ed2cSNitesh Lal .suite = { 2693a0d608eeSEric Biggers .aead = __VECS(hmac_sha224_des_cbc_tv_temp) 26945208ed2cSNitesh Lal } 26955208ed2cSNitesh Lal }, { 2696a4198fd4SHerbert Xu .alg = "authenc(hmac(sha224),cbc(des3_ede))", 26975208ed2cSNitesh Lal .test = alg_test_aead, 2698ed1afac9SMarcus Meissner .fips_allowed = 1, 26995208ed2cSNitesh Lal .suite = { 2700a0d608eeSEric Biggers .aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp) 2701bca4feb0SHoria Geanta } 2702bca4feb0SHoria Geanta }, { 2703a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(aes))", 2704e46e9a46SHoria Geanta .test = alg_test_aead, 2705ed1afac9SMarcus Meissner .fips_allowed = 1, 2706e46e9a46SHoria Geanta .suite = { 2707a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_aes_cbc_tv_temp) 27085208ed2cSNitesh Lal } 27095208ed2cSNitesh Lal }, { 2710a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(des))", 27115208ed2cSNitesh Lal .test = alg_test_aead, 27125208ed2cSNitesh Lal .suite = { 2713a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_des_cbc_tv_temp) 27145208ed2cSNitesh Lal } 27155208ed2cSNitesh Lal }, { 2716a4198fd4SHerbert Xu .alg = "authenc(hmac(sha256),cbc(des3_ede))", 27175208ed2cSNitesh Lal .test = alg_test_aead, 2718ed1afac9SMarcus Meissner .fips_allowed = 1, 27195208ed2cSNitesh Lal .suite = { 2720a0d608eeSEric Biggers .aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp) 27215208ed2cSNitesh Lal } 27225208ed2cSNitesh Lal }, { 2723fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha256),ctr(aes))", 2724fb16abc2SMarcus Meissner .test = alg_test_null, 2725fb16abc2SMarcus Meissner .fips_allowed = 1, 2726fb16abc2SMarcus Meissner }, { 27278888690eSMarcus Meissner .alg = "authenc(hmac(sha256),rfc3686(ctr(aes)))", 27288888690eSMarcus Meissner .test = alg_test_null, 27298888690eSMarcus Meissner .fips_allowed = 1, 27308888690eSMarcus Meissner }, { 2731a4198fd4SHerbert Xu .alg = "authenc(hmac(sha384),cbc(des))", 27325208ed2cSNitesh Lal .test = alg_test_aead, 27335208ed2cSNitesh Lal .suite = { 2734a0d608eeSEric Biggers .aead = __VECS(hmac_sha384_des_cbc_tv_temp) 27355208ed2cSNitesh Lal } 27365208ed2cSNitesh Lal }, { 2737a4198fd4SHerbert Xu .alg = "authenc(hmac(sha384),cbc(des3_ede))", 27385208ed2cSNitesh Lal .test = alg_test_aead, 2739ed1afac9SMarcus Meissner .fips_allowed = 1, 27405208ed2cSNitesh Lal .suite = { 2741a0d608eeSEric Biggers .aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp) 2742e46e9a46SHoria Geanta } 2743e46e9a46SHoria Geanta }, { 2744fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha384),ctr(aes))", 2745fb16abc2SMarcus Meissner .test = alg_test_null, 2746fb16abc2SMarcus Meissner .fips_allowed = 1, 2747fb16abc2SMarcus Meissner }, { 27488888690eSMarcus Meissner .alg = "authenc(hmac(sha384),rfc3686(ctr(aes)))", 27498888690eSMarcus Meissner .test = alg_test_null, 27508888690eSMarcus Meissner .fips_allowed = 1, 27518888690eSMarcus Meissner }, { 2752a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(aes))", 2753ed1afac9SMarcus Meissner .fips_allowed = 1, 2754e46e9a46SHoria Geanta .test = alg_test_aead, 2755e46e9a46SHoria Geanta .suite = { 2756a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_aes_cbc_tv_temp) 27575208ed2cSNitesh Lal } 27585208ed2cSNitesh Lal }, { 2759a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(des))", 27605208ed2cSNitesh Lal .test = alg_test_aead, 27615208ed2cSNitesh Lal .suite = { 2762a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_des_cbc_tv_temp) 27635208ed2cSNitesh Lal } 27645208ed2cSNitesh Lal }, { 2765a4198fd4SHerbert Xu .alg = "authenc(hmac(sha512),cbc(des3_ede))", 27665208ed2cSNitesh Lal .test = alg_test_aead, 2767ed1afac9SMarcus Meissner .fips_allowed = 1, 27685208ed2cSNitesh Lal .suite = { 2769a0d608eeSEric Biggers .aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp) 2770e46e9a46SHoria Geanta } 2771e46e9a46SHoria Geanta }, { 2772fb16abc2SMarcus Meissner .alg = "authenc(hmac(sha512),ctr(aes))", 2773fb16abc2SMarcus Meissner .test = alg_test_null, 2774fb16abc2SMarcus Meissner .fips_allowed = 1, 2775fb16abc2SMarcus Meissner }, { 27768888690eSMarcus Meissner .alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))", 27778888690eSMarcus Meissner .test = alg_test_null, 27788888690eSMarcus Meissner .fips_allowed = 1, 27798888690eSMarcus Meissner }, { 2780da7f033dSHerbert Xu .alg = "cbc(aes)", 27811aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2782a1915d51SJarod Wilson .fips_allowed = 1, 2783da7f033dSHerbert Xu .suite = { 278492a4c9feSEric Biggers .cipher = __VECS(aes_cbc_tv_template) 278592a4c9feSEric Biggers }, 2786da7f033dSHerbert Xu }, { 2787da7f033dSHerbert Xu .alg = "cbc(anubis)", 27881aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2789da7f033dSHerbert Xu .suite = { 279092a4c9feSEric Biggers .cipher = __VECS(anubis_cbc_tv_template) 279192a4c9feSEric Biggers }, 2792da7f033dSHerbert Xu }, { 2793da7f033dSHerbert Xu .alg = "cbc(blowfish)", 27941aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2795da7f033dSHerbert Xu .suite = { 279692a4c9feSEric Biggers .cipher = __VECS(bf_cbc_tv_template) 279792a4c9feSEric Biggers }, 2798da7f033dSHerbert Xu }, { 2799da7f033dSHerbert Xu .alg = "cbc(camellia)", 28001aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2801da7f033dSHerbert Xu .suite = { 280292a4c9feSEric Biggers .cipher = __VECS(camellia_cbc_tv_template) 280392a4c9feSEric Biggers }, 2804da7f033dSHerbert Xu }, { 2805a2c58260SJohannes Goetzfried .alg = "cbc(cast5)", 2806a2c58260SJohannes Goetzfried .test = alg_test_skcipher, 2807a2c58260SJohannes Goetzfried .suite = { 280892a4c9feSEric Biggers .cipher = __VECS(cast5_cbc_tv_template) 280992a4c9feSEric Biggers }, 2810a2c58260SJohannes Goetzfried }, { 28119b8b0405SJohannes Goetzfried .alg = "cbc(cast6)", 28129b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 28139b8b0405SJohannes Goetzfried .suite = { 281492a4c9feSEric Biggers .cipher = __VECS(cast6_cbc_tv_template) 281592a4c9feSEric Biggers }, 28169b8b0405SJohannes Goetzfried }, { 2817da7f033dSHerbert Xu .alg = "cbc(des)", 28181aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2819da7f033dSHerbert Xu .suite = { 282092a4c9feSEric Biggers .cipher = __VECS(des_cbc_tv_template) 282192a4c9feSEric Biggers }, 2822da7f033dSHerbert Xu }, { 2823da7f033dSHerbert Xu .alg = "cbc(des3_ede)", 28241aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2825a1915d51SJarod Wilson .fips_allowed = 1, 2826da7f033dSHerbert Xu .suite = { 282792a4c9feSEric Biggers .cipher = __VECS(des3_ede_cbc_tv_template) 282892a4c9feSEric Biggers }, 2829da7f033dSHerbert Xu }, { 2830a794d8d8SGilad Ben-Yossef /* Same as cbc(aes) except the key is stored in 2831a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 2832a794d8d8SGilad Ben-Yossef */ 2833a794d8d8SGilad Ben-Yossef .alg = "cbc(paes)", 2834a794d8d8SGilad Ben-Yossef .test = alg_test_null, 2835a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 2836a794d8d8SGilad Ben-Yossef }, { 28379d25917dSJussi Kivilinna .alg = "cbc(serpent)", 28389d25917dSJussi Kivilinna .test = alg_test_skcipher, 28399d25917dSJussi Kivilinna .suite = { 284092a4c9feSEric Biggers .cipher = __VECS(serpent_cbc_tv_template) 284192a4c9feSEric Biggers }, 28429d25917dSJussi Kivilinna }, { 284395ba5973SGilad Ben-Yossef .alg = "cbc(sm4)", 284495ba5973SGilad Ben-Yossef .test = alg_test_skcipher, 284595ba5973SGilad Ben-Yossef .suite = { 284695ba5973SGilad Ben-Yossef .cipher = __VECS(sm4_cbc_tv_template) 284795ba5973SGilad Ben-Yossef } 284895ba5973SGilad Ben-Yossef }, { 2849da7f033dSHerbert Xu .alg = "cbc(twofish)", 28501aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2851da7f033dSHerbert Xu .suite = { 285292a4c9feSEric Biggers .cipher = __VECS(tf_cbc_tv_template) 285392a4c9feSEric Biggers }, 2854da7f033dSHerbert Xu }, { 2855092acf06SArd Biesheuvel .alg = "cbcmac(aes)", 2856092acf06SArd Biesheuvel .fips_allowed = 1, 2857092acf06SArd Biesheuvel .test = alg_test_hash, 2858092acf06SArd Biesheuvel .suite = { 2859092acf06SArd Biesheuvel .hash = __VECS(aes_cbcmac_tv_template) 2860092acf06SArd Biesheuvel } 2861092acf06SArd Biesheuvel }, { 2862da7f033dSHerbert Xu .alg = "ccm(aes)", 2863da7f033dSHerbert Xu .test = alg_test_aead, 2864a1915d51SJarod Wilson .fips_allowed = 1, 2865da7f033dSHerbert Xu .suite = { 2866a0d608eeSEric Biggers .aead = __VECS(aes_ccm_tv_template) 2867da7f033dSHerbert Xu } 2868da7f033dSHerbert Xu }, { 28697da66670SDmitry Eremin-Solenikov .alg = "cfb(aes)", 28707da66670SDmitry Eremin-Solenikov .test = alg_test_skcipher, 28717da66670SDmitry Eremin-Solenikov .fips_allowed = 1, 28727da66670SDmitry Eremin-Solenikov .suite = { 28737da66670SDmitry Eremin-Solenikov .cipher = __VECS(aes_cfb_tv_template) 28747da66670SDmitry Eremin-Solenikov }, 28757da66670SDmitry Eremin-Solenikov }, { 28763590ebf2SMartin Willi .alg = "chacha20", 28773590ebf2SMartin Willi .test = alg_test_skcipher, 28783590ebf2SMartin Willi .suite = { 287992a4c9feSEric Biggers .cipher = __VECS(chacha20_tv_template) 288092a4c9feSEric Biggers }, 28813590ebf2SMartin Willi }, { 288293b5e86aSJussi Kivilinna .alg = "cmac(aes)", 28838f183751SStephan Mueller .fips_allowed = 1, 288493b5e86aSJussi Kivilinna .test = alg_test_hash, 288593b5e86aSJussi Kivilinna .suite = { 288621c8e720SArd Biesheuvel .hash = __VECS(aes_cmac128_tv_template) 288793b5e86aSJussi Kivilinna } 288893b5e86aSJussi Kivilinna }, { 288993b5e86aSJussi Kivilinna .alg = "cmac(des3_ede)", 28908f183751SStephan Mueller .fips_allowed = 1, 289193b5e86aSJussi Kivilinna .test = alg_test_hash, 289293b5e86aSJussi Kivilinna .suite = { 289321c8e720SArd Biesheuvel .hash = __VECS(des3_ede_cmac64_tv_template) 289493b5e86aSJussi Kivilinna } 289593b5e86aSJussi Kivilinna }, { 2896e448370dSJussi Kivilinna .alg = "compress_null", 2897e448370dSJussi Kivilinna .test = alg_test_null, 2898e448370dSJussi Kivilinna }, { 2899ebb3472fSArd Biesheuvel .alg = "crc32", 2900ebb3472fSArd Biesheuvel .test = alg_test_hash, 2901a8a34416SMilan Broz .fips_allowed = 1, 2902ebb3472fSArd Biesheuvel .suite = { 290321c8e720SArd Biesheuvel .hash = __VECS(crc32_tv_template) 2904ebb3472fSArd Biesheuvel } 2905ebb3472fSArd Biesheuvel }, { 2906da7f033dSHerbert Xu .alg = "crc32c", 29078e3ee85eSHerbert Xu .test = alg_test_crc32c, 2908a1915d51SJarod Wilson .fips_allowed = 1, 2909da7f033dSHerbert Xu .suite = { 291021c8e720SArd Biesheuvel .hash = __VECS(crc32c_tv_template) 2911da7f033dSHerbert Xu } 2912da7f033dSHerbert Xu }, { 291368411521SHerbert Xu .alg = "crct10dif", 291468411521SHerbert Xu .test = alg_test_hash, 291568411521SHerbert Xu .fips_allowed = 1, 291668411521SHerbert Xu .suite = { 291721c8e720SArd Biesheuvel .hash = __VECS(crct10dif_tv_template) 291868411521SHerbert Xu } 291968411521SHerbert Xu }, { 2920f7cb80f2SJarod Wilson .alg = "ctr(aes)", 2921f7cb80f2SJarod Wilson .test = alg_test_skcipher, 2922a1915d51SJarod Wilson .fips_allowed = 1, 2923f7cb80f2SJarod Wilson .suite = { 292492a4c9feSEric Biggers .cipher = __VECS(aes_ctr_tv_template) 2925f7cb80f2SJarod Wilson } 2926f7cb80f2SJarod Wilson }, { 292785b63e34SJussi Kivilinna .alg = "ctr(blowfish)", 292885b63e34SJussi Kivilinna .test = alg_test_skcipher, 292985b63e34SJussi Kivilinna .suite = { 293092a4c9feSEric Biggers .cipher = __VECS(bf_ctr_tv_template) 293185b63e34SJussi Kivilinna } 293285b63e34SJussi Kivilinna }, { 29330840605eSJussi Kivilinna .alg = "ctr(camellia)", 29340840605eSJussi Kivilinna .test = alg_test_skcipher, 29350840605eSJussi Kivilinna .suite = { 293692a4c9feSEric Biggers .cipher = __VECS(camellia_ctr_tv_template) 29370840605eSJussi Kivilinna } 29380840605eSJussi Kivilinna }, { 2939a2c58260SJohannes Goetzfried .alg = "ctr(cast5)", 2940a2c58260SJohannes Goetzfried .test = alg_test_skcipher, 2941a2c58260SJohannes Goetzfried .suite = { 294292a4c9feSEric Biggers .cipher = __VECS(cast5_ctr_tv_template) 2943a2c58260SJohannes Goetzfried } 2944a2c58260SJohannes Goetzfried }, { 29459b8b0405SJohannes Goetzfried .alg = "ctr(cast6)", 29469b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 29479b8b0405SJohannes Goetzfried .suite = { 294892a4c9feSEric Biggers .cipher = __VECS(cast6_ctr_tv_template) 29499b8b0405SJohannes Goetzfried } 29509b8b0405SJohannes Goetzfried }, { 29518163fc30SJussi Kivilinna .alg = "ctr(des)", 29528163fc30SJussi Kivilinna .test = alg_test_skcipher, 29538163fc30SJussi Kivilinna .suite = { 295492a4c9feSEric Biggers .cipher = __VECS(des_ctr_tv_template) 29558163fc30SJussi Kivilinna } 29568163fc30SJussi Kivilinna }, { 2957e080b17aSJussi Kivilinna .alg = "ctr(des3_ede)", 2958e080b17aSJussi Kivilinna .test = alg_test_skcipher, 29590d8da104SMarcelo Cerri .fips_allowed = 1, 2960e080b17aSJussi Kivilinna .suite = { 296192a4c9feSEric Biggers .cipher = __VECS(des3_ede_ctr_tv_template) 2962e080b17aSJussi Kivilinna } 2963e080b17aSJussi Kivilinna }, { 2964a794d8d8SGilad Ben-Yossef /* Same as ctr(aes) except the key is stored in 2965a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 2966a794d8d8SGilad Ben-Yossef */ 2967a794d8d8SGilad Ben-Yossef .alg = "ctr(paes)", 2968a794d8d8SGilad Ben-Yossef .test = alg_test_null, 2969a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 2970a794d8d8SGilad Ben-Yossef }, { 29719d25917dSJussi Kivilinna .alg = "ctr(serpent)", 29729d25917dSJussi Kivilinna .test = alg_test_skcipher, 29739d25917dSJussi Kivilinna .suite = { 297492a4c9feSEric Biggers .cipher = __VECS(serpent_ctr_tv_template) 29759d25917dSJussi Kivilinna } 29769d25917dSJussi Kivilinna }, { 297795ba5973SGilad Ben-Yossef .alg = "ctr(sm4)", 297895ba5973SGilad Ben-Yossef .test = alg_test_skcipher, 297995ba5973SGilad Ben-Yossef .suite = { 298095ba5973SGilad Ben-Yossef .cipher = __VECS(sm4_ctr_tv_template) 298195ba5973SGilad Ben-Yossef } 298295ba5973SGilad Ben-Yossef }, { 2983573da620SJussi Kivilinna .alg = "ctr(twofish)", 2984573da620SJussi Kivilinna .test = alg_test_skcipher, 2985573da620SJussi Kivilinna .suite = { 298692a4c9feSEric Biggers .cipher = __VECS(tf_ctr_tv_template) 2987573da620SJussi Kivilinna } 2988573da620SJussi Kivilinna }, { 2989da7f033dSHerbert Xu .alg = "cts(cbc(aes))", 29901aa4ecd9SHerbert Xu .test = alg_test_skcipher, 2991196ad604SGilad Ben-Yossef .fips_allowed = 1, 2992da7f033dSHerbert Xu .suite = { 299392a4c9feSEric Biggers .cipher = __VECS(cts_mode_tv_template) 2994da7f033dSHerbert Xu } 2995da7f033dSHerbert Xu }, { 2996da7f033dSHerbert Xu .alg = "deflate", 2997da7f033dSHerbert Xu .test = alg_test_comp, 29980818904dSMilan Broz .fips_allowed = 1, 2999da7f033dSHerbert Xu .suite = { 3000da7f033dSHerbert Xu .comp = { 300121c8e720SArd Biesheuvel .comp = __VECS(deflate_comp_tv_template), 300221c8e720SArd Biesheuvel .decomp = __VECS(deflate_decomp_tv_template) 3003da7f033dSHerbert Xu } 3004da7f033dSHerbert Xu } 3005da7f033dSHerbert Xu }, { 3006802c7f1cSSalvatore Benedetto .alg = "dh", 3007802c7f1cSSalvatore Benedetto .test = alg_test_kpp, 3008802c7f1cSSalvatore Benedetto .fips_allowed = 1, 3009802c7f1cSSalvatore Benedetto .suite = { 301021c8e720SArd Biesheuvel .kpp = __VECS(dh_tv_template) 3011802c7f1cSSalvatore Benedetto } 3012802c7f1cSSalvatore Benedetto }, { 3013e448370dSJussi Kivilinna .alg = "digest_null", 3014e448370dSJussi Kivilinna .test = alg_test_null, 3015e448370dSJussi Kivilinna }, { 301664d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes128", 301764d1cdfbSStephan Mueller .test = alg_test_drbg, 301864d1cdfbSStephan Mueller .fips_allowed = 1, 301964d1cdfbSStephan Mueller .suite = { 302021c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes128_tv_template) 302164d1cdfbSStephan Mueller } 302264d1cdfbSStephan Mueller }, { 302364d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes192", 302464d1cdfbSStephan Mueller .test = alg_test_drbg, 302564d1cdfbSStephan Mueller .fips_allowed = 1, 302664d1cdfbSStephan Mueller .suite = { 302721c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes192_tv_template) 302864d1cdfbSStephan Mueller } 302964d1cdfbSStephan Mueller }, { 303064d1cdfbSStephan Mueller .alg = "drbg_nopr_ctr_aes256", 303164d1cdfbSStephan Mueller .test = alg_test_drbg, 303264d1cdfbSStephan Mueller .fips_allowed = 1, 303364d1cdfbSStephan Mueller .suite = { 303421c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_ctr_aes256_tv_template) 303564d1cdfbSStephan Mueller } 303664d1cdfbSStephan Mueller }, { 303764d1cdfbSStephan Mueller /* 303864d1cdfbSStephan Mueller * There is no need to specifically test the DRBG with every 303964d1cdfbSStephan Mueller * backend cipher -- covered by drbg_nopr_hmac_sha256 test 304064d1cdfbSStephan Mueller */ 304164d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha1", 304264d1cdfbSStephan Mueller .fips_allowed = 1, 304364d1cdfbSStephan Mueller .test = alg_test_null, 304464d1cdfbSStephan Mueller }, { 304564d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha256", 304664d1cdfbSStephan Mueller .test = alg_test_drbg, 304764d1cdfbSStephan Mueller .fips_allowed = 1, 304864d1cdfbSStephan Mueller .suite = { 304921c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_hmac_sha256_tv_template) 305064d1cdfbSStephan Mueller } 305164d1cdfbSStephan Mueller }, { 305264d1cdfbSStephan Mueller /* covered by drbg_nopr_hmac_sha256 test */ 305364d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha384", 305464d1cdfbSStephan Mueller .fips_allowed = 1, 305564d1cdfbSStephan Mueller .test = alg_test_null, 305664d1cdfbSStephan Mueller }, { 305764d1cdfbSStephan Mueller .alg = "drbg_nopr_hmac_sha512", 305864d1cdfbSStephan Mueller .test = alg_test_null, 305964d1cdfbSStephan Mueller .fips_allowed = 1, 306064d1cdfbSStephan Mueller }, { 306164d1cdfbSStephan Mueller .alg = "drbg_nopr_sha1", 306264d1cdfbSStephan Mueller .fips_allowed = 1, 306364d1cdfbSStephan Mueller .test = alg_test_null, 306464d1cdfbSStephan Mueller }, { 306564d1cdfbSStephan Mueller .alg = "drbg_nopr_sha256", 306664d1cdfbSStephan Mueller .test = alg_test_drbg, 306764d1cdfbSStephan Mueller .fips_allowed = 1, 306864d1cdfbSStephan Mueller .suite = { 306921c8e720SArd Biesheuvel .drbg = __VECS(drbg_nopr_sha256_tv_template) 307064d1cdfbSStephan Mueller } 307164d1cdfbSStephan Mueller }, { 307264d1cdfbSStephan Mueller /* covered by drbg_nopr_sha256 test */ 307364d1cdfbSStephan Mueller .alg = "drbg_nopr_sha384", 307464d1cdfbSStephan Mueller .fips_allowed = 1, 307564d1cdfbSStephan Mueller .test = alg_test_null, 307664d1cdfbSStephan Mueller }, { 307764d1cdfbSStephan Mueller .alg = "drbg_nopr_sha512", 307864d1cdfbSStephan Mueller .fips_allowed = 1, 307964d1cdfbSStephan Mueller .test = alg_test_null, 308064d1cdfbSStephan Mueller }, { 308164d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes128", 308264d1cdfbSStephan Mueller .test = alg_test_drbg, 308364d1cdfbSStephan Mueller .fips_allowed = 1, 308464d1cdfbSStephan Mueller .suite = { 308521c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_ctr_aes128_tv_template) 308664d1cdfbSStephan Mueller } 308764d1cdfbSStephan Mueller }, { 308864d1cdfbSStephan Mueller /* covered by drbg_pr_ctr_aes128 test */ 308964d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes192", 309064d1cdfbSStephan Mueller .fips_allowed = 1, 309164d1cdfbSStephan Mueller .test = alg_test_null, 309264d1cdfbSStephan Mueller }, { 309364d1cdfbSStephan Mueller .alg = "drbg_pr_ctr_aes256", 309464d1cdfbSStephan Mueller .fips_allowed = 1, 309564d1cdfbSStephan Mueller .test = alg_test_null, 309664d1cdfbSStephan Mueller }, { 309764d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha1", 309864d1cdfbSStephan Mueller .fips_allowed = 1, 309964d1cdfbSStephan Mueller .test = alg_test_null, 310064d1cdfbSStephan Mueller }, { 310164d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha256", 310264d1cdfbSStephan Mueller .test = alg_test_drbg, 310364d1cdfbSStephan Mueller .fips_allowed = 1, 310464d1cdfbSStephan Mueller .suite = { 310521c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_hmac_sha256_tv_template) 310664d1cdfbSStephan Mueller } 310764d1cdfbSStephan Mueller }, { 310864d1cdfbSStephan Mueller /* covered by drbg_pr_hmac_sha256 test */ 310964d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha384", 311064d1cdfbSStephan Mueller .fips_allowed = 1, 311164d1cdfbSStephan Mueller .test = alg_test_null, 311264d1cdfbSStephan Mueller }, { 311364d1cdfbSStephan Mueller .alg = "drbg_pr_hmac_sha512", 311464d1cdfbSStephan Mueller .test = alg_test_null, 311564d1cdfbSStephan Mueller .fips_allowed = 1, 311664d1cdfbSStephan Mueller }, { 311764d1cdfbSStephan Mueller .alg = "drbg_pr_sha1", 311864d1cdfbSStephan Mueller .fips_allowed = 1, 311964d1cdfbSStephan Mueller .test = alg_test_null, 312064d1cdfbSStephan Mueller }, { 312164d1cdfbSStephan Mueller .alg = "drbg_pr_sha256", 312264d1cdfbSStephan Mueller .test = alg_test_drbg, 312364d1cdfbSStephan Mueller .fips_allowed = 1, 312464d1cdfbSStephan Mueller .suite = { 312521c8e720SArd Biesheuvel .drbg = __VECS(drbg_pr_sha256_tv_template) 312664d1cdfbSStephan Mueller } 312764d1cdfbSStephan Mueller }, { 312864d1cdfbSStephan Mueller /* covered by drbg_pr_sha256 test */ 312964d1cdfbSStephan Mueller .alg = "drbg_pr_sha384", 313064d1cdfbSStephan Mueller .fips_allowed = 1, 313164d1cdfbSStephan Mueller .test = alg_test_null, 313264d1cdfbSStephan Mueller }, { 313364d1cdfbSStephan Mueller .alg = "drbg_pr_sha512", 313464d1cdfbSStephan Mueller .fips_allowed = 1, 313564d1cdfbSStephan Mueller .test = alg_test_null, 313664d1cdfbSStephan Mueller }, { 3137da7f033dSHerbert Xu .alg = "ecb(aes)", 31381aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3139a1915d51SJarod Wilson .fips_allowed = 1, 3140da7f033dSHerbert Xu .suite = { 314192a4c9feSEric Biggers .cipher = __VECS(aes_tv_template) 3142da7f033dSHerbert Xu } 3143da7f033dSHerbert Xu }, { 3144da7f033dSHerbert Xu .alg = "ecb(anubis)", 31451aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3146da7f033dSHerbert Xu .suite = { 314792a4c9feSEric Biggers .cipher = __VECS(anubis_tv_template) 3148da7f033dSHerbert Xu } 3149da7f033dSHerbert Xu }, { 3150da7f033dSHerbert Xu .alg = "ecb(arc4)", 31511aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3152da7f033dSHerbert Xu .suite = { 315392a4c9feSEric Biggers .cipher = __VECS(arc4_tv_template) 3154da7f033dSHerbert Xu } 3155da7f033dSHerbert Xu }, { 3156da7f033dSHerbert Xu .alg = "ecb(blowfish)", 31571aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3158da7f033dSHerbert Xu .suite = { 315992a4c9feSEric Biggers .cipher = __VECS(bf_tv_template) 3160da7f033dSHerbert Xu } 3161da7f033dSHerbert Xu }, { 3162da7f033dSHerbert Xu .alg = "ecb(camellia)", 31631aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3164da7f033dSHerbert Xu .suite = { 316592a4c9feSEric Biggers .cipher = __VECS(camellia_tv_template) 3166da7f033dSHerbert Xu } 3167da7f033dSHerbert Xu }, { 3168da7f033dSHerbert Xu .alg = "ecb(cast5)", 31691aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3170da7f033dSHerbert Xu .suite = { 317192a4c9feSEric Biggers .cipher = __VECS(cast5_tv_template) 3172da7f033dSHerbert Xu } 3173da7f033dSHerbert Xu }, { 3174da7f033dSHerbert Xu .alg = "ecb(cast6)", 31751aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3176da7f033dSHerbert Xu .suite = { 317792a4c9feSEric Biggers .cipher = __VECS(cast6_tv_template) 3178da7f033dSHerbert Xu } 3179da7f033dSHerbert Xu }, { 3180e448370dSJussi Kivilinna .alg = "ecb(cipher_null)", 3181e448370dSJussi Kivilinna .test = alg_test_null, 31826175ca2bSMilan Broz .fips_allowed = 1, 3183e448370dSJussi Kivilinna }, { 3184da7f033dSHerbert Xu .alg = "ecb(des)", 31851aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3186da7f033dSHerbert Xu .suite = { 318792a4c9feSEric Biggers .cipher = __VECS(des_tv_template) 3188da7f033dSHerbert Xu } 3189da7f033dSHerbert Xu }, { 3190da7f033dSHerbert Xu .alg = "ecb(des3_ede)", 31911aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3192a1915d51SJarod Wilson .fips_allowed = 1, 3193da7f033dSHerbert Xu .suite = { 319492a4c9feSEric Biggers .cipher = __VECS(des3_ede_tv_template) 3195da7f033dSHerbert Xu } 3196da7f033dSHerbert Xu }, { 319766e5bd00SJussi Kivilinna .alg = "ecb(fcrypt)", 319866e5bd00SJussi Kivilinna .test = alg_test_skcipher, 319966e5bd00SJussi Kivilinna .suite = { 320066e5bd00SJussi Kivilinna .cipher = { 320192a4c9feSEric Biggers .vecs = fcrypt_pcbc_tv_template, 320266e5bd00SJussi Kivilinna .count = 1 320366e5bd00SJussi Kivilinna } 320466e5bd00SJussi Kivilinna } 320566e5bd00SJussi Kivilinna }, { 3206da7f033dSHerbert Xu .alg = "ecb(khazad)", 32071aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3208da7f033dSHerbert Xu .suite = { 320992a4c9feSEric Biggers .cipher = __VECS(khazad_tv_template) 3210da7f033dSHerbert Xu } 3211da7f033dSHerbert Xu }, { 321215f47ce5SGilad Ben-Yossef /* Same as ecb(aes) except the key is stored in 321315f47ce5SGilad Ben-Yossef * hardware secure memory which we reference by index 321415f47ce5SGilad Ben-Yossef */ 321515f47ce5SGilad Ben-Yossef .alg = "ecb(paes)", 321615f47ce5SGilad Ben-Yossef .test = alg_test_null, 321715f47ce5SGilad Ben-Yossef .fips_allowed = 1, 321815f47ce5SGilad Ben-Yossef }, { 3219da7f033dSHerbert Xu .alg = "ecb(seed)", 32201aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3221da7f033dSHerbert Xu .suite = { 322292a4c9feSEric Biggers .cipher = __VECS(seed_tv_template) 3223da7f033dSHerbert Xu } 3224da7f033dSHerbert Xu }, { 3225da7f033dSHerbert Xu .alg = "ecb(serpent)", 32261aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3227da7f033dSHerbert Xu .suite = { 322892a4c9feSEric Biggers .cipher = __VECS(serpent_tv_template) 3229da7f033dSHerbert Xu } 3230da7f033dSHerbert Xu }, { 3231cd83a8a7SGilad Ben-Yossef .alg = "ecb(sm4)", 3232cd83a8a7SGilad Ben-Yossef .test = alg_test_skcipher, 3233cd83a8a7SGilad Ben-Yossef .suite = { 323492a4c9feSEric Biggers .cipher = __VECS(sm4_tv_template) 3235cd83a8a7SGilad Ben-Yossef } 3236cd83a8a7SGilad Ben-Yossef }, { 3237da7f033dSHerbert Xu .alg = "ecb(tea)", 32381aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3239da7f033dSHerbert Xu .suite = { 324092a4c9feSEric Biggers .cipher = __VECS(tea_tv_template) 3241da7f033dSHerbert Xu } 3242da7f033dSHerbert Xu }, { 3243da7f033dSHerbert Xu .alg = "ecb(tnepres)", 32441aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3245da7f033dSHerbert Xu .suite = { 324692a4c9feSEric Biggers .cipher = __VECS(tnepres_tv_template) 3247da7f033dSHerbert Xu } 3248da7f033dSHerbert Xu }, { 3249da7f033dSHerbert Xu .alg = "ecb(twofish)", 32501aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3251da7f033dSHerbert Xu .suite = { 325292a4c9feSEric Biggers .cipher = __VECS(tf_tv_template) 3253da7f033dSHerbert Xu } 3254da7f033dSHerbert Xu }, { 3255da7f033dSHerbert Xu .alg = "ecb(xeta)", 32561aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3257da7f033dSHerbert Xu .suite = { 325892a4c9feSEric Biggers .cipher = __VECS(xeta_tv_template) 3259da7f033dSHerbert Xu } 3260da7f033dSHerbert Xu }, { 3261da7f033dSHerbert Xu .alg = "ecb(xtea)", 32621aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3263da7f033dSHerbert Xu .suite = { 326492a4c9feSEric Biggers .cipher = __VECS(xtea_tv_template) 3265da7f033dSHerbert Xu } 3266da7f033dSHerbert Xu }, { 32673c4b2390SSalvatore Benedetto .alg = "ecdh", 32683c4b2390SSalvatore Benedetto .test = alg_test_kpp, 32693c4b2390SSalvatore Benedetto .fips_allowed = 1, 32703c4b2390SSalvatore Benedetto .suite = { 327121c8e720SArd Biesheuvel .kpp = __VECS(ecdh_tv_template) 32723c4b2390SSalvatore Benedetto } 32733c4b2390SSalvatore Benedetto }, { 3274da7f033dSHerbert Xu .alg = "gcm(aes)", 3275da7f033dSHerbert Xu .test = alg_test_aead, 3276a1915d51SJarod Wilson .fips_allowed = 1, 3277da7f033dSHerbert Xu .suite = { 3278a0d608eeSEric Biggers .aead = __VECS(aes_gcm_tv_template) 3279da7f033dSHerbert Xu } 3280da7f033dSHerbert Xu }, { 3281507069c9SYouquan, Song .alg = "ghash", 3282507069c9SYouquan, Song .test = alg_test_hash, 328318c0ebd2SJarod Wilson .fips_allowed = 1, 3284507069c9SYouquan, Song .suite = { 328521c8e720SArd Biesheuvel .hash = __VECS(ghash_tv_template) 3286507069c9SYouquan, Song } 3287507069c9SYouquan, Song }, { 3288da7f033dSHerbert Xu .alg = "hmac(md5)", 3289da7f033dSHerbert Xu .test = alg_test_hash, 3290da7f033dSHerbert Xu .suite = { 329121c8e720SArd Biesheuvel .hash = __VECS(hmac_md5_tv_template) 3292da7f033dSHerbert Xu } 3293da7f033dSHerbert Xu }, { 3294da7f033dSHerbert Xu .alg = "hmac(rmd128)", 3295da7f033dSHerbert Xu .test = alg_test_hash, 3296da7f033dSHerbert Xu .suite = { 329721c8e720SArd Biesheuvel .hash = __VECS(hmac_rmd128_tv_template) 3298da7f033dSHerbert Xu } 3299da7f033dSHerbert Xu }, { 3300da7f033dSHerbert Xu .alg = "hmac(rmd160)", 3301da7f033dSHerbert Xu .test = alg_test_hash, 3302da7f033dSHerbert Xu .suite = { 330321c8e720SArd Biesheuvel .hash = __VECS(hmac_rmd160_tv_template) 3304da7f033dSHerbert Xu } 3305da7f033dSHerbert Xu }, { 3306da7f033dSHerbert Xu .alg = "hmac(sha1)", 3307da7f033dSHerbert Xu .test = alg_test_hash, 3308a1915d51SJarod Wilson .fips_allowed = 1, 3309da7f033dSHerbert Xu .suite = { 331021c8e720SArd Biesheuvel .hash = __VECS(hmac_sha1_tv_template) 3311da7f033dSHerbert Xu } 3312da7f033dSHerbert Xu }, { 3313da7f033dSHerbert Xu .alg = "hmac(sha224)", 3314da7f033dSHerbert Xu .test = alg_test_hash, 3315a1915d51SJarod Wilson .fips_allowed = 1, 3316da7f033dSHerbert Xu .suite = { 331721c8e720SArd Biesheuvel .hash = __VECS(hmac_sha224_tv_template) 3318da7f033dSHerbert Xu } 3319da7f033dSHerbert Xu }, { 3320da7f033dSHerbert Xu .alg = "hmac(sha256)", 3321da7f033dSHerbert Xu .test = alg_test_hash, 3322a1915d51SJarod Wilson .fips_allowed = 1, 3323da7f033dSHerbert Xu .suite = { 332421c8e720SArd Biesheuvel .hash = __VECS(hmac_sha256_tv_template) 3325da7f033dSHerbert Xu } 3326da7f033dSHerbert Xu }, { 332798eca72fSraveendra padasalagi .alg = "hmac(sha3-224)", 332898eca72fSraveendra padasalagi .test = alg_test_hash, 332998eca72fSraveendra padasalagi .fips_allowed = 1, 333098eca72fSraveendra padasalagi .suite = { 333121c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_224_tv_template) 333298eca72fSraveendra padasalagi } 333398eca72fSraveendra padasalagi }, { 333498eca72fSraveendra padasalagi .alg = "hmac(sha3-256)", 333598eca72fSraveendra padasalagi .test = alg_test_hash, 333698eca72fSraveendra padasalagi .fips_allowed = 1, 333798eca72fSraveendra padasalagi .suite = { 333821c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_256_tv_template) 333998eca72fSraveendra padasalagi } 334098eca72fSraveendra padasalagi }, { 334198eca72fSraveendra padasalagi .alg = "hmac(sha3-384)", 334298eca72fSraveendra padasalagi .test = alg_test_hash, 334398eca72fSraveendra padasalagi .fips_allowed = 1, 334498eca72fSraveendra padasalagi .suite = { 334521c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_384_tv_template) 334698eca72fSraveendra padasalagi } 334798eca72fSraveendra padasalagi }, { 334898eca72fSraveendra padasalagi .alg = "hmac(sha3-512)", 334998eca72fSraveendra padasalagi .test = alg_test_hash, 335098eca72fSraveendra padasalagi .fips_allowed = 1, 335198eca72fSraveendra padasalagi .suite = { 335221c8e720SArd Biesheuvel .hash = __VECS(hmac_sha3_512_tv_template) 335398eca72fSraveendra padasalagi } 335498eca72fSraveendra padasalagi }, { 3355da7f033dSHerbert Xu .alg = "hmac(sha384)", 3356da7f033dSHerbert Xu .test = alg_test_hash, 3357a1915d51SJarod Wilson .fips_allowed = 1, 3358da7f033dSHerbert Xu .suite = { 335921c8e720SArd Biesheuvel .hash = __VECS(hmac_sha384_tv_template) 3360da7f033dSHerbert Xu } 3361da7f033dSHerbert Xu }, { 3362da7f033dSHerbert Xu .alg = "hmac(sha512)", 3363da7f033dSHerbert Xu .test = alg_test_hash, 3364a1915d51SJarod Wilson .fips_allowed = 1, 3365da7f033dSHerbert Xu .suite = { 336621c8e720SArd Biesheuvel .hash = __VECS(hmac_sha512_tv_template) 3367da7f033dSHerbert Xu } 3368da7f033dSHerbert Xu }, { 336925a0b9d4SVitaly Chikunov .alg = "hmac(streebog256)", 337025a0b9d4SVitaly Chikunov .test = alg_test_hash, 337125a0b9d4SVitaly Chikunov .suite = { 337225a0b9d4SVitaly Chikunov .hash = __VECS(hmac_streebog256_tv_template) 337325a0b9d4SVitaly Chikunov } 337425a0b9d4SVitaly Chikunov }, { 337525a0b9d4SVitaly Chikunov .alg = "hmac(streebog512)", 337625a0b9d4SVitaly Chikunov .test = alg_test_hash, 337725a0b9d4SVitaly Chikunov .suite = { 337825a0b9d4SVitaly Chikunov .hash = __VECS(hmac_streebog512_tv_template) 337925a0b9d4SVitaly Chikunov } 338025a0b9d4SVitaly Chikunov }, { 3381bb5530e4SStephan Mueller .alg = "jitterentropy_rng", 3382bb5530e4SStephan Mueller .fips_allowed = 1, 3383bb5530e4SStephan Mueller .test = alg_test_null, 3384bb5530e4SStephan Mueller }, { 338535351988SStephan Mueller .alg = "kw(aes)", 338635351988SStephan Mueller .test = alg_test_skcipher, 338735351988SStephan Mueller .fips_allowed = 1, 338835351988SStephan Mueller .suite = { 338992a4c9feSEric Biggers .cipher = __VECS(aes_kw_tv_template) 339035351988SStephan Mueller } 339135351988SStephan Mueller }, { 3392da7f033dSHerbert Xu .alg = "lrw(aes)", 33931aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3394da7f033dSHerbert Xu .suite = { 339592a4c9feSEric Biggers .cipher = __VECS(aes_lrw_tv_template) 3396da7f033dSHerbert Xu } 3397da7f033dSHerbert Xu }, { 33980840605eSJussi Kivilinna .alg = "lrw(camellia)", 33990840605eSJussi Kivilinna .test = alg_test_skcipher, 34000840605eSJussi Kivilinna .suite = { 340192a4c9feSEric Biggers .cipher = __VECS(camellia_lrw_tv_template) 34020840605eSJussi Kivilinna } 34030840605eSJussi Kivilinna }, { 34049b8b0405SJohannes Goetzfried .alg = "lrw(cast6)", 34059b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 34069b8b0405SJohannes Goetzfried .suite = { 340792a4c9feSEric Biggers .cipher = __VECS(cast6_lrw_tv_template) 34089b8b0405SJohannes Goetzfried } 34099b8b0405SJohannes Goetzfried }, { 3410d7bfc0faSJussi Kivilinna .alg = "lrw(serpent)", 3411d7bfc0faSJussi Kivilinna .test = alg_test_skcipher, 3412d7bfc0faSJussi Kivilinna .suite = { 341392a4c9feSEric Biggers .cipher = __VECS(serpent_lrw_tv_template) 3414d7bfc0faSJussi Kivilinna } 3415d7bfc0faSJussi Kivilinna }, { 34160b2a1551SJussi Kivilinna .alg = "lrw(twofish)", 34170b2a1551SJussi Kivilinna .test = alg_test_skcipher, 34180b2a1551SJussi Kivilinna .suite = { 341992a4c9feSEric Biggers .cipher = __VECS(tf_lrw_tv_template) 34200b2a1551SJussi Kivilinna } 34210b2a1551SJussi Kivilinna }, { 34221443cc9bSKOVACS Krisztian .alg = "lz4", 34231443cc9bSKOVACS Krisztian .test = alg_test_comp, 34241443cc9bSKOVACS Krisztian .fips_allowed = 1, 34251443cc9bSKOVACS Krisztian .suite = { 34261443cc9bSKOVACS Krisztian .comp = { 342721c8e720SArd Biesheuvel .comp = __VECS(lz4_comp_tv_template), 342821c8e720SArd Biesheuvel .decomp = __VECS(lz4_decomp_tv_template) 34291443cc9bSKOVACS Krisztian } 34301443cc9bSKOVACS Krisztian } 34311443cc9bSKOVACS Krisztian }, { 34321443cc9bSKOVACS Krisztian .alg = "lz4hc", 34331443cc9bSKOVACS Krisztian .test = alg_test_comp, 34341443cc9bSKOVACS Krisztian .fips_allowed = 1, 34351443cc9bSKOVACS Krisztian .suite = { 34361443cc9bSKOVACS Krisztian .comp = { 343721c8e720SArd Biesheuvel .comp = __VECS(lz4hc_comp_tv_template), 343821c8e720SArd Biesheuvel .decomp = __VECS(lz4hc_decomp_tv_template) 34391443cc9bSKOVACS Krisztian } 34401443cc9bSKOVACS Krisztian } 34411443cc9bSKOVACS Krisztian }, { 3442da7f033dSHerbert Xu .alg = "lzo", 3443da7f033dSHerbert Xu .test = alg_test_comp, 34440818904dSMilan Broz .fips_allowed = 1, 3445da7f033dSHerbert Xu .suite = { 3446da7f033dSHerbert Xu .comp = { 344721c8e720SArd Biesheuvel .comp = __VECS(lzo_comp_tv_template), 344821c8e720SArd Biesheuvel .decomp = __VECS(lzo_decomp_tv_template) 3449da7f033dSHerbert Xu } 3450da7f033dSHerbert Xu } 3451da7f033dSHerbert Xu }, { 3452da7f033dSHerbert Xu .alg = "md4", 3453da7f033dSHerbert Xu .test = alg_test_hash, 3454da7f033dSHerbert Xu .suite = { 345521c8e720SArd Biesheuvel .hash = __VECS(md4_tv_template) 3456da7f033dSHerbert Xu } 3457da7f033dSHerbert Xu }, { 3458da7f033dSHerbert Xu .alg = "md5", 3459da7f033dSHerbert Xu .test = alg_test_hash, 3460da7f033dSHerbert Xu .suite = { 346121c8e720SArd Biesheuvel .hash = __VECS(md5_tv_template) 3462da7f033dSHerbert Xu } 3463da7f033dSHerbert Xu }, { 3464da7f033dSHerbert Xu .alg = "michael_mic", 3465da7f033dSHerbert Xu .test = alg_test_hash, 3466da7f033dSHerbert Xu .suite = { 346721c8e720SArd Biesheuvel .hash = __VECS(michael_mic_tv_template) 3468da7f033dSHerbert Xu } 3469da7f033dSHerbert Xu }, { 34704feb4c59SOndrej Mosnacek .alg = "morus1280", 34714feb4c59SOndrej Mosnacek .test = alg_test_aead, 34724feb4c59SOndrej Mosnacek .suite = { 3473a0d608eeSEric Biggers .aead = __VECS(morus1280_tv_template) 34744feb4c59SOndrej Mosnacek } 34754feb4c59SOndrej Mosnacek }, { 34764feb4c59SOndrej Mosnacek .alg = "morus640", 34774feb4c59SOndrej Mosnacek .test = alg_test_aead, 34784feb4c59SOndrej Mosnacek .suite = { 3479a0d608eeSEric Biggers .aead = __VECS(morus640_tv_template) 34804feb4c59SOndrej Mosnacek } 34814feb4c59SOndrej Mosnacek }, { 348226609a21SEric Biggers .alg = "nhpoly1305", 348326609a21SEric Biggers .test = alg_test_hash, 348426609a21SEric Biggers .suite = { 348526609a21SEric Biggers .hash = __VECS(nhpoly1305_tv_template) 348626609a21SEric Biggers } 348726609a21SEric Biggers }, { 3488ba0e14acSPuneet Saxena .alg = "ofb(aes)", 3489ba0e14acSPuneet Saxena .test = alg_test_skcipher, 3490ba0e14acSPuneet Saxena .fips_allowed = 1, 3491ba0e14acSPuneet Saxena .suite = { 349292a4c9feSEric Biggers .cipher = __VECS(aes_ofb_tv_template) 3493ba0e14acSPuneet Saxena } 3494ba0e14acSPuneet Saxena }, { 3495a794d8d8SGilad Ben-Yossef /* Same as ofb(aes) except the key is stored in 3496a794d8d8SGilad Ben-Yossef * hardware secure memory which we reference by index 3497a794d8d8SGilad Ben-Yossef */ 3498a794d8d8SGilad Ben-Yossef .alg = "ofb(paes)", 3499a794d8d8SGilad Ben-Yossef .test = alg_test_null, 3500a794d8d8SGilad Ben-Yossef .fips_allowed = 1, 3501a794d8d8SGilad Ben-Yossef }, { 3502da7f033dSHerbert Xu .alg = "pcbc(fcrypt)", 35031aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3504da7f033dSHerbert Xu .suite = { 350592a4c9feSEric Biggers .cipher = __VECS(fcrypt_pcbc_tv_template) 3506da7f033dSHerbert Xu } 3507da7f033dSHerbert Xu }, { 35081207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha224)", 35091207107cSStephan Mueller .test = alg_test_null, 35101207107cSStephan Mueller .fips_allowed = 1, 35111207107cSStephan Mueller }, { 35121207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha256)", 35131207107cSStephan Mueller .test = alg_test_akcipher, 35141207107cSStephan Mueller .fips_allowed = 1, 35151207107cSStephan Mueller .suite = { 35161207107cSStephan Mueller .akcipher = __VECS(pkcs1pad_rsa_tv_template) 35171207107cSStephan Mueller } 35181207107cSStephan Mueller }, { 35191207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha384)", 35201207107cSStephan Mueller .test = alg_test_null, 35211207107cSStephan Mueller .fips_allowed = 1, 35221207107cSStephan Mueller }, { 35231207107cSStephan Mueller .alg = "pkcs1pad(rsa,sha512)", 35241207107cSStephan Mueller .test = alg_test_null, 35251207107cSStephan Mueller .fips_allowed = 1, 35261207107cSStephan Mueller }, { 3527eee9dc61SMartin Willi .alg = "poly1305", 3528eee9dc61SMartin Willi .test = alg_test_hash, 3529eee9dc61SMartin Willi .suite = { 353021c8e720SArd Biesheuvel .hash = __VECS(poly1305_tv_template) 3531eee9dc61SMartin Willi } 3532eee9dc61SMartin Willi }, { 3533da7f033dSHerbert Xu .alg = "rfc3686(ctr(aes))", 35341aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3535a1915d51SJarod Wilson .fips_allowed = 1, 3536da7f033dSHerbert Xu .suite = { 353792a4c9feSEric Biggers .cipher = __VECS(aes_ctr_rfc3686_tv_template) 3538da7f033dSHerbert Xu } 3539da7f033dSHerbert Xu }, { 35403f31a740SHerbert Xu .alg = "rfc4106(gcm(aes))", 354169435b94SAdrian Hoban .test = alg_test_aead, 3542db71f29aSJarod Wilson .fips_allowed = 1, 354369435b94SAdrian Hoban .suite = { 3544a0d608eeSEric Biggers .aead = __VECS(aes_gcm_rfc4106_tv_template) 354569435b94SAdrian Hoban } 354669435b94SAdrian Hoban }, { 3547544c436aSHerbert Xu .alg = "rfc4309(ccm(aes))", 35485d667322SJarod Wilson .test = alg_test_aead, 3549a1915d51SJarod Wilson .fips_allowed = 1, 35505d667322SJarod Wilson .suite = { 3551a0d608eeSEric Biggers .aead = __VECS(aes_ccm_rfc4309_tv_template) 35525d667322SJarod Wilson } 35535d667322SJarod Wilson }, { 3554bb68745eSHerbert Xu .alg = "rfc4543(gcm(aes))", 3555e9b7441aSJussi Kivilinna .test = alg_test_aead, 3556e9b7441aSJussi Kivilinna .suite = { 3557a0d608eeSEric Biggers .aead = __VECS(aes_gcm_rfc4543_tv_template) 3558e9b7441aSJussi Kivilinna } 3559e9b7441aSJussi Kivilinna }, { 3560af2b76b5SMartin Willi .alg = "rfc7539(chacha20,poly1305)", 3561af2b76b5SMartin Willi .test = alg_test_aead, 3562af2b76b5SMartin Willi .suite = { 3563a0d608eeSEric Biggers .aead = __VECS(rfc7539_tv_template) 3564af2b76b5SMartin Willi } 3565af2b76b5SMartin Willi }, { 35665900758dSMartin Willi .alg = "rfc7539esp(chacha20,poly1305)", 35675900758dSMartin Willi .test = alg_test_aead, 35685900758dSMartin Willi .suite = { 3569a0d608eeSEric Biggers .aead = __VECS(rfc7539esp_tv_template) 35705900758dSMartin Willi } 35715900758dSMartin Willi }, { 3572da7f033dSHerbert Xu .alg = "rmd128", 3573da7f033dSHerbert Xu .test = alg_test_hash, 3574da7f033dSHerbert Xu .suite = { 357521c8e720SArd Biesheuvel .hash = __VECS(rmd128_tv_template) 3576da7f033dSHerbert Xu } 3577da7f033dSHerbert Xu }, { 3578da7f033dSHerbert Xu .alg = "rmd160", 3579da7f033dSHerbert Xu .test = alg_test_hash, 3580da7f033dSHerbert Xu .suite = { 358121c8e720SArd Biesheuvel .hash = __VECS(rmd160_tv_template) 3582da7f033dSHerbert Xu } 3583da7f033dSHerbert Xu }, { 3584da7f033dSHerbert Xu .alg = "rmd256", 3585da7f033dSHerbert Xu .test = alg_test_hash, 3586da7f033dSHerbert Xu .suite = { 358721c8e720SArd Biesheuvel .hash = __VECS(rmd256_tv_template) 3588da7f033dSHerbert Xu } 3589da7f033dSHerbert Xu }, { 3590da7f033dSHerbert Xu .alg = "rmd320", 3591da7f033dSHerbert Xu .test = alg_test_hash, 3592da7f033dSHerbert Xu .suite = { 359321c8e720SArd Biesheuvel .hash = __VECS(rmd320_tv_template) 3594da7f033dSHerbert Xu } 3595da7f033dSHerbert Xu }, { 3596946cc463STadeusz Struk .alg = "rsa", 3597946cc463STadeusz Struk .test = alg_test_akcipher, 3598946cc463STadeusz Struk .fips_allowed = 1, 3599946cc463STadeusz Struk .suite = { 360021c8e720SArd Biesheuvel .akcipher = __VECS(rsa_tv_template) 3601946cc463STadeusz Struk } 3602946cc463STadeusz Struk }, { 3603da7f033dSHerbert Xu .alg = "salsa20", 36041aa4ecd9SHerbert Xu .test = alg_test_skcipher, 3605da7f033dSHerbert Xu .suite = { 360692a4c9feSEric Biggers .cipher = __VECS(salsa20_stream_tv_template) 3607da7f033dSHerbert Xu } 3608da7f033dSHerbert Xu }, { 3609da7f033dSHerbert Xu .alg = "sha1", 3610da7f033dSHerbert Xu .test = alg_test_hash, 3611a1915d51SJarod Wilson .fips_allowed = 1, 3612da7f033dSHerbert Xu .suite = { 361321c8e720SArd Biesheuvel .hash = __VECS(sha1_tv_template) 3614da7f033dSHerbert Xu } 3615da7f033dSHerbert Xu }, { 3616da7f033dSHerbert Xu .alg = "sha224", 3617da7f033dSHerbert Xu .test = alg_test_hash, 3618a1915d51SJarod Wilson .fips_allowed = 1, 3619da7f033dSHerbert Xu .suite = { 362021c8e720SArd Biesheuvel .hash = __VECS(sha224_tv_template) 3621da7f033dSHerbert Xu } 3622da7f033dSHerbert Xu }, { 3623da7f033dSHerbert Xu .alg = "sha256", 3624da7f033dSHerbert Xu .test = alg_test_hash, 3625a1915d51SJarod Wilson .fips_allowed = 1, 3626da7f033dSHerbert Xu .suite = { 362721c8e720SArd Biesheuvel .hash = __VECS(sha256_tv_template) 3628da7f033dSHerbert Xu } 3629da7f033dSHerbert Xu }, { 363079cc6ab8Sraveendra padasalagi .alg = "sha3-224", 363179cc6ab8Sraveendra padasalagi .test = alg_test_hash, 363279cc6ab8Sraveendra padasalagi .fips_allowed = 1, 363379cc6ab8Sraveendra padasalagi .suite = { 363421c8e720SArd Biesheuvel .hash = __VECS(sha3_224_tv_template) 363579cc6ab8Sraveendra padasalagi } 363679cc6ab8Sraveendra padasalagi }, { 363779cc6ab8Sraveendra padasalagi .alg = "sha3-256", 363879cc6ab8Sraveendra padasalagi .test = alg_test_hash, 363979cc6ab8Sraveendra padasalagi .fips_allowed = 1, 364079cc6ab8Sraveendra padasalagi .suite = { 364121c8e720SArd Biesheuvel .hash = __VECS(sha3_256_tv_template) 364279cc6ab8Sraveendra padasalagi } 364379cc6ab8Sraveendra padasalagi }, { 364479cc6ab8Sraveendra padasalagi .alg = "sha3-384", 364579cc6ab8Sraveendra padasalagi .test = alg_test_hash, 364679cc6ab8Sraveendra padasalagi .fips_allowed = 1, 364779cc6ab8Sraveendra padasalagi .suite = { 364821c8e720SArd Biesheuvel .hash = __VECS(sha3_384_tv_template) 364979cc6ab8Sraveendra padasalagi } 365079cc6ab8Sraveendra padasalagi }, { 365179cc6ab8Sraveendra padasalagi .alg = "sha3-512", 365279cc6ab8Sraveendra padasalagi .test = alg_test_hash, 365379cc6ab8Sraveendra padasalagi .fips_allowed = 1, 365479cc6ab8Sraveendra padasalagi .suite = { 365521c8e720SArd Biesheuvel .hash = __VECS(sha3_512_tv_template) 365679cc6ab8Sraveendra padasalagi } 365779cc6ab8Sraveendra padasalagi }, { 3658da7f033dSHerbert Xu .alg = "sha384", 3659da7f033dSHerbert Xu .test = alg_test_hash, 3660a1915d51SJarod Wilson .fips_allowed = 1, 3661da7f033dSHerbert Xu .suite = { 366221c8e720SArd Biesheuvel .hash = __VECS(sha384_tv_template) 3663da7f033dSHerbert Xu } 3664da7f033dSHerbert Xu }, { 3665da7f033dSHerbert Xu .alg = "sha512", 3666da7f033dSHerbert Xu .test = alg_test_hash, 3667a1915d51SJarod Wilson .fips_allowed = 1, 3668da7f033dSHerbert Xu .suite = { 366921c8e720SArd Biesheuvel .hash = __VECS(sha512_tv_template) 3670da7f033dSHerbert Xu } 3671da7f033dSHerbert Xu }, { 3672b7e27530SGilad Ben-Yossef .alg = "sm3", 3673b7e27530SGilad Ben-Yossef .test = alg_test_hash, 3674b7e27530SGilad Ben-Yossef .suite = { 3675b7e27530SGilad Ben-Yossef .hash = __VECS(sm3_tv_template) 3676b7e27530SGilad Ben-Yossef } 3677b7e27530SGilad Ben-Yossef }, { 367825a0b9d4SVitaly Chikunov .alg = "streebog256", 367925a0b9d4SVitaly Chikunov .test = alg_test_hash, 368025a0b9d4SVitaly Chikunov .suite = { 368125a0b9d4SVitaly Chikunov .hash = __VECS(streebog256_tv_template) 368225a0b9d4SVitaly Chikunov } 368325a0b9d4SVitaly Chikunov }, { 368425a0b9d4SVitaly Chikunov .alg = "streebog512", 368525a0b9d4SVitaly Chikunov .test = alg_test_hash, 368625a0b9d4SVitaly Chikunov .suite = { 368725a0b9d4SVitaly Chikunov .hash = __VECS(streebog512_tv_template) 368825a0b9d4SVitaly Chikunov } 368925a0b9d4SVitaly Chikunov }, { 3690da7f033dSHerbert Xu .alg = "tgr128", 3691da7f033dSHerbert Xu .test = alg_test_hash, 3692da7f033dSHerbert Xu .suite = { 369321c8e720SArd Biesheuvel .hash = __VECS(tgr128_tv_template) 3694da7f033dSHerbert Xu } 3695da7f033dSHerbert Xu }, { 3696da7f033dSHerbert Xu .alg = "tgr160", 3697da7f033dSHerbert Xu .test = alg_test_hash, 3698da7f033dSHerbert Xu .suite = { 369921c8e720SArd Biesheuvel .hash = __VECS(tgr160_tv_template) 3700da7f033dSHerbert Xu } 3701da7f033dSHerbert Xu }, { 3702da7f033dSHerbert Xu .alg = "tgr192", 3703da7f033dSHerbert Xu .test = alg_test_hash, 3704da7f033dSHerbert Xu .suite = { 370521c8e720SArd Biesheuvel .hash = __VECS(tgr192_tv_template) 3706da7f033dSHerbert Xu } 3707da7f033dSHerbert Xu }, { 3708ed331adaSEric Biggers .alg = "vmac64(aes)", 3709ed331adaSEric Biggers .test = alg_test_hash, 3710ed331adaSEric Biggers .suite = { 3711ed331adaSEric Biggers .hash = __VECS(vmac64_aes_tv_template) 3712ed331adaSEric Biggers } 3713ed331adaSEric Biggers }, { 3714da7f033dSHerbert Xu .alg = "wp256", 3715da7f033dSHerbert Xu .test = alg_test_hash, 3716da7f033dSHerbert Xu .suite = { 371721c8e720SArd Biesheuvel .hash = __VECS(wp256_tv_template) 3718da7f033dSHerbert Xu } 3719da7f033dSHerbert Xu }, { 3720da7f033dSHerbert Xu .alg = "wp384", 3721da7f033dSHerbert Xu .test = alg_test_hash, 3722da7f033dSHerbert Xu .suite = { 372321c8e720SArd Biesheuvel .hash = __VECS(wp384_tv_template) 3724da7f033dSHerbert Xu } 3725da7f033dSHerbert Xu }, { 3726da7f033dSHerbert Xu .alg = "wp512", 3727da7f033dSHerbert Xu .test = alg_test_hash, 3728da7f033dSHerbert Xu .suite = { 372921c8e720SArd Biesheuvel .hash = __VECS(wp512_tv_template) 3730da7f033dSHerbert Xu } 3731da7f033dSHerbert Xu }, { 3732da7f033dSHerbert Xu .alg = "xcbc(aes)", 3733da7f033dSHerbert Xu .test = alg_test_hash, 3734da7f033dSHerbert Xu .suite = { 373521c8e720SArd Biesheuvel .hash = __VECS(aes_xcbc128_tv_template) 3736da7f033dSHerbert Xu } 3737da7f033dSHerbert Xu }, { 3738aa762409SEric Biggers .alg = "xchacha12", 3739aa762409SEric Biggers .test = alg_test_skcipher, 3740aa762409SEric Biggers .suite = { 3741aa762409SEric Biggers .cipher = __VECS(xchacha12_tv_template) 3742aa762409SEric Biggers }, 3743aa762409SEric Biggers }, { 3744de61d7aeSEric Biggers .alg = "xchacha20", 3745de61d7aeSEric Biggers .test = alg_test_skcipher, 3746de61d7aeSEric Biggers .suite = { 3747de61d7aeSEric Biggers .cipher = __VECS(xchacha20_tv_template) 3748de61d7aeSEric Biggers }, 3749de61d7aeSEric Biggers }, { 3750da7f033dSHerbert Xu .alg = "xts(aes)", 37511aa4ecd9SHerbert Xu .test = alg_test_skcipher, 37522918aa8dSJarod Wilson .fips_allowed = 1, 3753da7f033dSHerbert Xu .suite = { 375492a4c9feSEric Biggers .cipher = __VECS(aes_xts_tv_template) 3755da7f033dSHerbert Xu } 37560c01aed5SGeert Uytterhoeven }, { 37570840605eSJussi Kivilinna .alg = "xts(camellia)", 37580840605eSJussi Kivilinna .test = alg_test_skcipher, 37590840605eSJussi Kivilinna .suite = { 376092a4c9feSEric Biggers .cipher = __VECS(camellia_xts_tv_template) 37610840605eSJussi Kivilinna } 37620840605eSJussi Kivilinna }, { 37639b8b0405SJohannes Goetzfried .alg = "xts(cast6)", 37649b8b0405SJohannes Goetzfried .test = alg_test_skcipher, 37659b8b0405SJohannes Goetzfried .suite = { 376692a4c9feSEric Biggers .cipher = __VECS(cast6_xts_tv_template) 37679b8b0405SJohannes Goetzfried } 37689b8b0405SJohannes Goetzfried }, { 376915f47ce5SGilad Ben-Yossef /* Same as xts(aes) except the key is stored in 377015f47ce5SGilad Ben-Yossef * hardware secure memory which we reference by index 377115f47ce5SGilad Ben-Yossef */ 377215f47ce5SGilad Ben-Yossef .alg = "xts(paes)", 377315f47ce5SGilad Ben-Yossef .test = alg_test_null, 377415f47ce5SGilad Ben-Yossef .fips_allowed = 1, 377515f47ce5SGilad Ben-Yossef }, { 377618be20b9SJussi Kivilinna .alg = "xts(serpent)", 377718be20b9SJussi Kivilinna .test = alg_test_skcipher, 377818be20b9SJussi Kivilinna .suite = { 377992a4c9feSEric Biggers .cipher = __VECS(serpent_xts_tv_template) 378018be20b9SJussi Kivilinna } 378118be20b9SJussi Kivilinna }, { 3782aed265b9SJussi Kivilinna .alg = "xts(twofish)", 3783aed265b9SJussi Kivilinna .test = alg_test_skcipher, 3784aed265b9SJussi Kivilinna .suite = { 378592a4c9feSEric Biggers .cipher = __VECS(tf_xts_tv_template) 3786aed265b9SJussi Kivilinna } 3787a368f43dSGiovanni Cabiddu }, { 378815f47ce5SGilad Ben-Yossef .alg = "xts4096(paes)", 378915f47ce5SGilad Ben-Yossef .test = alg_test_null, 379015f47ce5SGilad Ben-Yossef .fips_allowed = 1, 379115f47ce5SGilad Ben-Yossef }, { 379215f47ce5SGilad Ben-Yossef .alg = "xts512(paes)", 379315f47ce5SGilad Ben-Yossef .test = alg_test_null, 379415f47ce5SGilad Ben-Yossef .fips_allowed = 1, 379515f47ce5SGilad Ben-Yossef }, { 3796a368f43dSGiovanni Cabiddu .alg = "zlib-deflate", 3797a368f43dSGiovanni Cabiddu .test = alg_test_comp, 3798a368f43dSGiovanni Cabiddu .fips_allowed = 1, 3799a368f43dSGiovanni Cabiddu .suite = { 3800a368f43dSGiovanni Cabiddu .comp = { 3801a368f43dSGiovanni Cabiddu .comp = __VECS(zlib_deflate_comp_tv_template), 3802a368f43dSGiovanni Cabiddu .decomp = __VECS(zlib_deflate_decomp_tv_template) 3803a368f43dSGiovanni Cabiddu } 3804a368f43dSGiovanni Cabiddu } 3805d28fc3dbSNick Terrell }, { 3806d28fc3dbSNick Terrell .alg = "zstd", 3807d28fc3dbSNick Terrell .test = alg_test_comp, 3808d28fc3dbSNick Terrell .fips_allowed = 1, 3809d28fc3dbSNick Terrell .suite = { 3810d28fc3dbSNick Terrell .comp = { 3811d28fc3dbSNick Terrell .comp = __VECS(zstd_comp_tv_template), 3812d28fc3dbSNick Terrell .decomp = __VECS(zstd_decomp_tv_template) 3813d28fc3dbSNick Terrell } 3814d28fc3dbSNick Terrell } 3815da7f033dSHerbert Xu } 3816da7f033dSHerbert Xu }; 3817da7f033dSHerbert Xu 38183f47a03dSEric Biggers static void alg_check_test_descs_order(void) 38195714758bSJussi Kivilinna { 38205714758bSJussi Kivilinna int i; 38215714758bSJussi Kivilinna 38225714758bSJussi Kivilinna for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) { 38235714758bSJussi Kivilinna int diff = strcmp(alg_test_descs[i - 1].alg, 38245714758bSJussi Kivilinna alg_test_descs[i].alg); 38255714758bSJussi Kivilinna 38265714758bSJussi Kivilinna if (WARN_ON(diff > 0)) { 38275714758bSJussi Kivilinna pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n", 38285714758bSJussi Kivilinna alg_test_descs[i - 1].alg, 38295714758bSJussi Kivilinna alg_test_descs[i].alg); 38305714758bSJussi Kivilinna } 38315714758bSJussi Kivilinna 38325714758bSJussi Kivilinna if (WARN_ON(diff == 0)) { 38335714758bSJussi Kivilinna pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n", 38345714758bSJussi Kivilinna alg_test_descs[i].alg); 38355714758bSJussi Kivilinna } 38365714758bSJussi Kivilinna } 38375714758bSJussi Kivilinna } 38385714758bSJussi Kivilinna 38393f47a03dSEric Biggers static void alg_check_testvec_configs(void) 38403f47a03dSEric Biggers { 38414e7babbaSEric Biggers int i; 38424e7babbaSEric Biggers 38434e7babbaSEric Biggers for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) 38444e7babbaSEric Biggers WARN_ON(!valid_testvec_config( 38454e7babbaSEric Biggers &default_cipher_testvec_configs[i])); 38464cc2dcf9SEric Biggers 38474cc2dcf9SEric Biggers for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) 38484cc2dcf9SEric Biggers WARN_ON(!valid_testvec_config( 38494cc2dcf9SEric Biggers &default_hash_testvec_configs[i])); 38503f47a03dSEric Biggers } 38513f47a03dSEric Biggers 38523f47a03dSEric Biggers static void testmgr_onetime_init(void) 38533f47a03dSEric Biggers { 38543f47a03dSEric Biggers alg_check_test_descs_order(); 38553f47a03dSEric Biggers alg_check_testvec_configs(); 38565b2706a4SEric Biggers 38575b2706a4SEric Biggers #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS 38585b2706a4SEric Biggers pr_warn("alg: extra crypto tests enabled. This is intended for developer use only.\n"); 38595b2706a4SEric Biggers #endif 38603f47a03dSEric Biggers } 38613f47a03dSEric Biggers 38621aa4ecd9SHerbert Xu static int alg_find_test(const char *alg) 3863da7f033dSHerbert Xu { 3864da7f033dSHerbert Xu int start = 0; 3865da7f033dSHerbert Xu int end = ARRAY_SIZE(alg_test_descs); 3866da7f033dSHerbert Xu 3867da7f033dSHerbert Xu while (start < end) { 3868da7f033dSHerbert Xu int i = (start + end) / 2; 3869da7f033dSHerbert Xu int diff = strcmp(alg_test_descs[i].alg, alg); 3870da7f033dSHerbert Xu 3871da7f033dSHerbert Xu if (diff > 0) { 3872da7f033dSHerbert Xu end = i; 3873da7f033dSHerbert Xu continue; 3874da7f033dSHerbert Xu } 3875da7f033dSHerbert Xu 3876da7f033dSHerbert Xu if (diff < 0) { 3877da7f033dSHerbert Xu start = i + 1; 3878da7f033dSHerbert Xu continue; 3879da7f033dSHerbert Xu } 3880da7f033dSHerbert Xu 38811aa4ecd9SHerbert Xu return i; 3882da7f033dSHerbert Xu } 3883da7f033dSHerbert Xu 38841aa4ecd9SHerbert Xu return -1; 38851aa4ecd9SHerbert Xu } 38861aa4ecd9SHerbert Xu 38871aa4ecd9SHerbert Xu int alg_test(const char *driver, const char *alg, u32 type, u32 mask) 38881aa4ecd9SHerbert Xu { 38891aa4ecd9SHerbert Xu int i; 3890a68f6610SHerbert Xu int j; 3891d12d6b6dSNeil Horman int rc; 38921aa4ecd9SHerbert Xu 38939e5c9fe4SRichard W.M. Jones if (!fips_enabled && notests) { 38949e5c9fe4SRichard W.M. Jones printk_once(KERN_INFO "alg: self-tests disabled\n"); 38959e5c9fe4SRichard W.M. Jones return 0; 38969e5c9fe4SRichard W.M. Jones } 38979e5c9fe4SRichard W.M. Jones 38983f47a03dSEric Biggers DO_ONCE(testmgr_onetime_init); 38995714758bSJussi Kivilinna 39001aa4ecd9SHerbert Xu if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) { 39011aa4ecd9SHerbert Xu char nalg[CRYPTO_MAX_ALG_NAME]; 39021aa4ecd9SHerbert Xu 39031aa4ecd9SHerbert Xu if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >= 39041aa4ecd9SHerbert Xu sizeof(nalg)) 39051aa4ecd9SHerbert Xu return -ENAMETOOLONG; 39061aa4ecd9SHerbert Xu 39071aa4ecd9SHerbert Xu i = alg_find_test(nalg); 39081aa4ecd9SHerbert Xu if (i < 0) 39091aa4ecd9SHerbert Xu goto notest; 39101aa4ecd9SHerbert Xu 3911a3bef3a3SJarod Wilson if (fips_enabled && !alg_test_descs[i].fips_allowed) 3912a3bef3a3SJarod Wilson goto non_fips_alg; 3913a3bef3a3SJarod Wilson 3914941fb328SJarod Wilson rc = alg_test_cipher(alg_test_descs + i, driver, type, mask); 3915941fb328SJarod Wilson goto test_done; 39161aa4ecd9SHerbert Xu } 39171aa4ecd9SHerbert Xu 39181aa4ecd9SHerbert Xu i = alg_find_test(alg); 3919a68f6610SHerbert Xu j = alg_find_test(driver); 3920a68f6610SHerbert Xu if (i < 0 && j < 0) 39211aa4ecd9SHerbert Xu goto notest; 39221aa4ecd9SHerbert Xu 3923a68f6610SHerbert Xu if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) || 3924a68f6610SHerbert Xu (j >= 0 && !alg_test_descs[j].fips_allowed))) 3925a3bef3a3SJarod Wilson goto non_fips_alg; 3926a3bef3a3SJarod Wilson 3927a68f6610SHerbert Xu rc = 0; 3928a68f6610SHerbert Xu if (i >= 0) 3929a68f6610SHerbert Xu rc |= alg_test_descs[i].test(alg_test_descs + i, driver, 39301aa4ecd9SHerbert Xu type, mask); 3931032c8cacSCristian Stoica if (j >= 0 && j != i) 3932a68f6610SHerbert Xu rc |= alg_test_descs[j].test(alg_test_descs + j, driver, 3933a68f6610SHerbert Xu type, mask); 3934a68f6610SHerbert Xu 3935941fb328SJarod Wilson test_done: 3936d12d6b6dSNeil Horman if (fips_enabled && rc) 3937d12d6b6dSNeil Horman panic("%s: %s alg self test failed in fips mode!\n", driver, alg); 3938d12d6b6dSNeil Horman 393929ecd4abSJarod Wilson if (fips_enabled && !rc) 39403e8cffd4SMasanari Iida pr_info("alg: self-tests for %s (%s) passed\n", driver, alg); 394129ecd4abSJarod Wilson 3942d12d6b6dSNeil Horman return rc; 39431aa4ecd9SHerbert Xu 39441aa4ecd9SHerbert Xu notest: 3945da7f033dSHerbert Xu printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); 3946da7f033dSHerbert Xu return 0; 3947a3bef3a3SJarod Wilson non_fips_alg: 3948a3bef3a3SJarod Wilson return -EINVAL; 3949da7f033dSHerbert Xu } 39500b767f96SAlexander Shishkin 3951326a6346SHerbert Xu #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */ 39520b767f96SAlexander Shishkin 3953da7f033dSHerbert Xu EXPORT_SYMBOL_GPL(alg_test); 3954