New function mbedtls_ecp_write_public_key

Directly export the public part of a key pair without having to go through
intermediate objects (using mbedtls_ecp_point_write_binary would require a
group object and a point object).

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine 2023-06-22 22:27:32 +02:00
parent 6dd87384ae
commit 62e33bcc64
3 changed files with 59 additions and 9 deletions

View File

@ -1346,6 +1346,32 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen);
/**
* \brief This function exports an elliptic curve public key.
*
* \param key The public key.
* \param format The point format. This must be either
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
* (For groups without these formats, this parameter is
* ignored. But it still has to be either of the above
* values.)
* \param olen The address at which to store the length of
* the output in Bytes. This must not be \c NULL.
* \param buf The output buffer. This must be a writable buffer
* of length \p buflen Bytes.
* \param buflen The length of the output buffer \p buf in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
* is too small to hold the point.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
* or the export for the given group is not implemented.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_write_public_key(mbedtls_ecp_keypair *key,
int format, size_t *olen,
unsigned char *buf, size_t buflen);
/**
* \brief This function checks that the keypair objects
* \p pub and \p prv have the same group and the

View File

@ -3333,6 +3333,18 @@ cleanup:
return ret;
}
/*
* Write a public key.
*/
int mbedtls_ecp_write_public_key(mbedtls_ecp_keypair *key,
int format, size_t *olen,
unsigned char *buf, size_t buflen)
{
return mbedtls_ecp_point_write_binary(&key->grp, &key->Q,
format, olen, buf, buflen);
}
#if defined(MBEDTLS_ECP_C)
/*
* Check a public-private key pair

View File

@ -590,29 +590,41 @@ void ecp_write_binary(int id, char *x, char *y, char *z, int format,
{
mbedtls_ecp_group grp;
mbedtls_ecp_point P;
mbedtls_ecp_keypair key;
unsigned char buf[256];
size_t olen;
memset(buf, 0, sizeof(buf));
mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
mbedtls_ecp_keypair_init(&key);
TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
&olen, buf, blen) == ret);
TEST_EQUAL(mbedtls_test_read_mpi(&P.X, x), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&P.Y, y), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&P.Z, z), 0);
TEST_EQUAL(mbedtls_ecp_point_write_binary(&grp, &P, format,
&olen, buf, blen), ret);
if (ret == 0) {
TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
TEST_LE_U(olen, MBEDTLS_ECP_MAX_PT_LEN);
ASSERT_COMPARE(buf, olen,
out->x, out->len);
}
memset(buf, 0, blen);
TEST_EQUAL(mbedtls_ecp_set_public_key(grp.id, &key, &P), 0);
TEST_EQUAL(mbedtls_ecp_write_public_key(&key, format,
&olen, buf, blen), ret);
if (ret == 0) {
ASSERT_COMPARE(buf, olen,
out->x, out->len);
}
exit:
mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
mbedtls_ecp_keypair_free(&key);
}
/* END_CASE */