Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* |
| 3 | * Copyright 2021 Google LLC |
| 4 | * |
| 5 | * Authors: Elena Petrova <lenaptr@google.com>, |
| 6 | * Eric Biggers <ebiggers@google.com> |
| 7 | * |
| 8 | * Self-tests of fips140.ko cryptographic functionality. These are run at |
| 9 | * module load time to fulfill FIPS 140 and NIAP FPT_TST_EXT.1 requirements. |
| 10 | * |
| 11 | * The actual requirements for these self-tests are somewhat vague, but |
| 12 | * section 9 ("Self-Tests") of the FIPS 140-2 Implementation Guidance document |
| 13 | * (https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf) |
| 14 | * is somewhat helpful. Basically, all implementations of all FIPS approved |
| 15 | * algorithms (including modes of operation) must be tested. However: |
| 16 | * |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 17 | * - There are provisions for skipping tests that are already sufficiently |
| 18 | * covered by other tests. E.g., HMAC-SHA256 may cover SHA-256. |
| 19 | * |
| 20 | * - Only one test vector is required per algorithm, and it can be generated |
| 21 | * by any known-good implementation or taken from any official document. |
| 22 | * |
| 23 | * - For ciphers, both encryption and decryption must be tested. |
| 24 | * |
| 25 | * - Only one key size per algorithm needs to be tested. |
| 26 | * |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 27 | * There is some ambiguity about whether all implementations of each algorithm |
| 28 | * must be tested, or whether it is sufficient to test just the highest priority |
| 29 | * implementation. To be safe we test all implementations, except ones that can |
| 30 | * be excluded by one of the rules above. |
| 31 | * |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 32 | * See fips140_selftests[] for the list of tests we've selected. Currently, all |
Eric Biggers | 2b5843a | 2021-08-04 17:21:58 -0700 | [diff] [blame] | 33 | * our test vectors except the AES-CBC-CTS and DRBG ones were generated by the |
| 34 | * script tools/crypto/gen_fips140_testvecs.py, using the known-good |
| 35 | * implementations in the Python packages hashlib, pycryptodome, and |
| 36 | * cryptography. |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 37 | * |
| 38 | * Note that we don't reuse the upstream crypto API's self-tests |
| 39 | * (crypto/testmgr.{c,h}), for several reasons: |
| 40 | * |
| 41 | * - To meet FIPS requirements, the self-tests must be located within the FIPS |
| 42 | * module boundary (fips140.ko). But testmgr is integrated into the crypto |
| 43 | * API framework and can't be extracted into the module. |
| 44 | * |
| 45 | * - testmgr is much more heavyweight than required for FIPS and NIAP; it |
| 46 | * tests more algorithms and does more tests per algorithm, as it's meant to |
| 47 | * do proper testing and not just meet certification requirements. We need |
| 48 | * tests that can run with minimal overhead on every boot-up. |
| 49 | * |
| 50 | * - Despite being more heavyweight in general, testmgr doesn't test the |
| 51 | * SHA-256 and AES library APIs, despite that being needed here. |
| 52 | */ |
| 53 | #include <crypto/aead.h> |
| 54 | #include <crypto/aes.h> |
| 55 | #include <crypto/drbg.h> |
| 56 | #include <crypto/hash.h> |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 57 | #include <crypto/rng.h> |
| 58 | #include <crypto/sha.h> |
| 59 | #include <crypto/skcipher.h> |
| 60 | |
| 61 | #include "fips140-module.h" |
| 62 | |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 63 | /* Test vector for an AEAD algorithm */ |
| 64 | struct aead_testvec { |
| 65 | const u8 *key; |
| 66 | size_t key_size; |
| 67 | const u8 *iv; |
| 68 | size_t iv_size; |
| 69 | const u8 *assoc; |
| 70 | size_t assoc_size; |
| 71 | const u8 *plaintext; |
| 72 | size_t plaintext_size; |
| 73 | const u8 *ciphertext; |
| 74 | size_t ciphertext_size; |
| 75 | }; |
| 76 | |
| 77 | /* Test vector for a length-preserving encryption algorithm */ |
| 78 | struct skcipher_testvec { |
| 79 | const u8 *key; |
| 80 | size_t key_size; |
| 81 | const u8 *iv; |
| 82 | size_t iv_size; |
| 83 | const u8 *plaintext; |
| 84 | const u8 *ciphertext; |
| 85 | size_t message_size; |
| 86 | }; |
| 87 | |
| 88 | /* Test vector for a hash algorithm */ |
| 89 | struct hash_testvec { |
| 90 | const u8 *key; |
| 91 | size_t key_size; |
| 92 | const u8 *message; |
| 93 | size_t message_size; |
| 94 | const u8 *digest; |
| 95 | size_t digest_size; |
| 96 | }; |
| 97 | |
| 98 | /* Test vector for a DRBG algorithm */ |
| 99 | struct drbg_testvec { |
| 100 | const u8 *entropy; |
| 101 | size_t entropy_size; |
| 102 | const u8 *pers; |
| 103 | size_t pers_size; |
| 104 | const u8 *entpr_a; |
| 105 | const u8 *entpr_b; |
| 106 | size_t entpr_size; |
| 107 | const u8 *add_a; |
| 108 | const u8 *add_b; |
| 109 | size_t add_size; |
| 110 | const u8 *output; |
| 111 | size_t out_size; |
| 112 | }; |
| 113 | |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 114 | struct fips_test { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 115 | /* The name of the algorithm, in crypto API syntax */ |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 116 | const char *alg; |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 117 | |
| 118 | /* |
| 119 | * The optional list of implementations to test. @func will be called |
| 120 | * once per implementation, or once with @alg if this list is empty. |
| 121 | * The implementation names must be given in crypto API syntax, or in |
| 122 | * the case of a library implementation should have "-lib" appended. |
| 123 | */ |
| 124 | const char *impls[8]; |
| 125 | |
| 126 | /* |
| 127 | * The test function. It should execute a known-answer test on an |
| 128 | * algorithm implementation, using the below test vector. |
| 129 | */ |
| 130 | int __must_check (*func)(const struct fips_test *test, |
| 131 | const char *impl); |
| 132 | |
| 133 | /* The test vector, with a format specific to the type of algorithm */ |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 134 | union { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 135 | struct aead_testvec aead; |
| 136 | struct skcipher_testvec skcipher; |
| 137 | struct hash_testvec hash; |
| 138 | struct drbg_testvec drbg; |
| 139 | }; |
| 140 | }; |
| 141 | |
| 142 | /* Maximum IV size (in bytes) among any algorithm tested here */ |
| 143 | #define MAX_IV_SIZE 16 |
| 144 | |
| 145 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 146 | fips_check_result(u8 *result, const u8 *expected_result, size_t result_size, |
| 147 | const char *impl, const char *operation) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 148 | { |
Eric Biggers | 903e97a | 2021-11-18 16:09:09 -0800 | [diff] [blame] | 149 | fips140_inject_selftest_failure(impl, result); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 150 | if (memcmp(result, expected_result, result_size) != 0) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 151 | pr_err("wrong result from %s %s\n", impl, operation); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 152 | return -EBADMSG; |
| 153 | } |
| 154 | return 0; |
| 155 | } |
| 156 | |
| 157 | /* |
| 158 | * None of the algorithms should be ASYNC, as the FIPS module doesn't register |
| 159 | * any ASYNC algorithms. (The ASYNC flag is only declared by hardware |
| 160 | * algorithms, which would need their own FIPS certification.) |
| 161 | * |
| 162 | * Ideally we would verify alg->cra_module == THIS_MODULE here as well, but that |
| 163 | * doesn't work because the files are compiled as built-in code. |
| 164 | */ |
| 165 | static int __init __must_check |
| 166 | fips_validate_alg(const struct crypto_alg *alg) |
| 167 | { |
| 168 | if (alg->cra_flags & CRYPTO_ALG_ASYNC) { |
| 169 | pr_err("unexpectedly got async implementation of %s (%s)\n", |
| 170 | alg->cra_name, alg->cra_driver_name); |
| 171 | return -EINVAL; |
| 172 | } |
| 173 | return 0; |
| 174 | } |
| 175 | |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 176 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 177 | fips_handle_alloc_tfm_error(const char *impl, int err) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 178 | { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 179 | if (err == -ENOENT) { |
| 180 | /* |
| 181 | * The requested implementation of the algorithm wasn't found. |
| 182 | * This is expected if the CPU lacks a feature the |
| 183 | * implementation needs, such as the ARMv8 Crypto Extensions. |
| 184 | * |
| 185 | * When this happens, the implementation isn't available for |
| 186 | * use, so we can't test it, nor do we need to. So we just skip |
| 187 | * the test. |
| 188 | */ |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 189 | pr_info("%s is unavailable (no CPU support?), skipping testing it\n", |
| 190 | impl); |
| 191 | return 0; |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 192 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 193 | pr_err("failed to allocate %s tfm: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 194 | return err; |
| 195 | } |
| 196 | |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 197 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 198 | fips_test_aes_library(const struct fips_test *test, const char *impl) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 199 | { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 200 | const struct skcipher_testvec *vec = &test->skcipher; |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 201 | struct crypto_aes_ctx ctx; |
| 202 | u8 block[AES_BLOCK_SIZE]; |
| 203 | int err; |
| 204 | |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 205 | if (WARN_ON(vec->message_size != AES_BLOCK_SIZE)) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 206 | return -EINVAL; |
| 207 | |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 208 | err = aes_expandkey(&ctx, vec->key, vec->key_size); |
| 209 | if (err) { |
| 210 | pr_err("aes_expandkey() failed: %d\n", err); |
| 211 | return err; |
| 212 | } |
| 213 | aes_encrypt(&ctx, block, vec->plaintext); |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 214 | err = fips_check_result(block, vec->ciphertext, AES_BLOCK_SIZE, |
| 215 | impl, "encryption"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 216 | if (err) |
| 217 | return err; |
| 218 | aes_decrypt(&ctx, block, block); |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 219 | return fips_check_result(block, vec->plaintext, AES_BLOCK_SIZE, |
| 220 | impl, "decryption"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 221 | } |
| 222 | |
| 223 | /* Test a length-preserving symmetric cipher using the crypto_skcipher API. */ |
| 224 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 225 | fips_test_skcipher(const struct fips_test *test, const char *impl) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 226 | { |
| 227 | const struct skcipher_testvec *vec = &test->skcipher; |
| 228 | struct crypto_skcipher *tfm; |
| 229 | struct skcipher_request *req = NULL; |
| 230 | u8 *message = NULL; |
| 231 | struct scatterlist sg; |
| 232 | u8 iv[MAX_IV_SIZE]; |
| 233 | int err; |
| 234 | |
| 235 | if (WARN_ON(vec->iv_size > MAX_IV_SIZE)) |
| 236 | return -EINVAL; |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 237 | if (WARN_ON(vec->message_size <= 0)) |
| 238 | return -EINVAL; |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 239 | |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 240 | tfm = crypto_alloc_skcipher(impl, 0, 0); |
| 241 | if (IS_ERR(tfm)) |
| 242 | return fips_handle_alloc_tfm_error(impl, PTR_ERR(tfm)); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 243 | err = fips_validate_alg(&crypto_skcipher_alg(tfm)->base); |
| 244 | if (err) |
| 245 | goto out; |
| 246 | if (crypto_skcipher_ivsize(tfm) != vec->iv_size) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 247 | pr_err("%s has wrong IV size\n", impl); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 248 | err = -EINVAL; |
| 249 | goto out; |
| 250 | } |
| 251 | |
| 252 | req = skcipher_request_alloc(tfm, GFP_KERNEL); |
| 253 | message = kmemdup(vec->plaintext, vec->message_size, GFP_KERNEL); |
| 254 | if (!req || !message) { |
| 255 | err = -ENOMEM; |
| 256 | goto out; |
| 257 | } |
| 258 | sg_init_one(&sg, message, vec->message_size); |
| 259 | |
| 260 | skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, |
| 261 | NULL, NULL); |
| 262 | skcipher_request_set_crypt(req, &sg, &sg, vec->message_size, iv); |
| 263 | |
| 264 | err = crypto_skcipher_setkey(tfm, vec->key, vec->key_size); |
| 265 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 266 | pr_err("failed to set %s key: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 267 | goto out; |
| 268 | } |
| 269 | |
| 270 | /* Encrypt the plaintext, then verify the resulting ciphertext. */ |
| 271 | memcpy(iv, vec->iv, vec->iv_size); |
| 272 | err = crypto_skcipher_encrypt(req); |
| 273 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 274 | pr_err("%s encryption failed: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 275 | goto out; |
| 276 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 277 | err = fips_check_result(message, vec->ciphertext, vec->message_size, |
| 278 | impl, "encryption"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 279 | if (err) |
| 280 | goto out; |
| 281 | |
| 282 | /* Decrypt the ciphertext, then verify the resulting plaintext. */ |
| 283 | memcpy(iv, vec->iv, vec->iv_size); |
| 284 | err = crypto_skcipher_decrypt(req); |
| 285 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 286 | pr_err("%s decryption failed: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 287 | goto out; |
| 288 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 289 | err = fips_check_result(message, vec->plaintext, vec->message_size, |
| 290 | impl, "decryption"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 291 | out: |
| 292 | kfree(message); |
| 293 | skcipher_request_free(req); |
| 294 | crypto_free_skcipher(tfm); |
| 295 | return err; |
| 296 | } |
| 297 | |
| 298 | /* Test an AEAD using the crypto_aead API. */ |
| 299 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 300 | fips_test_aead(const struct fips_test *test, const char *impl) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 301 | { |
| 302 | const struct aead_testvec *vec = &test->aead; |
| 303 | const int tag_size = vec->ciphertext_size - vec->plaintext_size; |
| 304 | struct crypto_aead *tfm; |
| 305 | struct aead_request *req = NULL; |
| 306 | u8 *assoc = NULL; |
| 307 | u8 *message = NULL; |
| 308 | struct scatterlist sg[2]; |
| 309 | int sg_idx = 0; |
| 310 | u8 iv[MAX_IV_SIZE]; |
| 311 | int err; |
| 312 | |
| 313 | if (WARN_ON(vec->iv_size > MAX_IV_SIZE)) |
| 314 | return -EINVAL; |
| 315 | if (WARN_ON(vec->ciphertext_size <= vec->plaintext_size)) |
| 316 | return -EINVAL; |
| 317 | |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 318 | tfm = crypto_alloc_aead(impl, 0, 0); |
| 319 | if (IS_ERR(tfm)) |
| 320 | return fips_handle_alloc_tfm_error(impl, PTR_ERR(tfm)); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 321 | err = fips_validate_alg(&crypto_aead_alg(tfm)->base); |
| 322 | if (err) |
| 323 | goto out; |
| 324 | if (crypto_aead_ivsize(tfm) != vec->iv_size) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 325 | pr_err("%s has wrong IV size\n", impl); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 326 | err = -EINVAL; |
| 327 | goto out; |
| 328 | } |
| 329 | |
| 330 | req = aead_request_alloc(tfm, GFP_KERNEL); |
| 331 | assoc = kmemdup(vec->assoc, vec->assoc_size, GFP_KERNEL); |
| 332 | message = kzalloc(vec->ciphertext_size, GFP_KERNEL); |
| 333 | if (!req || !assoc || !message) { |
| 334 | err = -ENOMEM; |
| 335 | goto out; |
| 336 | } |
| 337 | memcpy(message, vec->plaintext, vec->plaintext_size); |
| 338 | |
| 339 | sg_init_table(sg, ARRAY_SIZE(sg)); |
| 340 | if (vec->assoc_size) |
| 341 | sg_set_buf(&sg[sg_idx++], assoc, vec->assoc_size); |
| 342 | sg_set_buf(&sg[sg_idx++], message, vec->ciphertext_size); |
| 343 | |
| 344 | aead_request_set_ad(req, vec->assoc_size); |
| 345 | aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); |
| 346 | |
| 347 | err = crypto_aead_setkey(tfm, vec->key, vec->key_size); |
| 348 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 349 | pr_err("failed to set %s key: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 350 | goto out; |
| 351 | } |
| 352 | |
| 353 | err = crypto_aead_setauthsize(tfm, tag_size); |
| 354 | if (err) { |
| 355 | pr_err("failed to set %s authentication tag size: %d\n", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 356 | impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 357 | goto out; |
| 358 | } |
| 359 | |
| 360 | /* |
| 361 | * Encrypt the plaintext, then verify the resulting ciphertext (which |
| 362 | * includes the authentication tag). |
| 363 | */ |
| 364 | memcpy(iv, vec->iv, vec->iv_size); |
| 365 | aead_request_set_crypt(req, sg, sg, vec->plaintext_size, iv); |
| 366 | err = crypto_aead_encrypt(req); |
| 367 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 368 | pr_err("%s encryption failed: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 369 | goto out; |
| 370 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 371 | err = fips_check_result(message, vec->ciphertext, vec->ciphertext_size, |
| 372 | impl, "encryption"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 373 | if (err) |
| 374 | goto out; |
| 375 | |
| 376 | /* |
| 377 | * Decrypt the ciphertext (which includes the authentication tag), then |
| 378 | * verify the resulting plaintext. |
| 379 | */ |
| 380 | memcpy(iv, vec->iv, vec->iv_size); |
| 381 | aead_request_set_crypt(req, sg, sg, vec->ciphertext_size, iv); |
| 382 | err = crypto_aead_decrypt(req); |
| 383 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 384 | pr_err("%s decryption failed: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 385 | goto out; |
| 386 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 387 | err = fips_check_result(message, vec->plaintext, vec->plaintext_size, |
| 388 | impl, "decryption"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 389 | out: |
| 390 | kfree(message); |
| 391 | kfree(assoc); |
| 392 | aead_request_free(req); |
| 393 | crypto_free_aead(tfm); |
| 394 | return err; |
| 395 | } |
| 396 | |
| 397 | /* |
| 398 | * Test a hash algorithm using the crypto_shash API. |
| 399 | * |
| 400 | * Note that we don't need to test the crypto_ahash API too, since none of the |
| 401 | * hash algorithms in the FIPS module have the ASYNC flag, and thus there will |
| 402 | * be no hash algorithms that can be accessed only through crypto_ahash. |
| 403 | */ |
| 404 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 405 | fips_test_hash(const struct fips_test *test, const char *impl) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 406 | { |
| 407 | const struct hash_testvec *vec = &test->hash; |
| 408 | struct crypto_shash *tfm; |
| 409 | u8 digest[HASH_MAX_DIGESTSIZE]; |
| 410 | int err; |
| 411 | |
| 412 | if (WARN_ON(vec->digest_size > HASH_MAX_DIGESTSIZE)) |
| 413 | return -EINVAL; |
| 414 | |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 415 | tfm = crypto_alloc_shash(impl, 0, 0); |
| 416 | if (IS_ERR(tfm)) |
| 417 | return fips_handle_alloc_tfm_error(impl, PTR_ERR(tfm)); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 418 | err = fips_validate_alg(&crypto_shash_alg(tfm)->base); |
| 419 | if (err) |
| 420 | goto out; |
| 421 | if (crypto_shash_digestsize(tfm) != vec->digest_size) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 422 | pr_err("%s has wrong digest size\n", impl); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 423 | err = -EINVAL; |
| 424 | goto out; |
| 425 | } |
| 426 | |
| 427 | if (vec->key) { |
| 428 | err = crypto_shash_setkey(tfm, vec->key, vec->key_size); |
| 429 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 430 | pr_err("failed to set %s key: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 431 | goto out; |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | err = crypto_shash_tfm_digest(tfm, vec->message, vec->message_size, |
| 436 | digest); |
| 437 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 438 | pr_err("%s digest computation failed: %d\n", impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 439 | goto out; |
| 440 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 441 | err = fips_check_result(digest, vec->digest, vec->digest_size, |
| 442 | impl, "digest"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 443 | out: |
| 444 | crypto_free_shash(tfm); |
| 445 | return err; |
| 446 | } |
| 447 | |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 448 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 449 | fips_test_sha256_library(const struct fips_test *test, const char *impl) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 450 | { |
| 451 | const struct hash_testvec *vec = &test->hash; |
| 452 | u8 digest[SHA256_DIGEST_SIZE]; |
| 453 | |
| 454 | if (WARN_ON(vec->digest_size != SHA256_DIGEST_SIZE)) |
| 455 | return -EINVAL; |
| 456 | |
| 457 | sha256(vec->message, vec->message_size, digest); |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 458 | return fips_check_result(digest, vec->digest, vec->digest_size, |
| 459 | impl, "digest"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 460 | } |
| 461 | |
| 462 | /* Test a DRBG using the crypto_rng API. */ |
| 463 | static int __init __must_check |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 464 | fips_test_drbg(const struct fips_test *test, const char *impl) |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 465 | { |
| 466 | const struct drbg_testvec *vec = &test->drbg; |
| 467 | struct crypto_rng *rng; |
| 468 | u8 *output = NULL; |
| 469 | struct drbg_test_data test_data; |
| 470 | struct drbg_string addtl, pers, testentropy; |
| 471 | int err; |
| 472 | |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 473 | rng = crypto_alloc_rng(impl, 0, 0); |
| 474 | if (IS_ERR(rng)) |
| 475 | return fips_handle_alloc_tfm_error(impl, PTR_ERR(rng)); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 476 | err = fips_validate_alg(&crypto_rng_alg(rng)->base); |
| 477 | if (err) |
| 478 | goto out; |
| 479 | |
| 480 | output = kzalloc(vec->out_size, GFP_KERNEL); |
| 481 | if (!output) { |
| 482 | err = -ENOMEM; |
| 483 | goto out; |
| 484 | } |
| 485 | |
| 486 | /* |
| 487 | * Initialize the DRBG with the entropy and personalization string given |
| 488 | * in the test vector. |
| 489 | */ |
| 490 | test_data.testentropy = &testentropy; |
| 491 | drbg_string_fill(&testentropy, vec->entropy, vec->entropy_size); |
| 492 | drbg_string_fill(&pers, vec->pers, vec->pers_size); |
| 493 | err = crypto_drbg_reset_test(rng, &pers, &test_data); |
| 494 | if (err) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 495 | pr_err("failed to reset %s\n", impl); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 496 | goto out; |
| 497 | } |
| 498 | |
| 499 | /* |
| 500 | * Generate some random bytes using the additional data string provided |
| 501 | * in the test vector. Also use the additional entropy if provided |
| 502 | * (relevant for the prediction-resistant DRBG variants only). |
| 503 | */ |
| 504 | drbg_string_fill(&addtl, vec->add_a, vec->add_size); |
| 505 | if (vec->entpr_size) { |
| 506 | drbg_string_fill(&testentropy, vec->entpr_a, vec->entpr_size); |
| 507 | err = crypto_drbg_get_bytes_addtl_test(rng, output, |
| 508 | vec->out_size, &addtl, |
| 509 | &test_data); |
| 510 | } else { |
| 511 | err = crypto_drbg_get_bytes_addtl(rng, output, vec->out_size, |
| 512 | &addtl); |
| 513 | } |
| 514 | if (err) { |
| 515 | pr_err("failed to get bytes from %s (try 1): %d\n", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 516 | impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 517 | goto out; |
| 518 | } |
| 519 | |
| 520 | /* |
| 521 | * Do the same again, using a second additional data string, and (when |
| 522 | * applicable) a second additional entropy string. |
| 523 | */ |
| 524 | drbg_string_fill(&addtl, vec->add_b, vec->add_size); |
| 525 | if (test->drbg.entpr_size) { |
| 526 | drbg_string_fill(&testentropy, vec->entpr_b, vec->entpr_size); |
| 527 | err = crypto_drbg_get_bytes_addtl_test(rng, output, |
| 528 | vec->out_size, &addtl, |
| 529 | &test_data); |
| 530 | } else { |
| 531 | err = crypto_drbg_get_bytes_addtl(rng, output, vec->out_size, |
| 532 | &addtl); |
| 533 | } |
| 534 | if (err) { |
| 535 | pr_err("failed to get bytes from %s (try 2): %d\n", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 536 | impl, err); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 537 | goto out; |
| 538 | } |
| 539 | |
| 540 | /* Check that the DRBG generated the expected output. */ |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 541 | err = fips_check_result(output, vec->output, vec->out_size, |
| 542 | impl, "get_bytes"); |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 543 | out: |
| 544 | kfree(output); |
| 545 | crypto_free_rng(rng); |
| 546 | return err; |
| 547 | } |
| 548 | |
| 549 | /* Include the test vectors generated by the Python script. */ |
| 550 | #include "fips140-generated-testvecs.h" |
| 551 | |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 552 | /* |
| 553 | * List of all self-tests. Keep this in sync with fips140_algorithms[]. |
| 554 | * |
| 555 | * When possible, we have followed the FIPS 140-2 Implementation Guidance (IG) |
| 556 | * document when creating this list of tests. The result is intended to be a |
| 557 | * list of tests that is near-minimal (and thus minimizes runtime overhead) |
| 558 | * while complying with all requirements. For additional details, see the |
| 559 | * comment at the beginning of this file. |
| 560 | */ |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 561 | static const struct fips_test fips140_selftests[] __initconst = { |
| 562 | /* |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 563 | * Test for the AES library API. |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 564 | * |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 565 | * Since the AES library API may use its own AES implementation and the |
| 566 | * module provides no support for composing it with a mode of operation |
| 567 | * (it's just plain AES), we must test it directly. |
| 568 | * |
| 569 | * In contrast, we don't need to directly test the "aes" ciphers that |
| 570 | * are accessible through the crypto_cipher API (e.g. "aes-ce"), as they |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 571 | * are covered indirectly by AES-CMAC and AES-ECB tests. |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 572 | */ |
| 573 | { |
| 574 | .alg = "aes", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 575 | .impls = {"aes-lib"}, |
| 576 | .func = fips_test_aes_library, |
| 577 | .skcipher = { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 578 | .key = fips_aes_key, |
| 579 | .key_size = sizeof(fips_aes_key), |
| 580 | .plaintext = fips_message, |
| 581 | .ciphertext = fips_aes_ecb_ciphertext, |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 582 | .message_size = 16, |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 583 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 584 | }, |
| 585 | /* |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 586 | * Tests for AES-CMAC, a.k.a. "cmac(aes)" in crypto API syntax. |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 587 | * |
| 588 | * The IG requires that each underlying AES implementation be tested in |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 589 | * an authenticated mode, if implemented. Of such modes, this module |
| 590 | * implements AES-GCM and AES-CMAC. However, AES-GCM doesn't "count" |
| 591 | * because this module's implementations of AES-GCM won't actually be |
| 592 | * FIPS-approved, due to a quirk in the FIPS requirements. |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 593 | * |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 594 | * Therefore, for us this requirement applies to AES-CMAC, so we must |
| 595 | * test the "cmac" template composed with each "aes" implementation. |
| 596 | * |
| 597 | * Separately from the above, we also must test all standalone |
| 598 | * implementations of "cmac(aes)" such as "cmac-aes-ce", as they don't |
| 599 | * reuse another full AES implementation and thus can't be covered by |
| 600 | * another test. |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 601 | */ |
| 602 | { |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 603 | .alg = "cmac(aes)", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 604 | .impls = { |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 605 | /* "cmac" template with all "aes" implementations */ |
| 606 | "cmac(aes-generic)", |
| 607 | "cmac(aes-arm64)", |
| 608 | "cmac(aes-ce)", |
| 609 | /* All standalone implementations of "cmac(aes)" */ |
| 610 | "cmac-aes-neon", |
| 611 | "cmac-aes-ce", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 612 | }, |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 613 | .func = fips_test_hash, |
| 614 | .hash = { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 615 | .key = fips_aes_key, |
| 616 | .key_size = sizeof(fips_aes_key), |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 617 | .message = fips_message, |
| 618 | .message_size = sizeof(fips_message), |
| 619 | .digest = fips_aes_cmac_digest, |
| 620 | .digest_size = sizeof(fips_aes_cmac_digest), |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 621 | } |
| 622 | }, |
| 623 | /* |
| 624 | * Tests for AES-ECB, a.k.a. "ecb(aes)" in crypto API syntax. |
| 625 | * |
| 626 | * The IG requires that each underlying AES implementation be tested in |
| 627 | * a mode that exercises the encryption direction of AES and in a mode |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 628 | * that exercises the decryption direction of AES. CMAC only covers the |
| 629 | * encryption direction, so we choose ECB to test decryption. Thus, we |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 630 | * test the "ecb" template composed with each "aes" implementation. |
| 631 | * |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 632 | * Separately from the above, we also must test all standalone |
| 633 | * implementations of "ecb(aes)" such as "ecb-aes-ce", as they don't |
| 634 | * reuse another full AES implementation and thus can't be covered by |
| 635 | * another test. |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 636 | */ |
| 637 | { |
| 638 | .alg = "ecb(aes)", |
| 639 | .impls = { |
| 640 | /* "ecb" template with all "aes" implementations */ |
| 641 | "ecb(aes-generic)", |
| 642 | "ecb(aes-arm64)", |
| 643 | "ecb(aes-ce)", |
| 644 | /* All standalone implementations of "ecb(aes)" */ |
| 645 | "ecb-aes-neon", |
| 646 | "ecb-aes-neonbs", |
| 647 | "ecb-aes-ce", |
| 648 | }, |
| 649 | .func = fips_test_skcipher, |
| 650 | .skcipher = { |
| 651 | .key = fips_aes_key, |
| 652 | .key_size = sizeof(fips_aes_key), |
| 653 | .plaintext = fips_message, |
| 654 | .ciphertext = fips_aes_ecb_ciphertext, |
| 655 | .message_size = sizeof(fips_message) |
| 656 | } |
| 657 | }, |
| 658 | /* |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 659 | * Tests for AES-CBC, AES-CBC-CTS, AES-CTR, AES-XTS, and AES-GCM. |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 660 | * |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 661 | * According to the IG, an AES mode of operation doesn't need to have |
| 662 | * its own test, provided that (a) both the encryption and decryption |
| 663 | * directions of the underlying AES implementation are already tested |
| 664 | * via other mode(s), and (b) in the case of an authenticated mode, at |
| 665 | * least one other authenticated mode is already tested. The tests of |
| 666 | * the "cmac" and "ecb" templates fulfill these conditions; therefore, |
| 667 | * we don't need to test any other AES mode templates. |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 668 | * |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 669 | * This does *not* apply to standalone implementations of these modes |
| 670 | * such as "cbc-aes-ce", as such implementations don't reuse another |
| 671 | * full AES implementation and thus can't be covered by another test. |
| 672 | * We must test all such standalone implementations. |
| 673 | * |
| 674 | * The AES-GCM test isn't actually required, as it's expected that this |
| 675 | * module's AES-GCM implementation won't actually be able to be |
| 676 | * FIPS-approved. This is unfortunate; it's caused by the FIPS |
| 677 | * requirements for GCM being incompatible with GCM implementations that |
| 678 | * don't generate their own IVs. We choose to still include the AES-GCM |
| 679 | * test to keep it on par with the other FIPS-approved algorithms, in |
| 680 | * case it turns out that AES-GCM can be approved after all. |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 681 | */ |
| 682 | { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 683 | .alg = "cbc(aes)", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 684 | .impls = { |
| 685 | /* All standalone implementations of "cbc(aes)" */ |
| 686 | "cbc-aes-neon", |
| 687 | "cbc-aes-neonbs", |
| 688 | "cbc-aes-ce", |
| 689 | }, |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 690 | .func = fips_test_skcipher, |
| 691 | .skcipher = { |
| 692 | .key = fips_aes_key, |
| 693 | .key_size = sizeof(fips_aes_key), |
| 694 | .iv = fips_aes_iv, |
| 695 | .iv_size = sizeof(fips_aes_iv), |
| 696 | .plaintext = fips_message, |
| 697 | .ciphertext = fips_aes_cbc_ciphertext, |
| 698 | .message_size = sizeof(fips_message), |
| 699 | } |
| 700 | }, { |
Eric Biggers | 2b5843a | 2021-08-04 17:21:58 -0700 | [diff] [blame] | 701 | .alg = "cts(cbc(aes))", |
| 702 | .impls = { |
| 703 | /* All standalone implementations of "cts(cbc(aes))" */ |
| 704 | "cts-cbc-aes-neon", |
| 705 | "cts-cbc-aes-ce", |
| 706 | }, |
| 707 | .func = fips_test_skcipher, |
| 708 | /* Test vector taken from RFC 3962 */ |
| 709 | .skcipher = { |
| 710 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" |
| 711 | "\x74\x65\x72\x69\x79\x61\x6b\x69", |
| 712 | .key_size = 16, |
| 713 | .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" |
| 714 | "\x00\x00\x00\x00\x00\x00\x00\x00", |
| 715 | .iv_size = 16, |
| 716 | .plaintext = "\x49\x20\x77\x6f\x75\x6c\x64\x20" |
| 717 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" |
| 718 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" |
| 719 | "\x20\x47\x61\x75\x27\x73\x20", |
| 720 | .ciphertext = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1" |
| 721 | "\xd4\x45\xd4\xc8\xef\xf7\xed\x22" |
| 722 | "\x97\x68\x72\x68\xd6\xec\xcc\xc0" |
| 723 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5", |
| 724 | .message_size = 31, |
| 725 | } |
| 726 | }, { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 727 | .alg = "ctr(aes)", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 728 | .impls = { |
| 729 | /* All standalone implementations of "ctr(aes)" */ |
| 730 | "ctr-aes-neon", |
| 731 | "ctr-aes-neonbs", |
| 732 | "ctr-aes-ce", |
| 733 | }, |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 734 | .func = fips_test_skcipher, |
| 735 | .skcipher = { |
| 736 | .key = fips_aes_key, |
| 737 | .key_size = sizeof(fips_aes_key), |
| 738 | .iv = fips_aes_iv, |
| 739 | .iv_size = sizeof(fips_aes_iv), |
| 740 | .plaintext = fips_message, |
| 741 | .ciphertext = fips_aes_ctr_ciphertext, |
| 742 | .message_size = sizeof(fips_message), |
| 743 | } |
| 744 | }, { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 745 | .alg = "xts(aes)", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 746 | .impls = { |
| 747 | /* All standalone implementations of "xts(aes)" */ |
| 748 | "xts-aes-neon", |
| 749 | "xts-aes-neonbs", |
| 750 | "xts-aes-ce", |
| 751 | }, |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 752 | .func = fips_test_skcipher, |
| 753 | .skcipher = { |
| 754 | .key = fips_aes_xts_key, |
| 755 | .key_size = sizeof(fips_aes_xts_key), |
| 756 | .iv = fips_aes_iv, |
| 757 | .iv_size = sizeof(fips_aes_iv), |
| 758 | .plaintext = fips_message, |
| 759 | .ciphertext = fips_aes_xts_ciphertext, |
| 760 | .message_size = sizeof(fips_message), |
| 761 | } |
Eric Biggers | 2ee56aa | 2021-08-04 17:21:59 -0700 | [diff] [blame] | 762 | }, { |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 763 | .alg = "gcm(aes)", |
Eric Biggers | 2ee56aa | 2021-08-04 17:21:59 -0700 | [diff] [blame] | 764 | .impls = { |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 765 | /* All standalone implementations of "gcm(aes)" */ |
| 766 | "gcm-aes-ce", |
Eric Biggers | 2ee56aa | 2021-08-04 17:21:59 -0700 | [diff] [blame] | 767 | }, |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 768 | .func = fips_test_aead, |
| 769 | .aead = { |
Eric Biggers | 2ee56aa | 2021-08-04 17:21:59 -0700 | [diff] [blame] | 770 | .key = fips_aes_key, |
| 771 | .key_size = sizeof(fips_aes_key), |
Eric Biggers | e5b1439 | 2021-08-05 13:49:23 -0700 | [diff] [blame] | 772 | .iv = fips_aes_iv, |
| 773 | /* The GCM implementations assume an IV size of 12. */ |
| 774 | .iv_size = 12, |
| 775 | .assoc = fips_aes_gcm_assoc, |
| 776 | .assoc_size = sizeof(fips_aes_gcm_assoc), |
| 777 | .plaintext = fips_message, |
| 778 | .plaintext_size = sizeof(fips_message), |
| 779 | .ciphertext = fips_aes_gcm_ciphertext, |
| 780 | .ciphertext_size = sizeof(fips_aes_gcm_ciphertext), |
Eric Biggers | 2ee56aa | 2021-08-04 17:21:59 -0700 | [diff] [blame] | 781 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 782 | }, |
| 783 | |
| 784 | /* Tests for SHA-1 */ |
| 785 | { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 786 | .alg = "sha1", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 787 | .impls = { |
| 788 | /* All implementations of "sha1" */ |
| 789 | "sha1-generic", |
| 790 | "sha1-ce" |
| 791 | }, |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 792 | .func = fips_test_hash, |
| 793 | .hash = { |
| 794 | .message = fips_message, |
| 795 | .message_size = sizeof(fips_message), |
| 796 | .digest = fips_sha1_digest, |
| 797 | .digest_size = sizeof(fips_sha1_digest) |
| 798 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 799 | }, |
| 800 | /* |
| 801 | * Tests for all SHA-256 implementations other than the sha256() library |
| 802 | * function. As per the IG, these tests also fulfill the tests for the |
| 803 | * corresponding SHA-224 implementations. |
| 804 | */ |
| 805 | { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 806 | .alg = "sha256", |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 807 | .impls = { |
| 808 | /* All implementations of "sha256" */ |
| 809 | "sha256-generic", |
| 810 | "sha256-arm64", |
| 811 | "sha256-ce", |
| 812 | }, |
| 813 | .func = fips_test_hash, |
| 814 | .hash = { |
| 815 | .message = fips_message, |
| 816 | .message_size = sizeof(fips_message), |
| 817 | .digest = fips_sha256_digest, |
| 818 | .digest_size = sizeof(fips_sha256_digest) |
| 819 | } |
| 820 | }, |
| 821 | /* |
| 822 | * Test for the sha256() library function. This must be tested |
| 823 | * separately because it may use its own SHA-256 implementation. |
| 824 | */ |
| 825 | { |
| 826 | .alg = "sha256", |
| 827 | .impls = {"sha256-lib"}, |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 828 | .func = fips_test_sha256_library, |
| 829 | .hash = { |
| 830 | .message = fips_message, |
| 831 | .message_size = sizeof(fips_message), |
| 832 | .digest = fips_sha256_digest, |
| 833 | .digest_size = sizeof(fips_sha256_digest) |
| 834 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 835 | }, |
| 836 | /* |
| 837 | * Tests for all SHA-512 implementations. As per the IG, these tests |
| 838 | * also fulfill the tests for the corresponding SHA-384 implementations. |
| 839 | */ |
| 840 | { |
| 841 | .alg = "sha512", |
| 842 | .impls = { |
| 843 | /* All implementations of "sha512" */ |
| 844 | "sha512-generic", |
| 845 | "sha512-arm64", |
| 846 | "sha512-ce", |
| 847 | }, |
| 848 | .func = fips_test_hash, |
| 849 | .hash = { |
| 850 | .message = fips_message, |
| 851 | .message_size = sizeof(fips_message), |
| 852 | .digest = fips_sha512_digest, |
| 853 | .digest_size = sizeof(fips_sha512_digest) |
| 854 | } |
| 855 | }, |
| 856 | /* |
| 857 | * Test for HMAC. As per the IG, only one HMAC test is required, |
| 858 | * provided that the same HMAC code is shared by all HMAC-SHA*. This is |
| 859 | * true in our case. We choose HMAC-SHA256 for the test. |
| 860 | * |
| 861 | * Note that as per the IG, this can fulfill the test for the underlying |
| 862 | * SHA. However, we don't currently rely on this. |
| 863 | */ |
| 864 | { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 865 | .alg = "hmac(sha256)", |
| 866 | .func = fips_test_hash, |
| 867 | .hash = { |
| 868 | .key = fips_hmac_key, |
| 869 | .key_size = sizeof(fips_hmac_key), |
| 870 | .message = fips_message, |
| 871 | .message_size = sizeof(fips_message), |
| 872 | .digest = fips_hmac_sha256_digest, |
| 873 | .digest_size = sizeof(fips_hmac_sha256_digest) |
| 874 | } |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 875 | }, |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 876 | /* |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 877 | * Known-answer tests for the SP800-90A DRBG algorithms. |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 878 | * |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 879 | * These test vectors were manually extracted from |
| 880 | * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip. |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 881 | * |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 882 | * The selection of these tests follows the FIPS 140-2 IG as well as |
| 883 | * Section 11 of SP800-90A: |
| 884 | * |
| 885 | * - We must test all DRBG types (HMAC, Hash, and CTR) that the module |
| 886 | * implements. However, currently the module only implements |
| 887 | * HMAC_DRBG (since CONFIG_CRYPTO_DRBG_CTR and CONFIG_CRYPTO_DRBG_HASH |
| 888 | * aren't enabled). Therefore, we only need to test HMAC_DRBG. |
| 889 | * |
| 890 | * - We only need to test one HMAC variant. |
| 891 | * |
| 892 | * - We must test all DRBG operations: Instantiate(), Reseed(), and |
| 893 | * Generate(). However, a single test sequence with a single output |
| 894 | * comparison may cover all three operations, and this is what we do. |
| 895 | * Note that Reseed() happens implicitly via the use of the additional |
| 896 | * input and also via the use of prediction resistance when enabled. |
| 897 | * |
| 898 | * - The personalization string, additional input, and prediction |
| 899 | * resistance support must be tested. Therefore we have chosen test |
| 900 | * vectors that have a nonempty personalization string and nonempty |
| 901 | * additional input, and we test the prediction-resistant variant. |
Eric Biggers | 1be58af | 2021-08-04 17:21:57 -0700 | [diff] [blame] | 902 | * Testing the non-prediction-resistant variant is not required. |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 903 | */ |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 904 | { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 905 | .alg = "drbg_pr_hmac_sha256", |
| 906 | .func = fips_test_drbg, |
| 907 | .drbg = { |
| 908 | .entropy = |
| 909 | "\xc7\xcc\xbc\x67\x7e\x21\x66\x1e\x27\x2b\x63\xdd" |
| 910 | "\x3a\x78\xdc\xdf\x66\x6d\x3f\x24\xae\xcf\x37\x01" |
| 911 | "\xa9\x0d\x89\x8a\xa7\xdc\x81\x58\xae\xb2\x10\x15" |
| 912 | "\x7e\x18\x44\x6d\x13\xea\xdf\x37\x85\xfe\x81\xfb", |
| 913 | .entropy_size = 48, |
| 914 | .entpr_a = |
| 915 | "\x7b\xa1\x91\x5b\x3c\x04\xc4\x1b\x1d\x19\x2f\x1a" |
| 916 | "\x18\x81\x60\x3c\x6c\x62\x91\xb7\xe9\xf5\xcb\x96" |
| 917 | "\xbb\x81\x6a\xcc\xb5\xae\x55\xb6", |
| 918 | .entpr_b = |
| 919 | "\x99\x2c\xc7\x78\x7e\x3b\x88\x12\xef\xbe\xd3\xd2" |
| 920 | "\x7d\x2a\xa5\x86\xda\x8d\x58\x73\x4a\x0a\xb2\x2e" |
| 921 | "\xbb\x4c\x7e\xe3\x9a\xb6\x81\xc1", |
| 922 | .entpr_size = 32, |
| 923 | .output = |
| 924 | "\x95\x6f\x95\xfc\x3b\xb7\xfe\x3e\xd0\x4e\x1a\x14" |
| 925 | "\x6c\x34\x7f\x7b\x1d\x0d\x63\x5e\x48\x9c\x69\xe6" |
| 926 | "\x46\x07\xd2\x87\xf3\x86\x52\x3d\x98\x27\x5e\xd7" |
| 927 | "\x54\xe7\x75\x50\x4f\xfb\x4d\xfd\xac\x2f\x4b\x77" |
| 928 | "\xcf\x9e\x8e\xcc\x16\xa2\x24\xcd\x53\xde\x3e\xc5" |
| 929 | "\x55\x5d\xd5\x26\x3f\x89\xdf\xca\x8b\x4e\x1e\xb6" |
| 930 | "\x88\x78\x63\x5c\xa2\x63\x98\x4e\x6f\x25\x59\xb1" |
| 931 | "\x5f\x2b\x23\xb0\x4b\xa5\x18\x5d\xc2\x15\x74\x40" |
| 932 | "\x59\x4c\xb4\x1e\xcf\x9a\x36\xfd\x43\xe2\x03\xb8" |
| 933 | "\x59\x91\x30\x89\x2a\xc8\x5a\x43\x23\x7c\x73\x72" |
| 934 | "\xda\x3f\xad\x2b\xba\x00\x6b\xd1", |
| 935 | .out_size = 128, |
| 936 | .add_a = |
| 937 | "\x18\xe8\x17\xff\xef\x39\xc7\x41\x5c\x73\x03\x03" |
| 938 | "\xf6\x3d\xe8\x5f\xc8\xab\xe4\xab\x0f\xad\xe8\xd6" |
| 939 | "\x86\x88\x55\x28\xc1\x69\xdd\x76", |
| 940 | .add_b = |
| 941 | "\xac\x07\xfc\xbe\x87\x0e\xd3\xea\x1f\x7e\xb8\xe7" |
| 942 | "\x9d\xec\xe8\xe7\xbc\xf3\x18\x25\x77\x35\x4a\xaa" |
| 943 | "\x00\x99\x2a\xdd\x0a\x00\x50\x82", |
| 944 | .add_size = 32, |
| 945 | .pers = |
| 946 | "\xbc\x55\xab\x3c\xf6\x52\xb0\x11\x3d\x7b\x90\xb8" |
| 947 | "\x24\xc9\x26\x4e\x5a\x1e\x77\x0d\x3d\x58\x4a\xda" |
| 948 | "\xd1\x81\xe9\xf8\xeb\x30\x8f\x6f", |
| 949 | .pers_size = 32, |
| 950 | } |
| 951 | } |
| 952 | }; |
| 953 | |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 954 | static int __init __must_check |
| 955 | fips_run_test(const struct fips_test *test) |
| 956 | { |
| 957 | int i; |
| 958 | int err; |
| 959 | |
| 960 | /* |
| 961 | * If no implementations were specified, then just test the default one. |
| 962 | * Otherwise, test the specified list of implementations. |
| 963 | */ |
| 964 | |
| 965 | if (test->impls[0] == NULL) { |
| 966 | err = test->func(test, test->alg); |
| 967 | if (err) |
| 968 | pr_emerg("self-tests failed for algorithm %s: %d\n", |
| 969 | test->alg, err); |
| 970 | return err; |
| 971 | } |
| 972 | |
| 973 | for (i = 0; i < ARRAY_SIZE(test->impls) && test->impls[i] != NULL; |
| 974 | i++) { |
| 975 | err = test->func(test, test->impls[i]); |
| 976 | if (err) { |
| 977 | pr_emerg("self-tests failed for algorithm %s, implementation %s: %d\n", |
| 978 | test->alg, test->impls[i], err); |
| 979 | return err; |
| 980 | } |
| 981 | } |
| 982 | return 0; |
| 983 | } |
| 984 | |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 985 | bool __init fips140_run_selftests(void) |
| 986 | { |
| 987 | int i; |
| 988 | |
| 989 | pr_info("running self-tests\n"); |
| 990 | for (i = 0; i < ARRAY_SIZE(fips140_selftests); i++) { |
Eric Biggers | b397a03 | 2021-08-03 23:06:26 -0700 | [diff] [blame] | 991 | if (fips_run_test(&fips140_selftests[i]) != 0) { |
Eric Biggers | b7397e8 | 2021-07-08 14:46:46 -0700 | [diff] [blame] | 992 | /* The caller is responsible for calling panic(). */ |
| 993 | return false; |
| 994 | } |
| 995 | } |
| 996 | pr_info("all self-tests passed\n"); |
| 997 | return true; |
| 998 | } |