New function mbedtls_ecp_keypair_calc_public

For when you calculate or import a private key, and then need to calculate
the public key.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine 2023-06-21 20:39:08 +02:00
parent 28240323d3
commit 7ea72026cd
4 changed files with 77 additions and 0 deletions

View file

@ -1365,6 +1365,23 @@ int mbedtls_ecp_check_pub_priv(
const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
/** \brief Calculate the public key from a private key in a key pair.
*
* \param key A keypair structure. It must have a private key set.
* If the public key is set, it will be overwritten.
* \param f_rng The RNG function. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c
* NULL if \p f_rng doesn't need a context.
*
* \return \c 0 on success. The key pair object can be used for
* operations that require the public key.
* \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
* error code on calculation failure.
*/
int mbedtls_ecp_keypair_calc_public(
mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
/** \brief Query the group that a key pair belongs to.
*
* \param key The key pair to query.

View file

@ -3374,6 +3374,14 @@ cleanup:
return ret;
}
int mbedtls_ecp_keypair_calc_public(mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
return mbedtls_ecp_mul(&key->grp, &key->Q, &key->d, &key->grp.G,
f_rng, p_rng);
}
#endif /* MBEDTLS_ECP_C */
mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id(

View file

@ -529,6 +529,24 @@ ECP check public-private #7 (wrong Qy)
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
mbedtls_ecp_check_pub_priv:MBEDTLS_ECP_DP_SECP256R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edfe":MBEDTLS_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edfe":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
ECP calculate public: secp256r1, good
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
ecp_calc_public:MBEDTLS_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":0:"0437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff"
ECP calculate public: secp256r1, private value out of range
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
ecp_calc_public:MBEDTLS_ECP_DP_SECP256R1:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":MBEDTLS_ERR_ECP_INVALID_KEY:""
# Alice's private key from rfc 7748, masked and adjusted for endianness
# because the test function wants the little-endian representation.
ECP calculate public: Curve25519, good
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
ecp_calc_public:MBEDTLS_ECP_DP_CURVE25519:"6a2cb91da5fb77b12a99c0eb872f4cdf4566b25172c1163c7da518730a6d0770":0:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
ECP calculate public: Curve25519, private value not masked
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
ecp_calc_public:MBEDTLS_ECP_DP_CURVE25519:"2a2cb91da5fb77b12a99c0eb872f4cdf4566b25172c1163c7da518730a6d0770":MBEDTLS_ERR_ECP_INVALID_KEY:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
ECP gen keypair [#1]
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
mbedtls_ecp_gen_keypair:MBEDTLS_ECP_DP_SECP192R1

View file

@ -988,6 +988,40 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
void ecp_calc_public(int grp_id, data_t *private,
int expected_ret, data_t *expected_public)
{
mbedtls_ecp_keypair key;
mbedtls_ecp_keypair_init(&key);
mbedtls_test_rnd_pseudo_info rnd_info;
memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0);
TEST_EQUAL(mbedtls_mpi_read_binary(&key.d, private->x, private->len), 0);
TEST_EQUAL(mbedtls_ecp_keypair_calc_public(&key,
&mbedtls_test_rnd_pseudo_rand, &rnd_info),
expected_ret);
if (expected_ret == 0) {
TEST_EQUAL(mbedtls_ecp_check_pub_priv(&key, &key,
&mbedtls_test_rnd_pseudo_rand, &rnd_info),
0);
unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
size_t length;
TEST_EQUAL(mbedtls_ecp_point_write_binary(&key.grp, &key.Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&length, buf, sizeof(buf)),
0);
ASSERT_COMPARE(expected_public->x, expected_public->len, buf, length);
}
exit:
mbedtls_ecp_keypair_free(&key);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
void mbedtls_ecp_gen_keypair(int id)
{