Read and write X25519 and X448 private keys
Signed-off-by: Jethro Beekman <jethro@fortanix.com> Co-authored-by: Gijs Kwakkel <gijs.kwakkel@fortanix.com> Signed-off-by: Gijs Kwakkel <gijs.kwakkel@fortanix.com>
This commit is contained in:
parent
e4072c00c8
commit
0167244be4
19 changed files with 515 additions and 94 deletions
|
@ -213,7 +213,8 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *c;
|
||||
size_t len = 0, par_len = 0, oid_len;
|
||||
int has_par = 1;
|
||||
size_t len = 0, par_len = 0, oid_len = 0;
|
||||
mbedtls_pk_type_t pk_type;
|
||||
const char *oid;
|
||||
|
||||
|
@ -243,7 +244,17 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
pk_type = mbedtls_pk_get_type(key);
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (pk_type == MBEDTLS_PK_ECKEY) {
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, mbedtls_pk_ec(*key)));
|
||||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*key);
|
||||
|
||||
ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec->grp.id, &oid, &oid_len);
|
||||
|
||||
if (ret == 0) {
|
||||
has_par = 0;
|
||||
} else if (ret == MBEDTLS_ERR_OID_NOT_FOUND) {
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec));
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
@ -253,6 +264,8 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
mbedtls_svc_key_id_t key_id;
|
||||
psa_ecc_family_t curve;
|
||||
size_t bits;
|
||||
size_t oid2_len = 0;
|
||||
const char *oid2;
|
||||
|
||||
key_id = *((mbedtls_svc_key_id_t *) key->pk_ctx);
|
||||
if (PSA_SUCCESS != psa_get_key_attributes(key_id, &attributes)) {
|
||||
|
@ -269,7 +282,7 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
}
|
||||
|
||||
ret = mbedtls_psa_get_ecc_oid_from_id(curve, bits,
|
||||
&oid, &oid_len);
|
||||
&oid2, &oid2_len);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
@ -277,8 +290,8 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
/* Write EC algorithm parameters; that's akin
|
||||
* to pk_write_ec_param() above. */
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_oid(&c, buf,
|
||||
oid,
|
||||
oid_len));
|
||||
oid2,
|
||||
oid2_len));
|
||||
|
||||
/* The rest of the function works as for legacy EC contexts. */
|
||||
pk_type = MBEDTLS_PK_ECKEY;
|
||||
|
@ -291,13 +304,15 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if ((ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid,
|
||||
&oid_len)) != 0) {
|
||||
return ret;
|
||||
if (oid_len == 0) {
|
||||
if ((ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid,
|
||||
&oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier(&c, buf, oid, oid_len,
|
||||
par_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier_ext(&c, buf, oid, oid_len,
|
||||
par_len, has_par));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
|
@ -306,6 +321,55 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
return (int) len;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
/*
|
||||
* RFC8410
|
||||
*
|
||||
* OneAsymmetricKey ::= SEQUENCE {
|
||||
* version Version,
|
||||
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
|
||||
* privateKey PrivateKey,
|
||||
* attributes [0] IMPLICIT Attributes OPTIONAL,
|
||||
* ...,
|
||||
* [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* CurvePrivateKey ::= OCTET STRING
|
||||
*/
|
||||
static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf,
|
||||
mbedtls_ecp_keypair *ec)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
size_t oid_len = 0;
|
||||
const char *oid;
|
||||
|
||||
/* privateKey */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, ec));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING));
|
||||
|
||||
/* privateKeyAlgorithm */
|
||||
if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec->grp.id, &oid, &oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_algorithm_identifier_ext(p, buf, oid, oid_len, 0, 0));
|
||||
|
||||
/* version */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
@ -409,6 +473,12 @@ end_of_export:
|
|||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*key);
|
||||
size_t pub_len = 0, par_len = 0;
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
if (mbedtls_pk_is_rfc8410_curve(ec->grp.id)) {
|
||||
return pk_write_ec_rfc8410_der(&c, buf, ec);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RFC 5915, or SEC1 Appendix C.4
|
||||
*
|
||||
|
@ -472,6 +542,8 @@ end_of_export:
|
|||
#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
|
||||
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
|
||||
#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
|
||||
#define PEM_BEGIN_PRIVATE_KEY_PKCS8 "-----BEGIN PRIVATE KEY-----\n"
|
||||
#define PEM_END_PRIVATE_KEY_PKCS8 "-----END PRIVATE KEY-----\n"
|
||||
|
||||
#define PUB_DER_MAX_BYTES \
|
||||
(MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES > MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ? \
|
||||
|
@ -519,8 +591,16 @@ int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf,
|
|||
#endif
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_EC;
|
||||
end = PEM_END_PRIVATE_KEY_EC;
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
if (mbedtls_pk_is_rfc8410_curve(mbedtls_pk_ec(*key)->grp.id)) {
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_PKCS8;
|
||||
end = PEM_END_PRIVATE_KEY_PKCS8;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_EC;
|
||||
end = PEM_END_PRIVATE_KEY_EC;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue