1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | |
3 | /* |
4 | * Copyright (C) 2021, Stephan Mueller <smueller@chronox.de> |
5 | */ |
6 | |
7 | #ifndef _CRYPTO_KDF_SELFTEST_H |
8 | #define _CRYPTO_KDF_SELFTEST_H |
9 | |
10 | #include <crypto/hash.h> |
11 | #include <linux/uio.h> |
12 | |
13 | struct kdf_testvec { |
14 | unsigned char *key; |
15 | size_t keylen; |
16 | unsigned char *ikm; |
17 | size_t ikmlen; |
18 | struct kvec info; |
19 | unsigned char *expected; |
20 | size_t expectedlen; |
21 | }; |
22 | |
23 | static inline int |
24 | kdf_test(const struct kdf_testvec *test, const char *name, |
25 | int (*crypto_kdf_setkey)(struct crypto_shash *kmd, |
26 | const u8 *key, size_t keylen, |
27 | const u8 *ikm, size_t ikmlen), |
28 | int (*crypto_kdf_generate)(struct crypto_shash *kmd, |
29 | const struct kvec *info, |
30 | unsigned int info_nvec, |
31 | u8 *dst, unsigned int dlen)) |
32 | { |
33 | struct crypto_shash *kmd; |
34 | int ret; |
35 | u8 *buf = kzalloc(size: test->expectedlen, GFP_KERNEL); |
36 | |
37 | if (!buf) |
38 | return -ENOMEM; |
39 | |
40 | kmd = crypto_alloc_shash(alg_name: name, type: 0, mask: 0); |
41 | if (IS_ERR(ptr: kmd)) { |
42 | pr_err("alg: kdf: could not allocate hash handle for %s\n" , |
43 | name); |
44 | kfree(objp: buf); |
45 | return -ENOMEM; |
46 | } |
47 | |
48 | ret = crypto_kdf_setkey(kmd, test->key, test->keylen, |
49 | test->ikm, test->ikmlen); |
50 | if (ret) { |
51 | pr_err("alg: kdf: could not set key derivation key\n" ); |
52 | goto err; |
53 | } |
54 | |
55 | ret = crypto_kdf_generate(kmd, &test->info, 1, buf, test->expectedlen); |
56 | if (ret) { |
57 | pr_err("alg: kdf: could not obtain key data\n" ); |
58 | goto err; |
59 | } |
60 | |
61 | ret = memcmp(p: test->expected, q: buf, size: test->expectedlen); |
62 | if (ret) |
63 | ret = -EINVAL; |
64 | |
65 | err: |
66 | crypto_free_shash(tfm: kmd); |
67 | kfree(objp: buf); |
68 | return ret; |
69 | } |
70 | |
71 | #endif /* _CRYPTO_KDF_SELFTEST_H */ |
72 | |