New function mbedtls_ecp_set_public_key
Set the public key in a key pair. This complements mbedtls_ecp_read_key and the functions can be used in either order. Document the need to call check functions separately. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
091a85a762
commit
28240323d3
4 changed files with 196 additions and 0 deletions
|
@ -1259,6 +1259,38 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t),
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
void *p_rng);
|
void *p_rng);
|
||||||
|
|
||||||
|
/** \brief Set the public key in a key pair object.
|
||||||
|
*
|
||||||
|
* \note This function does not check that the point actually
|
||||||
|
* belongs to the given group. Call mbedtls_ecp_check_pubkey()
|
||||||
|
* on \p Q before calling this function to check that.
|
||||||
|
*
|
||||||
|
* \note This function does not check that the public key matches
|
||||||
|
* the private key that is already in \p key, if any.
|
||||||
|
* To check the consistency of the resulting key pair object,
|
||||||
|
* call mbedtls_ecp_check_pub_priv() after setting both
|
||||||
|
* the public key and the private key.
|
||||||
|
*
|
||||||
|
* \param grp_id The ECP group identifier.
|
||||||
|
* \param key The key pair object. It must be initialized.
|
||||||
|
* If its group has already been set, it must match \p grp_id.
|
||||||
|
* If its group has not been set, it will be set to \p grp_id.
|
||||||
|
* If the public key has already been set, it is overwritten.
|
||||||
|
* \param Q The public key to copy. This must be a point on the
|
||||||
|
* curve indicated by \p grp_id.
|
||||||
|
*
|
||||||
|
* \return \c 0 on success.
|
||||||
|
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p key does not
|
||||||
|
* match \p grp_id.
|
||||||
|
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
|
||||||
|
* the group is not implemented.
|
||||||
|
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
|
||||||
|
* \return Another negative error code on other kinds of failure.
|
||||||
|
*/
|
||||||
|
int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
|
||||||
|
mbedtls_ecp_keypair *key,
|
||||||
|
const mbedtls_ecp_point *Q);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This function reads an elliptic curve private key.
|
* \brief This function reads an elliptic curve private key.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3198,6 +3198,25 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ECP_C */
|
#endif /* MBEDTLS_ECP_C */
|
||||||
|
|
||||||
|
int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
|
||||||
|
mbedtls_ecp_keypair *key,
|
||||||
|
const mbedtls_ecp_point *Q)
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
if (key->grp.id == MBEDTLS_ECP_DP_NONE) {
|
||||||
|
/* Group not set yet */
|
||||||
|
if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else if (key->grp.id != grp_id) {
|
||||||
|
/* Group mismatch */
|
||||||
|
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||||
|
}
|
||||||
|
return mbedtls_ecp_copy(&key->Q, Q);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define ECP_CURVE25519_KEY_SIZE 32
|
#define ECP_CURVE25519_KEY_SIZE 32
|
||||||
#define ECP_CURVE448_KEY_SIZE 56
|
#define ECP_CURVE448_KEY_SIZE 56
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -581,6 +581,48 @@ genkey_mx_known_answer:447:"ffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
ECP generate Montgomery key: Curve448, not enough entropy
|
ECP generate Montgomery key: Curve448, not enough entropy
|
||||||
genkey_mx_known_answer:447:"4f0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536":""
|
genkey_mx_known_answer:447:"4f0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536":""
|
||||||
|
|
||||||
|
ECP set public key: invalid group (0)
|
||||||
|
ecp_set_public_key_group_check:MBEDTLS_ECP_DP_NONE:MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
|
||||||
|
|
||||||
|
ECP set public key: valid group (secp256r1)
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
|
ecp_set_public_key_group_check:MBEDTLS_ECP_DP_SECP256R1:0
|
||||||
|
|
||||||
|
ECP set public key: group not supported (secp256r1)
|
||||||
|
depends_on:!MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
|
ecp_set_public_key_group_check:MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
|
||||||
|
|
||||||
|
ECP set public key: bad group (not in enum)
|
||||||
|
ecp_set_public_key_group_check:MBEDTLS_ECP_DP_MAX:MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
|
||||||
|
|
||||||
|
ECP set public key: good, secp256r1
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
|
ecp_set_public_key_good:MBEDTLS_ECP_DP_SECP256R1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579"
|
||||||
|
|
||||||
|
ECP set public key: good, Curve25519
|
||||||
|
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||||
|
ecp_set_public_key_good:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
|
||||||
|
|
||||||
|
ECP set public key after private: good, secp256r1
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
|
ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP256R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP256R1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579"
|
||||||
|
|
||||||
|
ECP set public key after private: good, Curve25519
|
||||||
|
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||||
|
ecp_set_public_key_after_private:MBEDTLS_ECP_DP_CURVE25519:"70076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c6a":MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
|
||||||
|
|
||||||
|
ECP set public key after private: secp256r1 then secp256k1
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
||||||
|
ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP256R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP256K1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579"
|
||||||
|
|
||||||
|
ECP set public key after private: secp256r1 then secp384r1
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||||
|
ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP256R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP384R1:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||||
|
|
||||||
|
ECP set public key after private: secp384r1 then secp256r1
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
|
ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP384R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP256R1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579"
|
||||||
|
|
||||||
ECP read key #1 (short weierstrass, too small)
|
ECP read key #1 (short weierstrass, too small)
|
||||||
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||||
mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"00":MBEDTLS_ERR_ECP_INVALID_KEY:0
|
mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"00":MBEDTLS_ERR_ECP_INVALID_KEY:0
|
||||||
|
|
|
@ -1039,6 +1039,109 @@ exit:
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void ecp_set_public_key_group_check(int grp_id, int expected_ret)
|
||||||
|
{
|
||||||
|
mbedtls_ecp_keypair key;
|
||||||
|
mbedtls_ecp_keypair_init(&key);
|
||||||
|
mbedtls_ecp_point Q;
|
||||||
|
mbedtls_ecp_point_init(&Q);
|
||||||
|
|
||||||
|
TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q),
|
||||||
|
expected_ret);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_ecp_keypair_free(&key);
|
||||||
|
mbedtls_ecp_point_free(&Q);
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void ecp_set_public_key_good(int grp_id, data_t *public_data)
|
||||||
|
{
|
||||||
|
mbedtls_ecp_keypair key;
|
||||||
|
mbedtls_ecp_keypair_init(&key);
|
||||||
|
mbedtls_ecp_group grp;
|
||||||
|
mbedtls_ecp_group_init(&grp);
|
||||||
|
mbedtls_ecp_point Q;
|
||||||
|
mbedtls_ecp_point_init(&Q);
|
||||||
|
|
||||||
|
TEST_EQUAL(mbedtls_ecp_group_load(&grp, grp_id), 0);
|
||||||
|
TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &Q,
|
||||||
|
public_data->x, public_data->len),
|
||||||
|
0);
|
||||||
|
|
||||||
|
/* Freshly initialized key */
|
||||||
|
TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), 0);
|
||||||
|
TEST_EQUAL(key.grp.id, grp_id);
|
||||||
|
TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
|
/* Key with a public key already set to a different value */
|
||||||
|
TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.X, &key.Q.X, 1), 0);
|
||||||
|
TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.Y, &key.Q.Y, 1), 0);
|
||||||
|
TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.Z, &key.Q.Z, 1), 0);
|
||||||
|
TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), 0);
|
||||||
|
TEST_EQUAL(key.grp.id, grp_id);
|
||||||
|
TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_ecp_keypair_free(&key);
|
||||||
|
mbedtls_ecp_group_free(&grp);
|
||||||
|
mbedtls_ecp_point_free(&Q);
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void ecp_set_public_key_after_private(int private_grp_id, data_t *private_data,
|
||||||
|
int public_grp_id, data_t *public_data)
|
||||||
|
{
|
||||||
|
mbedtls_ecp_keypair key;
|
||||||
|
mbedtls_ecp_keypair_init(&key);
|
||||||
|
mbedtls_ecp_group grp;
|
||||||
|
mbedtls_ecp_group_init(&grp);
|
||||||
|
mbedtls_ecp_point Q;
|
||||||
|
mbedtls_ecp_point_init(&Q);
|
||||||
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
|
mbedtls_mpi d;
|
||||||
|
mbedtls_mpi_init(&d);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_EQUAL(mbedtls_ecp_group_load(&grp, public_grp_id), 0);
|
||||||
|
TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &Q,
|
||||||
|
public_data->x, public_data->len),
|
||||||
|
0);
|
||||||
|
TEST_EQUAL(mbedtls_ecp_read_key(private_grp_id, &key,
|
||||||
|
private_data->x, private_data->len),
|
||||||
|
0);
|
||||||
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
|
TEST_EQUAL(mbedtls_mpi_copy(&d, &key.d), 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ret = mbedtls_ecp_set_public_key(public_grp_id, &key, &Q);
|
||||||
|
|
||||||
|
if (private_grp_id == public_grp_id) {
|
||||||
|
TEST_EQUAL(ret, 0);
|
||||||
|
TEST_EQUAL(key.grp.id, public_grp_id);
|
||||||
|
TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0);
|
||||||
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
|
TEST_EQUAL(mbedtls_mpi_cmp_mpi(&d, &key.d), 0);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
TEST_EQUAL(ret, MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_ecp_keypair_free(&key);
|
||||||
|
mbedtls_ecp_group_free(&grp);
|
||||||
|
mbedtls_ecp_point_free(&Q);
|
||||||
|
#if defined(MBEDTLS_BIGNUM_C)
|
||||||
|
mbedtls_mpi_free(&d);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
/* BEGIN_CASE */
|
/* BEGIN_CASE */
|
||||||
void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
|
void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue