diff options
author | Tudor-Dan Ambarus <tudor.ambarus@microchip.com> | 2017-05-30 10:52:49 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-06-10 00:04:36 -0400 |
commit | 47d3fd390e899e0403da35733b75832eacfbbc3f (patch) | |
tree | 978c7091ffb0209330bb560fe5e5cf554ded03a9 /crypto | |
parent | 6755fd269d5c100b0eca420db501ae58435efd6e (diff) |
crypto: testmgr - add genkey kpp test
The test considers a party that already has a private-public
key pair and a party that provides a NULL key. The kernel will
generate the private-public key pair for the latter, computes
the shared secret on both ends and verifies if it's the same.
The explicit private-public key pair was copied from
the previous test vector.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/testmgr.c | 76 | ||||
-rw-r--r-- | crypto/testmgr.h | 47 |
2 files changed, 112 insertions, 11 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 6f5f3ed8376c..5f8e6838e5a8 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -1997,6 +1997,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, | |||
1997 | struct kpp_request *req; | 1997 | struct kpp_request *req; |
1998 | void *input_buf = NULL; | 1998 | void *input_buf = NULL; |
1999 | void *output_buf = NULL; | 1999 | void *output_buf = NULL; |
2000 | void *a_public = NULL; | ||
2001 | void *a_ss = NULL; | ||
2002 | void *shared_secret = NULL; | ||
2000 | struct tcrypt_result result; | 2003 | struct tcrypt_result result; |
2001 | unsigned int out_len_max; | 2004 | unsigned int out_len_max; |
2002 | int err = -ENOMEM; | 2005 | int err = -ENOMEM; |
@@ -2026,20 +2029,31 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, | |||
2026 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | 2029 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
2027 | tcrypt_complete, &result); | 2030 | tcrypt_complete, &result); |
2028 | 2031 | ||
2029 | /* Compute public key */ | 2032 | /* Compute party A's public key */ |
2030 | err = wait_async_op(&result, crypto_kpp_generate_public_key(req)); | 2033 | err = wait_async_op(&result, crypto_kpp_generate_public_key(req)); |
2031 | if (err) { | 2034 | if (err) { |
2032 | pr_err("alg: %s: generate public key test failed. err %d\n", | 2035 | pr_err("alg: %s: Party A: generate public key test failed. err %d\n", |
2033 | alg, err); | 2036 | alg, err); |
2034 | goto free_output; | 2037 | goto free_output; |
2035 | } | 2038 | } |
2036 | /* Verify calculated public key */ | 2039 | |
2037 | if (memcmp(vec->expected_a_public, sg_virt(req->dst), | 2040 | if (vec->genkey) { |
2038 | vec->expected_a_public_size)) { | 2041 | /* Save party A's public key */ |
2039 | pr_err("alg: %s: generate public key test failed. Invalid output\n", | 2042 | a_public = kzalloc(out_len_max, GFP_KERNEL); |
2040 | alg); | 2043 | if (!a_public) { |
2041 | err = -EINVAL; | 2044 | err = -ENOMEM; |
2042 | goto free_output; | 2045 | goto free_output; |
2046 | } | ||
2047 | memcpy(a_public, sg_virt(req->dst), out_len_max); | ||
2048 | } else { | ||
2049 | /* Verify calculated public key */ | ||
2050 | if (memcmp(vec->expected_a_public, sg_virt(req->dst), | ||
2051 | vec->expected_a_public_size)) { | ||
2052 | pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n", | ||
2053 | alg); | ||
2054 | err = -EINVAL; | ||
2055 | goto free_output; | ||
2056 | } | ||
2043 | } | 2057 | } |
2044 | 2058 | ||
2045 | /* Calculate shared secret key by using counter part (b) public key. */ | 2059 | /* Calculate shared secret key by using counter part (b) public key. */ |
@@ -2058,15 +2072,53 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, | |||
2058 | tcrypt_complete, &result); | 2072 | tcrypt_complete, &result); |
2059 | err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req)); | 2073 | err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req)); |
2060 | if (err) { | 2074 | if (err) { |
2061 | pr_err("alg: %s: compute shard secret test failed. err %d\n", | 2075 | pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n", |
2062 | alg, err); | 2076 | alg, err); |
2063 | goto free_all; | 2077 | goto free_all; |
2064 | } | 2078 | } |
2079 | |||
2080 | if (vec->genkey) { | ||
2081 | /* Save the shared secret obtained by party A */ | ||
2082 | a_ss = kzalloc(vec->expected_ss_size, GFP_KERNEL); | ||
2083 | if (!a_ss) { | ||
2084 | err = -ENOMEM; | ||
2085 | goto free_all; | ||
2086 | } | ||
2087 | memcpy(a_ss, sg_virt(req->dst), vec->expected_ss_size); | ||
2088 | |||
2089 | /* | ||
2090 | * Calculate party B's shared secret by using party A's | ||
2091 | * public key. | ||
2092 | */ | ||
2093 | err = crypto_kpp_set_secret(tfm, vec->b_secret, | ||
2094 | vec->b_secret_size); | ||
2095 | if (err < 0) | ||
2096 | goto free_all; | ||
2097 | |||
2098 | sg_init_one(&src, a_public, vec->expected_a_public_size); | ||
2099 | sg_init_one(&dst, output_buf, out_len_max); | ||
2100 | kpp_request_set_input(req, &src, vec->expected_a_public_size); | ||
2101 | kpp_request_set_output(req, &dst, out_len_max); | ||
2102 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
2103 | tcrypt_complete, &result); | ||
2104 | err = wait_async_op(&result, | ||
2105 | crypto_kpp_compute_shared_secret(req)); | ||
2106 | if (err) { | ||
2107 | pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", | ||
2108 | alg, err); | ||
2109 | goto free_all; | ||
2110 | } | ||
2111 | |||
2112 | shared_secret = a_ss; | ||
2113 | } else { | ||
2114 | shared_secret = (void *)vec->expected_ss; | ||
2115 | } | ||
2116 | |||
2065 | /* | 2117 | /* |
2066 | * verify shared secret from which the user will derive | 2118 | * verify shared secret from which the user will derive |
2067 | * secret key by executing whatever hash it has chosen | 2119 | * secret key by executing whatever hash it has chosen |
2068 | */ | 2120 | */ |
2069 | if (memcmp(vec->expected_ss, sg_virt(req->dst), | 2121 | if (memcmp(shared_secret, sg_virt(req->dst), |
2070 | vec->expected_ss_size)) { | 2122 | vec->expected_ss_size)) { |
2071 | pr_err("alg: %s: compute shared secret test failed. Invalid output\n", | 2123 | pr_err("alg: %s: compute shared secret test failed. Invalid output\n", |
2072 | alg); | 2124 | alg); |
@@ -2074,8 +2126,10 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, | |||
2074 | } | 2126 | } |
2075 | 2127 | ||
2076 | free_all: | 2128 | free_all: |
2129 | kfree(a_ss); | ||
2077 | kfree(input_buf); | 2130 | kfree(input_buf); |
2078 | free_output: | 2131 | free_output: |
2132 | kfree(a_public); | ||
2079 | kfree(output_buf); | 2133 | kfree(output_buf); |
2080 | free_req: | 2134 | free_req: |
2081 | kpp_request_free(req); | 2135 | kpp_request_free(req); |
diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 429357339dcc..db2e26c0c065 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h | |||
@@ -137,13 +137,16 @@ struct akcipher_testvec { | |||
137 | 137 | ||
138 | struct kpp_testvec { | 138 | struct kpp_testvec { |
139 | const unsigned char *secret; | 139 | const unsigned char *secret; |
140 | const unsigned char *b_secret; | ||
140 | const unsigned char *b_public; | 141 | const unsigned char *b_public; |
141 | const unsigned char *expected_a_public; | 142 | const unsigned char *expected_a_public; |
142 | const unsigned char *expected_ss; | 143 | const unsigned char *expected_ss; |
143 | unsigned short secret_size; | 144 | unsigned short secret_size; |
145 | unsigned short b_secret_size; | ||
144 | unsigned short b_public_size; | 146 | unsigned short b_public_size; |
145 | unsigned short expected_a_public_size; | 147 | unsigned short expected_a_public_size; |
146 | unsigned short expected_ss_size; | 148 | unsigned short expected_ss_size; |
149 | bool genkey; | ||
147 | }; | 150 | }; |
148 | 151 | ||
149 | static const char zeroed_string[48]; | 152 | static const char zeroed_string[48]; |
@@ -840,6 +843,50 @@ static const struct kpp_testvec ecdh_tv_template[] = { | |||
840 | .b_public_size = 64, | 843 | .b_public_size = 64, |
841 | .expected_a_public_size = 64, | 844 | .expected_a_public_size = 64, |
842 | .expected_ss_size = 32 | 845 | .expected_ss_size = 32 |
846 | }, { | ||
847 | .secret = | ||
848 | #ifdef __LITTLE_ENDIAN | ||
849 | "\x02\x00" /* type */ | ||
850 | "\x08\x00" /* len */ | ||
851 | "\x02\x00" /* curve_id */ | ||
852 | "\x00\x00", /* key_size */ | ||
853 | #else | ||
854 | "\x00\x02" /* type */ | ||
855 | "\x00\x08" /* len */ | ||
856 | "\x00\x02" /* curve_id */ | ||
857 | "\x00\x00", /* key_size */ | ||
858 | #endif | ||
859 | .b_secret = | ||
860 | #ifdef __LITTLE_ENDIAN | ||
861 | "\x02\x00" /* type */ | ||
862 | "\x28\x00" /* len */ | ||
863 | "\x02\x00" /* curve_id */ | ||
864 | "\x20\x00" /* key_size */ | ||
865 | #else | ||
866 | "\x00\x02" /* type */ | ||
867 | "\x00\x28" /* len */ | ||
868 | "\x00\x02" /* curve_id */ | ||
869 | "\x00\x20" /* key_size */ | ||
870 | #endif | ||
871 | "\x24\xd1\x21\xeb\xe5\xcf\x2d\x83" | ||
872 | "\xf6\x62\x1b\x6e\x43\x84\x3a\xa3" | ||
873 | "\x8b\xe0\x86\xc3\x20\x19\xda\x92" | ||
874 | "\x50\x53\x03\xe1\xc0\xea\xb8\x82", | ||
875 | .b_public = | ||
876 | "\x1a\x7f\xeb\x52\x00\xbd\x3c\x31" | ||
877 | "\x7d\xb6\x70\xc1\x86\xa6\xc7\xc4" | ||
878 | "\x3b\xc5\x5f\x6c\x6f\x58\x3c\xf5" | ||
879 | "\xb6\x63\x82\x77\x33\x24\xa1\x5f" | ||
880 | "\x6a\xca\x43\x6f\xf7\x7e\xff\x02" | ||
881 | "\x37\x08\xcc\x40\x5e\x7a\xfd\x6a" | ||
882 | "\x6a\x02\x6e\x41\x87\x68\x38\x77" | ||
883 | "\xfa\xa9\x44\x43\x2d\xef\x09\xdf", | ||
884 | .secret_size = 8, | ||
885 | .b_secret_size = 40, | ||
886 | .b_public_size = 64, | ||
887 | .expected_a_public_size = 64, | ||
888 | .expected_ss_size = 32, | ||
889 | .genkey = true, | ||
843 | } | 890 | } |
844 | }; | 891 | }; |
845 | 892 | ||