struct kpp_request *req;
void *input_buf = NULL;
void *output_buf = NULL;
+ void *a_public = NULL;
+ void *a_ss = NULL;
+ void *shared_secret = NULL;
struct tcrypt_result result;
unsigned int out_len_max;
int err = -ENOMEM;
kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
tcrypt_complete, &result);
- /* Compute public key */
+ /* Compute party A's public key */
err = wait_async_op(&result, crypto_kpp_generate_public_key(req));
if (err) {
- pr_err("alg: %s: generate public key test failed. err %d\n",
+ pr_err("alg: %s: Party A: generate public key test failed. err %d\n",
alg, err);
goto free_output;
}
- /* Verify calculated public key */
- if (memcmp(vec->expected_a_public, sg_virt(req->dst),
- vec->expected_a_public_size)) {
- pr_err("alg: %s: generate public key test failed. Invalid output\n",
- alg);
- err = -EINVAL;
- goto free_output;
+
+ if (vec->genkey) {
+ /* Save party A's public key */
+ a_public = kzalloc(out_len_max, GFP_KERNEL);
+ if (!a_public) {
+ err = -ENOMEM;
+ goto free_output;
+ }
+ memcpy(a_public, sg_virt(req->dst), out_len_max);
+ } else {
+ /* Verify calculated public key */
+ if (memcmp(vec->expected_a_public, sg_virt(req->dst),
+ vec->expected_a_public_size)) {
+ pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n",
+ alg);
+ err = -EINVAL;
+ goto free_output;
+ }
}
/* Calculate shared secret key by using counter part (b) public key. */
tcrypt_complete, &result);
err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req));
if (err) {
- pr_err("alg: %s: compute shard secret test failed. err %d\n",
+ pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n",
alg, err);
goto free_all;
}
+
+ if (vec->genkey) {
+ /* Save the shared secret obtained by party A */
+ a_ss = kzalloc(vec->expected_ss_size, GFP_KERNEL);
+ if (!a_ss) {
+ err = -ENOMEM;
+ goto free_all;
+ }
+ memcpy(a_ss, sg_virt(req->dst), vec->expected_ss_size);
+
+ /*
+ * Calculate party B's shared secret by using party A's
+ * public key.
+ */
+ err = crypto_kpp_set_secret(tfm, vec->b_secret,
+ vec->b_secret_size);
+ if (err < 0)
+ goto free_all;
+
+ sg_init_one(&src, a_public, vec->expected_a_public_size);
+ sg_init_one(&dst, output_buf, out_len_max);
+ kpp_request_set_input(req, &src, vec->expected_a_public_size);
+ kpp_request_set_output(req, &dst, out_len_max);
+ kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+ err = wait_async_op(&result,
+ crypto_kpp_compute_shared_secret(req));
+ if (err) {
+ pr_err("alg: %s: Party B: compute shared secret failed. err %d\n",
+ alg, err);
+ goto free_all;
+ }
+
+ shared_secret = a_ss;
+ } else {
+ shared_secret = (void *)vec->expected_ss;
+ }
+
/*
* verify shared secret from which the user will derive
* secret key by executing whatever hash it has chosen
*/
- if (memcmp(vec->expected_ss, sg_virt(req->dst),
+ if (memcmp(shared_secret, sg_virt(req->dst),
vec->expected_ss_size)) {
pr_err("alg: %s: compute shared secret test failed. Invalid output\n",
alg);
}
free_all:
+ kfree(a_ss);
kfree(input_buf);
free_output:
+ kfree(a_public);
kfree(output_buf);
free_req:
kpp_request_free(req);
struct kpp_testvec {
const unsigned char *secret;
+ const unsigned char *b_secret;
const unsigned char *b_public;
const unsigned char *expected_a_public;
const unsigned char *expected_ss;
unsigned short secret_size;
+ unsigned short b_secret_size;
unsigned short b_public_size;
unsigned short expected_a_public_size;
unsigned short expected_ss_size;
+ bool genkey;
};
static const char zeroed_string[48];
.b_public_size = 64,
.expected_a_public_size = 64,
.expected_ss_size = 32
+ }, {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x02\x00" /* type */
+ "\x08\x00" /* len */
+ "\x02\x00" /* curve_id */
+ "\x00\x00", /* key_size */
+#else
+ "\x00\x02" /* type */
+ "\x00\x08" /* len */
+ "\x00\x02" /* curve_id */
+ "\x00\x00", /* key_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x02\x00" /* type */
+ "\x28\x00" /* len */
+ "\x02\x00" /* curve_id */
+ "\x20\x00" /* key_size */
+#else
+ "\x00\x02" /* type */
+ "\x00\x28" /* len */
+ "\x00\x02" /* curve_id */
+ "\x00\x20" /* key_size */
+#endif
+ "\x24\xd1\x21\xeb\xe5\xcf\x2d\x83"
+ "\xf6\x62\x1b\x6e\x43\x84\x3a\xa3"
+ "\x8b\xe0\x86\xc3\x20\x19\xda\x92"
+ "\x50\x53\x03\xe1\xc0\xea\xb8\x82",
+ .b_public =
+ "\x1a\x7f\xeb\x52\x00\xbd\x3c\x31"
+ "\x7d\xb6\x70\xc1\x86\xa6\xc7\xc4"
+ "\x3b\xc5\x5f\x6c\x6f\x58\x3c\xf5"
+ "\xb6\x63\x82\x77\x33\x24\xa1\x5f"
+ "\x6a\xca\x43\x6f\xf7\x7e\xff\x02"
+ "\x37\x08\xcc\x40\x5e\x7a\xfd\x6a"
+ "\x6a\x02\x6e\x41\x87\x68\x38\x77"
+ "\xfa\xa9\x44\x43\x2d\xef\x09\xdf",
+ .secret_size = 8,
+ .b_secret_size = 40,
+ .b_public_size = 64,
+ .expected_a_public_size = 64,
+ .expected_ss_size = 32,
+ .genkey = true,
}
};