1 // SPDX-License-Identifier: GPL-2.0 1 2 3 /* 4 * SP800-108 Key-derivation function 5 * 6 * Copyright (C) 2021, Stephan Mueller <smuell 7 */ 8 9 #include <linux/fips.h> 10 #include <linux/module.h> 11 #include <crypto/kdf_sp800108.h> 12 #include <crypto/internal/kdf_selftest.h> 13 14 /* 15 * SP800-108 CTR KDF implementation 16 */ 17 int crypto_kdf108_ctr_generate(struct crypto_s 18 const struct kv 19 u8 *dst, unsign 20 { 21 SHASH_DESC_ON_STACK(desc, kmd); 22 __be32 counter = cpu_to_be32(1); 23 const unsigned int h = crypto_shash_di 24 unsigned int i; 25 int err = 0; 26 u8 *dst_orig = dst; 27 28 desc->tfm = kmd; 29 30 while (dlen) { 31 err = crypto_shash_init(desc); 32 if (err) 33 goto out; 34 35 err = crypto_shash_update(desc 36 if (err) 37 goto out; 38 39 for (i = 0; i < info_nvec; i++ 40 err = crypto_shash_upd 41 42 if (err) 43 goto out; 44 } 45 46 if (dlen < h) { 47 u8 tmpbuffer[HASH_MAX_ 48 49 err = crypto_shash_fin 50 if (err) 51 goto out; 52 memcpy(dst, tmpbuffer, 53 memzero_explicit(tmpbu 54 goto out; 55 } 56 57 err = crypto_shash_final(desc, 58 if (err) 59 goto out; 60 61 dlen -= h; 62 dst += h; 63 counter = cpu_to_be32(be32_to_ 64 } 65 66 out: 67 if (err) 68 memzero_explicit(dst_orig, dle 69 shash_desc_zero(desc); 70 return err; 71 } 72 EXPORT_SYMBOL(crypto_kdf108_ctr_generate); 73 74 /* 75 * The seeding of the KDF 76 */ 77 int crypto_kdf108_setkey(struct crypto_shash * 78 const u8 *key, size_t 79 const u8 *ikm, size_t 80 { 81 unsigned int ds = crypto_shash_digests 82 83 /* SP800-108 does not support IKM */ 84 if (ikm || ikmlen) 85 return -EINVAL; 86 87 /* Check according to SP800-108 sectio 88 if (ds > keylen) 89 return -EINVAL; 90 91 /* Set the key for the MAC used for th 92 return crypto_shash_setkey(kmd, key, k 93 } 94 EXPORT_SYMBOL(crypto_kdf108_setkey); 95 96 /* 97 * Test vector obtained from 98 * http://csrc.nist.gov/groups/STM/cavp/docume 99 */ 100 static const struct kdf_testvec kdf_ctr_hmac_s 101 { 102 .key = "\xdd\x1d\x91\xb7\xd9\x 103 "\x13\x85\x33\xce\x92\x 104 "\xf8\xa3\x69\x31\x6a\x 105 "\xe6\x59\xcc\x0a\xe2\x 106 .keylen = 32, 107 .ikm = NULL, 108 .ikmlen = 0, 109 .info = { 110 .iov_base = "\x01\x32\ 111 "\x79\x79\ 112 "\x68\x59\ 113 "\xe7\x25\ 114 "\x64\xa1\ 115 "\x08\xf8\ 116 "\x11\xd8\ 117 "\xb4\x13\ 118 .iov_len = 60 119 }, 120 .expected = "\x10\x62\ 121 "\x04\x6c\ 122 .expectedlen = 16 123 } 124 }; 125 126 static int __init crypto_kdf108_init(void) 127 { 128 int ret; 129 130 if (IS_ENABLED(CONFIG_CRYPTO_MANAGER_D 131 return 0; 132 133 ret = kdf_test(&kdf_ctr_hmac_sha256_tv 134 crypto_kdf108_setkey, c 135 if (ret) { 136 if (fips_enabled) 137 panic("alg: self-tests 138 ret); 139 140 WARN(1, 141 "alg: self-tests for CTR- 142 ret); 143 } else if (fips_enabled) { 144 pr_info("alg: self-tests for C 145 } 146 147 return ret; 148 } 149 150 static void __exit crypto_kdf108_exit(void) { 151 152 module_init(crypto_kdf108_init); 153 module_exit(crypto_kdf108_exit); 154 155 MODULE_LICENSE("GPL v2"); 156 MODULE_AUTHOR("Stephan Mueller <smueller@chron 157 MODULE_DESCRIPTION("Key Derivation Function co 158
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.