Merge pull request #8644 from gilles-peskine-arm/domain_parameters_document_size_hack
Document the domain_parameters_size==SIZE_MAX hack
diff --git a/library/alignment.h b/library/alignment.h
index 4aab8e0..9e1e044 100644
--- a/library/alignment.h
+++ b/library/alignment.h
@@ -180,6 +180,16 @@
#define MBEDTLS_BSWAP32 __rev
#endif
+/* Detect IAR built-in byteswap routine */
+#if defined(__IAR_SYSTEMS_ICC__)
+#if defined(__ARM_ACLE)
+#include <arm_acle.h>
+#define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x)))
+#define MBEDTLS_BSWAP32 __rev
+#define MBEDTLS_BSWAP64 __revll
+#endif
+#endif
+
/*
* Where compiler built-ins are not present, fall back to C code that the
* compiler may be able to detect and transform into the relevant bswap or
@@ -224,10 +234,25 @@
#endif /* !defined(MBEDTLS_BSWAP64) */
#if !defined(__BYTE_ORDER__)
+
+#if defined(__LITTLE_ENDIAN__)
+/* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */
+#define MBEDTLS_IS_BIG_ENDIAN 0
+#elif defined(__BIG_ENDIAN__)
+#define MBEDTLS_IS_BIG_ENDIAN 1
+#else
static const uint16_t mbedtls_byte_order_detector = { 0x100 };
#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
+#endif
+
#else
-#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__))
+
+#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)
+#define MBEDTLS_IS_BIG_ENDIAN 1
+#else
+#define MBEDTLS_IS_BIG_ENDIAN 0
+#endif
+
#endif /* !defined(__BYTE_ORDER__) */
/**
diff --git a/library/ccm.c b/library/ccm.c
index 6700dc7..6b137d7 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -91,7 +91,7 @@
}
#endif
- return 0;
+ return ret;
}
/*
diff --git a/library/pk_internal.h b/library/pk_internal.h
index 571b57e..81807f1 100644
--- a/library/pk_internal.h
+++ b/library/pk_internal.h
@@ -21,6 +21,20 @@
#include "psa/crypto.h"
#endif
+/* Headers/footers for PEM files */
+#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----"
+#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----"
+#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----"
+#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----"
+#define PEM_BEGIN_PUBLIC_KEY_RSA "-----BEGIN RSA PUBLIC KEY-----"
+#define PEM_END_PUBLIC_KEY_RSA "-----END RSA PUBLIC KEY-----"
+#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----"
+#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----"
+#define PEM_BEGIN_PRIVATE_KEY_PKCS8 "-----BEGIN PRIVATE KEY-----"
+#define PEM_END_PRIVATE_KEY_PKCS8 "-----END PRIVATE KEY-----"
+#define PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----BEGIN ENCRYPTED PRIVATE KEY-----"
+#define PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----END ENCRYPTED PRIVATE KEY-----"
+
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "psa_util_internal.h"
#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
@@ -71,7 +85,7 @@
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
-static inline mbedtls_ecp_group_id mbedtls_pk_get_group_id(const mbedtls_pk_context *pk)
+static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_context *pk)
{
mbedtls_ecp_group_id id;
@@ -105,6 +119,16 @@
#if defined(MBEDTLS_ECP_HAVE_CURVE25519) || defined(MBEDTLS_ECP_HAVE_CURVE448)
#define MBEDTLS_PK_HAVE_RFC8410_CURVES
#endif /* MBEDTLS_ECP_HAVE_CURVE25519 || MBEDTLS_ECP_DP_CURVE448 */
+
+#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \
+ ((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448))
+
+static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk)
+{
+ mbedtls_ecp_group_id id = mbedtls_pk_get_ec_group_id(pk);
+
+ return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id);
+}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
/* Helper for (deterministic) ECDSA */
diff --git a/library/pkparse.c b/library/pkparse.c
index 18498e5..c33b742 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -15,6 +15,7 @@
#include "mbedtls/platform_util.h"
#include "mbedtls/platform.h"
#include "mbedtls/error.h"
+#include "pk_internal.h"
#include <string.h>
@@ -29,7 +30,6 @@
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#include "mbedtls/ecp.h"
-#include "pk_internal.h"
#endif
/* Extended formats */
@@ -868,12 +868,6 @@
return 0;
}
-/* Helper for Montgomery curves */
-#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
-#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \
- ((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448))
-#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
-
/*
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
@@ -1539,8 +1533,7 @@
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
} else {
ret = mbedtls_pem_read_buffer(&pem,
- "-----BEGIN RSA PRIVATE KEY-----",
- "-----END RSA PRIVATE KEY-----",
+ PEM_BEGIN_PRIVATE_KEY_RSA, PEM_END_PRIVATE_KEY_RSA,
key, pwd, pwdlen, &len);
}
@@ -1569,8 +1562,8 @@
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
} else {
ret = mbedtls_pem_read_buffer(&pem,
- "-----BEGIN EC PRIVATE KEY-----",
- "-----END EC PRIVATE KEY-----",
+ PEM_BEGIN_PRIVATE_KEY_EC,
+ PEM_END_PRIVATE_KEY_EC,
key, pwd, pwdlen, &len);
}
if (ret == 0) {
@@ -1599,8 +1592,7 @@
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
} else {
ret = mbedtls_pem_read_buffer(&pem,
- "-----BEGIN PRIVATE KEY-----",
- "-----END PRIVATE KEY-----",
+ PEM_BEGIN_PRIVATE_KEY_PKCS8, PEM_END_PRIVATE_KEY_PKCS8,
key, NULL, 0, &len);
}
if (ret == 0) {
@@ -1621,8 +1613,8 @@
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
} else {
ret = mbedtls_pem_read_buffer(&pem,
- "-----BEGIN ENCRYPTED PRIVATE KEY-----",
- "-----END ENCRYPTED PRIVATE KEY-----",
+ PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8,
+ PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8,
key, NULL, 0, &len);
}
if (ret == 0) {
@@ -1748,8 +1740,7 @@
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
} else {
ret = mbedtls_pem_read_buffer(&pem,
- "-----BEGIN RSA PUBLIC KEY-----",
- "-----END RSA PUBLIC KEY-----",
+ PEM_BEGIN_PUBLIC_KEY_RSA, PEM_END_PUBLIC_KEY_RSA,
key, NULL, 0, &len);
}
@@ -1782,8 +1773,7 @@
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
} else {
ret = mbedtls_pem_read_buffer(&pem,
- "-----BEGIN PUBLIC KEY-----",
- "-----END PUBLIC KEY-----",
+ PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
key, NULL, 0, &len);
}
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 11c0204..1f0d399 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -18,9 +18,6 @@
#include <string.h>
-#if defined(MBEDTLS_RSA_C)
-#include "mbedtls/rsa.h"
-#endif
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/bignum.h"
#include "mbedtls/ecp.h"
@@ -32,9 +29,6 @@
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#include "pkwrite.h"
#endif
-#if defined(MBEDTLS_ECDSA_C)
-#include "mbedtls/ecdsa.h"
-#endif
#if defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
#endif
@@ -45,62 +39,22 @@
#endif
#include "mbedtls/platform.h"
-/* Helper for Montgomery curves */
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
-#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
-static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk)
-{
- mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk);
-
-#if defined(MBEDTLS_ECP_HAVE_CURVE25519)
- if (id == MBEDTLS_ECP_DP_CURVE25519) {
- return 1;
- }
+/* Helpers for properly sizing buffers aimed at holding public keys or
+ * key-pairs based on build symbols. */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH
+#elif defined(MBEDTLS_USE_PSA_CRYPTO)
+#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH
+#else
+#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_ECP_MAX_PT_LEN
+#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_ECP_MAX_BYTES
#endif
-#if defined(MBEDTLS_ECP_HAVE_CURVE448)
- if (id == MBEDTLS_ECP_DP_CURVE448) {
- return 1;
- }
-#endif
- return 0;
-}
-#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PEM_WRITE_C)
-/* It is assumed that the input key is opaque */
-static psa_ecc_family_t pk_get_opaque_ec_family(const mbedtls_pk_context *pk)
-{
- psa_ecc_family_t ec_family = 0;
- psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
-
- if (psa_get_key_attributes(pk->priv_id, &key_attrs) != PSA_SUCCESS) {
- return 0;
- }
- ec_family = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attrs));
- psa_reset_key_attributes(&key_attrs);
-
- return ec_family;
-}
-#endif /* MBETLS_USE_PSA_CRYPTO && MBEDTLS_PEM_WRITE_C */
-#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-/* It is assumed that the input key is opaque */
-static psa_key_type_t pk_get_opaque_key_type(const mbedtls_pk_context *pk)
-{
- psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_type_t opaque_key_type;
-
- if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
- return 0;
- }
- opaque_key_type = psa_get_key_type(&opaque_attrs);
- psa_reset_key_attributes(&opaque_attrs);
-
- return opaque_key_type;
-}
-#endif /* MBETLS_USE_PSA_CRYPTO */
-
+/******************************************************************************
+ * Internal functions for RSA keys.
+ ******************************************************************************/
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
@@ -145,425 +99,7 @@
return (int) len;
}
-#endif /* MBEDTLS_RSA_C */
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
-static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *pk)
-{
- size_t len = 0;
- uint8_t buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
-
- if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
- if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
- return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
- }
- } else {
- len = pk->pub_raw_len;
- memcpy(buf, pk->pub_raw, len);
- }
-
- if (*p < start || (size_t) (*p - start) < len) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
-
- *p -= len;
- memcpy(*p, buf, len);
-
- return (int) len;
-}
-#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
-static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *pk)
-{
- size_t len = 0;
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- uint8_t buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
-#else
- unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
- mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk);
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
- if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
- return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
- }
- *p -= len;
- memcpy(*p, buf, len);
- return (int) len;
- } else
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
- {
- if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
- MBEDTLS_ECP_PF_UNCOMPRESSED,
- &len, buf, sizeof(buf))) != 0) {
- return ret;
- }
- }
-
- if (*p < start || (size_t) (*p - start) < len) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
-
- *p -= len;
- memcpy(*p, buf, len);
-
- return (int) len;
-}
-#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
-
-/*
- * ECParameters ::= CHOICE {
- * namedCurve OBJECT IDENTIFIER
- * }
- */
-static int pk_write_ec_param(unsigned char **p, unsigned char *start,
- mbedtls_ecp_group_id grp_id)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len = 0;
- const char *oid;
- size_t oid_len;
-
- if ((ret = mbedtls_oid_get_oid_by_ec_grp(grp_id, &oid, &oid_len)) != 0) {
- return ret;
- }
-
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len));
-
- return (int) len;
-}
-
-/*
- * privateKey OCTET STRING -- always of length ceil(log2(n)/8)
- */
-#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
-static int pk_write_ec_private(unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *pk)
-{
- size_t byte_length;
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
- psa_status_t status;
-
- if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
- status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
- if (status != PSA_SUCCESS) {
- ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
- return ret;
- }
- } else {
- status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
- if (status != PSA_SUCCESS) {
- ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
- goto exit;
- }
- }
-
- ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
-exit:
- mbedtls_platform_zeroize(tmp, sizeof(tmp));
- return ret;
-}
-#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
-static int pk_write_ec_private(unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *pk)
-{
- size_t byte_length;
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
- psa_status_t status;
-#else
- unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
- status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
- if (status != PSA_SUCCESS) {
- ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
- return ret;
- }
- } else
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
- {
- mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
- byte_length = (ec->grp.pbits + 7) / 8;
-
- ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
- if (ret != 0) {
- goto exit;
- }
- }
- ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
-exit:
- mbedtls_platform_zeroize(tmp, sizeof(tmp));
- return ret;
-}
-#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *pk)
-{
- size_t buffer_size;
- size_t len = 0;
-
- if (*p < start) {
- return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
- }
-
- buffer_size = (size_t) (*p - start);
- if (psa_export_public_key(pk->priv_id, start, buffer_size,
- &len) != PSA_SUCCESS) {
- return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
- }
-
- *p -= len;
- memmove(*p, start, len);
-
- return (int) len;
-}
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *key)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len = 0;
-
-#if defined(MBEDTLS_RSA_C)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, key));
- } else
-#endif
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, key));
- } else
-#endif
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_opaque_pubkey(p, start, key));
- } else
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
- return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
-
- return (int) len;
-}
-
-int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- unsigned char *c;
- int has_par = 1;
- size_t len = 0, par_len = 0, oid_len = 0;
- mbedtls_pk_type_t pk_type;
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE;
-#endif
- const char *oid = NULL;
-
- if (size == 0) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
-
- c = buf + size;
-
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_pk_write_pubkey(&c, buf, key));
-
- if (c - buf < 1) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
-
- /*
- * SubjectPublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * subjectPublicKey BIT STRING }
- */
- *--c = 0;
- len += 1;
-
- 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_BIT_STRING));
-
- pk_type = mbedtls_pk_get_type(key);
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- if (pk_type == MBEDTLS_PK_ECKEY) {
- ec_grp_id = mbedtls_pk_get_group_id(key);
- }
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if (pk_type == MBEDTLS_PK_OPAQUE) {
- psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key);
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) {
- pk_type = MBEDTLS_PK_ECKEY;
- ec_grp_id = mbedtls_pk_get_group_id(key);
- } else
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
- if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) {
- /* The rest of the function works as for legacy RSA contexts. */
- pk_type = MBEDTLS_PK_RSA;
- }
- }
- /* `pk_type` will have been changed to non-opaque by here if this function can handle it */
- if (pk_type == MBEDTLS_PK_OPAQUE) {
- return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- if (pk_type == MBEDTLS_PK_ECKEY) {
- /* Some groups have their own AlgorithmIdentifier OID, others are handled
- * by mbedtls_oid_get_oid_by_pk_alg() below */
- ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len);
-
- if (ret == 0) {
- /* Currently, none of the supported algorithms that have their own
- * AlgorithmIdentifier OID have any parameters */
- has_par = 0;
- } else if (ret == MBEDTLS_ERR_OID_NOT_FOUND) {
- MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id));
- } else {
- return ret;
- }
- }
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-
- 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_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 |
- MBEDTLS_ASN1_SEQUENCE));
-
- return (int) len;
-}
-
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
-#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
-/*
- * RFC8410 section 7
- *
- * 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,
- const mbedtls_pk_context *pk)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len = 0;
- size_t oid_len = 0;
- const char *oid;
- mbedtls_ecp_group_id grp_id;
-
- /* privateKey */
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
- 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));
-
- grp_id = mbedtls_pk_get_group_id(pk);
- /* privateKeyAlgorithm */
- if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(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 */
-
-/*
- * RFC 5915, or SEC1 Appendix C.4
- *
- * ECPrivateKey ::= SEQUENCE {
- * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
- * privateKey OCTET STRING,
- * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
- * publicKey [1] BIT STRING OPTIONAL
- * }
- */
-static int pk_write_ec_der(unsigned char **p, unsigned char *buf,
- const mbedtls_pk_context *pk)
-{
- size_t len = 0;
- int ret;
- size_t pub_len = 0, par_len = 0;
- mbedtls_ecp_group_id grp_id;
-
- /* publicKey */
- MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk));
-
- if (*p - buf < 1) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
- (*p)--;
- **p = 0;
- pub_len += 1;
-
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING));
-
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 1));
- len += pub_len;
-
- /* parameters */
- grp_id = mbedtls_pk_get_group_id(pk);
- MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id));
- MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len));
- MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 0));
- len += par_len;
-
- /* privateKey */
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
-
- /* version */
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1));
-
- 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_ECC_KEYS */
-
-#if defined(MBEDTLS_RSA_C)
static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
const mbedtls_pk_context *pk)
{
@@ -673,18 +209,366 @@
}
#endif /* MBEDTLS_RSA_C */
-int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
-{
- unsigned char *c;
-#if defined(MBEDTLS_RSA_C)
- int is_rsa_opaque = 0;
-#endif /* MBEDTLS_RSA_C */
+/******************************************************************************
+ * Internal functions for EC keys.
+ ******************************************************************************/
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- int is_ec_opaque = 0;
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t len = 0;
+ uint8_t buf[PK_MAX_EC_PUBLIC_KEY_SIZE];
+
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ } else {
+ len = pk->pub_raw_len;
+ memcpy(buf, pk->pub_raw, len);
+ }
+
+ if (*p < start || (size_t) (*p - start) < len) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+
+ *p -= len;
+ memcpy(*p, buf, len);
+
+ return (int) len;
+}
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t len = 0;
+ unsigned char buf[PK_MAX_EC_PUBLIC_KEY_SIZE];
+ mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk);
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- psa_key_type_t opaque_key_type;
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ *p -= len;
+ memcpy(*p, buf, len);
+ return (int) len;
+ } else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
+ MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &len, buf, sizeof(buf))) != 0) {
+ return ret;
+ }
+ }
+
+ if (*p < start || (size_t) (*p - start) < len) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+
+ *p -= len;
+ memcpy(*p, buf, len);
+
+ return (int) len;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
+/*
+ * privateKey OCTET STRING -- always of length ceil(log2(n)/8)
+ */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+static int pk_write_ec_private(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t byte_length;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE];
+ psa_status_t status;
+
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
+ if (status != PSA_SUCCESS) {
+ ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
+ return ret;
+ }
+ } else {
+ status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
+ if (status != PSA_SUCCESS) {
+ ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
+ goto exit;
+ }
+ }
+
+ ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
+exit:
+ mbedtls_platform_zeroize(tmp, sizeof(tmp));
+ return ret;
+}
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+static int pk_write_ec_private(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t byte_length;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE];
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_status_t status;
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
+ if (status != PSA_SUCCESS) {
+ ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
+ return ret;
+ }
+ } else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
+ byte_length = (ec->grp.pbits + 7) / 8;
+
+ ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
+ if (ret != 0) {
+ goto exit;
+ }
+ }
+ ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
+exit:
+ mbedtls_platform_zeroize(tmp, sizeof(tmp));
+ return ret;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
+/*
+ * ECParameters ::= CHOICE {
+ * namedCurve OBJECT IDENTIFIER
+ * }
+ */
+static int pk_write_ec_param(unsigned char **p, unsigned char *start,
+ mbedtls_ecp_group_id grp_id)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+ const char *oid;
+ size_t oid_len;
+
+ if ((ret = mbedtls_oid_get_oid_by_ec_grp(grp_id, &oid, &oid_len)) != 0) {
+ return ret;
+ }
+
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len));
+
+ return (int) len;
+}
+
+#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
+/*
+ * RFC8410 section 7
+ *
+ * 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,
+ const mbedtls_pk_context *pk)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+ size_t oid_len = 0;
+ const char *oid;
+ mbedtls_ecp_group_id grp_id;
+
+ /* privateKey */
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
+ 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));
+
+ grp_id = mbedtls_pk_get_ec_group_id(pk);
+ /* privateKeyAlgorithm */
+ if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(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 */
+
+/*
+ * RFC 5915, or SEC1 Appendix C.4
+ *
+ * ECPrivateKey ::= SEQUENCE {
+ * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+ * privateKey OCTET STRING,
+ * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
+ * publicKey [1] BIT STRING OPTIONAL
+ * }
+ */
+static int pk_write_ec_der(unsigned char **p, unsigned char *buf,
+ const mbedtls_pk_context *pk)
+{
+ size_t len = 0;
+ int ret;
+ size_t pub_len = 0, par_len = 0;
+ mbedtls_ecp_group_id grp_id;
+
+ /* publicKey */
+ MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk));
+
+ if (*p - buf < 1) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+ (*p)--;
+ **p = 0;
+ pub_len += 1;
+
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING));
+
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+ MBEDTLS_ASN1_CONSTRUCTED | 1));
+ len += pub_len;
+
+ /* parameters */
+ grp_id = mbedtls_pk_get_ec_group_id(pk);
+ MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id));
+ MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len));
+ MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+ MBEDTLS_ASN1_CONSTRUCTED | 0));
+ len += par_len;
+
+ /* privateKey */
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
+
+ /* version */
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1));
+
+ 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_ECC_KEYS */
+
+/******************************************************************************
+ * Internal functions for Opaque keys.
+ ******************************************************************************/
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t buffer_size;
+ size_t len = 0;
+
+ if (*p < start) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+ buffer_size = (size_t) (*p - start);
+ if (psa_export_public_key(pk->priv_id, start, buffer_size,
+ &len) != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+ *p -= len;
+ memmove(*p, start, len);
+
+ return (int) len;
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+/******************************************************************************
+ * Generic helpers
+ ******************************************************************************/
+
+/* Extend the public mbedtls_pk_get_type() by getting key type also in case of
+ * opaque keys. */
+static mbedtls_pk_type_t pk_get_type_ext(const mbedtls_pk_context *pk)
+{
+ mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (pk_type == MBEDTLS_PK_OPAQUE) {
+ psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t opaque_key_type;
+
+ if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
+ return MBEDTLS_PK_NONE;
+ }
+ opaque_key_type = psa_get_key_type(&opaque_attrs);
+ psa_reset_key_attributes(&opaque_attrs);
+
+ if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) {
+ return MBEDTLS_PK_ECKEY;
+ } else if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) {
+ return MBEDTLS_PK_RSA;
+ } else {
+ return MBEDTLS_PK_NONE;
+ }
+ } else
+#endif
+ return pk_type;
+}
+
+/******************************************************************************
+ * Public functions for writing private/public DER keys.
+ ******************************************************************************/
+int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *key)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+
+#if defined(MBEDTLS_RSA_C)
+ if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, key));
+ } else
+#endif
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
+ if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, key));
+ } else
+#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_opaque_pubkey(p, start, key));
+ } else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
+
+ return (int) len;
+}
+
+int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *c;
+ int has_par = 1;
+ size_t len = 0, par_len = 0, oid_len = 0;
+ mbedtls_pk_type_t pk_type;
+ const char *oid = NULL;
if (size == 0) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
@@ -692,25 +576,75 @@
c = buf + size;
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
- opaque_key_type = pk_get_opaque_key_type(key);
-#if defined(MBEDTLS_RSA_C)
- is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type);
-#endif /* MBEDTLS_RSA_C */
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type);
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_pk_write_pubkey(&c, buf, key));
+
+ if (c - buf < 1) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ /*
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING }
+ */
+ *--c = 0;
+ len += 1;
+
+ 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_BIT_STRING));
+
+ pk_type = pk_get_type_ext(key);
+
+#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
+ if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) {
+ mbedtls_ecp_group_id ec_grp_id = mbedtls_pk_get_ec_group_id(key);
+ if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
+ ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len);
+ if (ret != 0) {
+ return ret;
+ }
+ has_par = 0;
+ } else {
+ MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id));
+ }
+ }
+#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
+
+ /* At this point oid_len is not null only for EC Montgomery keys. */
+ if (oid_len == 0) {
+ ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid, &oid_len);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ 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 |
+ MBEDTLS_ASN1_SEQUENCE));
+
+ return (int) len;
+}
+
+int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
+{
+ unsigned char *c;
+
+ if (size == 0) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+
+ c = buf + size;
#if defined(MBEDTLS_RSA_C)
- if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) {
+ if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) {
return pk_write_rsa_der(&c, buf, key);
} else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) {
+ if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) {
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
if (mbedtls_pk_is_rfc8410(key)) {
return pk_write_ec_rfc8410_der(&c, buf, key);
@@ -722,18 +656,11 @@
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
}
+/******************************************************************************
+ * Public functions for wrinting private/public PEM keys.
+ ******************************************************************************/
#if defined(MBEDTLS_PEM_WRITE_C)
-#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
-#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
-
-#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
-#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 ? \
MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES : MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES)
@@ -756,7 +683,7 @@
goto cleanup;
}
- if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
+ if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_PUBLIC_KEY "\n", PEM_END_PUBLIC_KEY "\n",
output_buf + PUB_DER_MAX_BYTES - ret,
ret, buf, size, &olen)) != 0) {
goto cleanup;
@@ -778,57 +705,25 @@
}
const char *begin, *end;
size_t olen = 0;
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- int is_ec_opaque = 0;
-#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
- int is_montgomery_opaque = 0;
-#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-#if defined(MBEDTLS_RSA_C)
- int is_rsa_opaque = 0;
-#endif
if ((ret = mbedtls_pk_write_key_der(key, output_buf, PRV_DER_MAX_BYTES)) < 0) {
goto cleanup;
}
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
- psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key);
-
#if defined(MBEDTLS_RSA_C)
- is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type);
-#endif
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type);
-#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
- if (pk_get_opaque_ec_family(key) == PSA_ECC_FAMILY_MONTGOMERY) {
- is_montgomery_opaque = 1;
- }
-#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_RSA_C)
- if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) {
- begin = PEM_BEGIN_PRIVATE_KEY_RSA;
- end = PEM_END_PRIVATE_KEY_RSA;
+ if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) {
+ begin = PEM_BEGIN_PRIVATE_KEY_RSA "\n";
+ end = PEM_END_PRIVATE_KEY_RSA "\n";
} else
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
- if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) {
-#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
- if (is_montgomery_opaque ||
- ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) &&
- (mbedtls_pk_is_rfc8410(key)))) {
- begin = PEM_BEGIN_PRIVATE_KEY_PKCS8;
- end = PEM_END_PRIVATE_KEY_PKCS8;
- } else
-#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
- {
- begin = PEM_BEGIN_PRIVATE_KEY_EC;
- end = PEM_END_PRIVATE_KEY_EC;
+ if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) {
+ if (mbedtls_pk_is_rfc8410(key)) {
+ begin = PEM_BEGIN_PRIVATE_KEY_PKCS8 "\n";
+ end = PEM_END_PRIVATE_KEY_PKCS8 "\n";
+ } else {
+ begin = PEM_BEGIN_PRIVATE_KEY_EC "\n";
+ end = PEM_END_PRIVATE_KEY_EC "\n";
}
} else
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4daf2e7..1536d04 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -7419,7 +7419,7 @@
/* and in the unlikely case the above assumption no longer holds
* we are making sure that pk_ec() here does not return a NULL
*/
- mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(pk);
+ mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
MBEDTLS_SSL_DEBUG_MSG(1, ("invalid group ID"));
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 08549a8..0c5af87 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -2012,7 +2012,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
uint16_t tls_id = 0;
psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
- mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(peer_pk);
+ mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(peer_pk);
if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 923b093..f905e65 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -664,7 +664,7 @@
uint16_t *curves_tls_id)
{
uint16_t *curr_tls_id = curves_tls_id;
- mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(pk);
+ mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk);
mbedtls_ecp_group_id curr_grp_id;
while (*curr_tls_id != 0) {
@@ -2678,7 +2678,7 @@
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
key = mbedtls_pk_ec_rw(*pk);
- grp_id = mbedtls_pk_get_group_id(pk);
+ grp_id = mbedtls_pk_get_ec_group_id(pk);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 1fe4448..4e7672e 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -222,7 +222,7 @@
if (pk_alg == MBEDTLS_PK_ECDSA ||
pk_alg == MBEDTLS_PK_ECKEY ||
pk_alg == MBEDTLS_PK_ECKEY_DH) {
- const mbedtls_ecp_group_id gid = mbedtls_pk_get_group_id(pk);
+ const mbedtls_ecp_group_id gid = mbedtls_pk_get_ec_group_id(pk);
if (gid == MBEDTLS_ECP_DP_NONE) {
return -1;