Merge pull request #8703 from valeriosetti/issue7765-guards-in-asn1

Conversion function between raw and DER ECDSA signatures (guards in ASN1)
This commit is contained in:
Manuel Pégourié-Gonnard 2024-02-08 08:45:30 +00:00 committed by GitHub
commit b7307630bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 596 additions and 169 deletions

3
ChangeLog.d/7765.txt Normal file
View file

@ -0,0 +1,3 @@
Features
* Add functions mbedtls_ecdsa_raw_to_der() and mbedtls_ecdsa_der_to_raw() to
convert ECDSA signatures between raw and DER (ASN.1) formats.

View file

@ -197,7 +197,8 @@ typedef struct mbedtls_asn1_named_data {
} }
mbedtls_asn1_named_data; mbedtls_asn1_named_data;
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) #if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/** /**
* \brief Get the length of an ASN.1 element. * \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length. * Updates the pointer to immediately behind the length.
@ -244,7 +245,7 @@ int mbedtls_asn1_get_len(unsigned char **p,
int mbedtls_asn1_get_tag(unsigned char **p, int mbedtls_asn1_get_tag(unsigned char **p,
const unsigned char *end, const unsigned char *end,
size_t *len, int tag); size_t *len, int tag);
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */ #endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C) #if defined(MBEDTLS_ASN1_PARSE_C)
/** /**

View file

@ -36,7 +36,8 @@
extern "C" { extern "C" {
#endif #endif
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) #if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/** /**
* \brief Write a length field in ASN.1 format. * \brief Write a length field in ASN.1 format.
* *
@ -65,7 +66,7 @@ int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start,
*/ */
int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start,
unsigned char tag); unsigned char tag);
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */ #endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA*/
#if defined(MBEDTLS_ASN1_WRITE_C) #if defined(MBEDTLS_ASN1_WRITE_C)
/** /**

View file

@ -391,6 +391,13 @@
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY #define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
#endif #endif
/* psa_util file features some ECDSA conversion functions, to convert between
* legacy's ASN.1 DER format and PSA's raw one. */
#if defined(MBEDTLS_ECDSA_C) || (defined(MBEDTLS_PSA_CRYPTO_C) && \
(defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)))
#define MBEDTLS_PSA_UTIL_HAVE_ECDSA
#endif
/* Some internal helpers to determine which keys are availble. */ /* Some internal helpers to determine which keys are availble. */
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \ #if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES)) (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))

View file

@ -16,6 +16,11 @@
#include "psa/crypto.h" #include "psa/crypto.h"
/* ASN1 defines used in the ECDSA conversion functions.
* Note: intentionally not adding MBEDTLS_ASN1_[PARSE|WRITE]_C guards here
* otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/
#include <mbedtls/asn1write.h>
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
/* Expose whatever RNG the PSA subsystem uses to applications using the /* Expose whatever RNG the PSA subsystem uses to applications using the
@ -175,8 +180,50 @@ static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa
{ {
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK); return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
} }
#endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/** Convert an ECDSA signature from raw format to DER ASN.1 format.
*
* \param bits Size of each coordinate in bits.
* \param raw Buffer that contains the signature in raw format.
* \param raw_len Length of \p raw in bytes. This must be
* PSA_BITS_TO_BYTES(bits) bytes.
* \param[out] der Buffer that will be filled with the converted DER
* output. It can overlap with raw buffer.
* \param der_size Size of \p der in bytes. It is enough if \p der_size
* is at least the size of the actual output. (The size
* of the output can vary depending on the presence of
* leading zeros in the data.) You can use
* #MBEDTLS_ECDSA_MAX_SIG_LEN(\p bits) to determine a
* size that is large enough for all signatures for a
* given value of \p bits.
* \param[out] der_len On success it contains the amount of valid data
* (in bytes) written to \p der. It's undefined
* in case of failure.
*/
int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
unsigned char *der, size_t der_size, size_t *der_len);
/** Convert an ECDSA signature from DER ASN.1 format to raw format.
*
* \param bits Size of each coordinate in bits.
* \param der Buffer that contains the signature in DER format.
* \param der_len Size of \p der in bytes.
* \param[out] raw Buffer that will be filled with the converted raw
* signature. It can overlap with der buffer.
* \param raw_size Size of \p raw in bytes. Must be at least
* 2 * PSA_BITS_TO_BYTES(bits) bytes.
* \param[out] raw_len On success it is updated with the amount of valid
* data (in bytes) written to \p raw. It's undefined
* in case of failure.
*/
int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
unsigned char *raw, size_t raw_size, size_t *raw_len);
#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
/**@}*/ /**@}*/
#endif /* MBEDTLS_PSA_CRYPTO_C */
#endif /* MBEDTLS_PSA_UTIL_H */ #endif /* MBEDTLS_PSA_UTIL_H */

View file

@ -7,7 +7,8 @@
#include "common.h" #include "common.h"
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) #if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1.h" #include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h" #include "mbedtls/platform_util.h"
@ -73,7 +74,7 @@ int mbedtls_asn1_get_tag(unsigned char **p,
return mbedtls_asn1_get_len(p, end, len); return mbedtls_asn1_get_len(p, end, len);
} }
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */ #endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C) #if defined(MBEDTLS_ASN1_PARSE_C)
int mbedtls_asn1_get_bool(unsigned char **p, int mbedtls_asn1_get_bool(unsigned char **p,

View file

@ -7,7 +7,8 @@
#include "common.h" #include "common.h"
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) #if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1write.h" #include "mbedtls/asn1write.h"
#include "mbedtls/error.h" #include "mbedtls/error.h"
@ -62,7 +63,7 @@ int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, unsign
return 1; return 1;
} }
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */ #endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_WRITE_C) #if defined(MBEDTLS_ASN1_WRITE_C)
static int mbedtls_asn1_write_len_and_tag(unsigned char **p, static int mbedtls_asn1_write_len_and_tag(unsigned char **p,

View file

@ -29,6 +29,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa_util_internal.h" #include "psa_util_internal.h"
#include "psa/crypto.h" #include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)
#include "pkwrite.h" #include "pkwrite.h"
@ -522,66 +523,6 @@ static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
* those integers and convert it to the fixed-length encoding expected by PSA.
*/
static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end,
unsigned char *to, size_t to_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t unpadded_len, padding_len;
if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len,
MBEDTLS_ASN1_INTEGER)) != 0) {
return ret;
}
while (unpadded_len > 0 && **from == 0x00) {
(*from)++;
unpadded_len--;
}
if (unpadded_len > to_len || unpadded_len == 0) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
padding_len = to_len - unpadded_len;
memset(to, 0x00, padding_len);
memcpy(to + padding_len, *from, unpadded_len);
(*from) += unpadded_len;
return 0;
}
/*
* Convert a signature from an ASN.1 sequence of two integers
* to a raw {r,s} buffer. Note: the provided sig buffer must be at least
* twice as big as int_size.
*/
static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
unsigned char *sig, size_t int_size)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t tmp_size;
if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return ret;
}
/* Extract r */
if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) {
return ret;
}
/* Extract s */
if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) {
return ret;
}
return 0;
}
/* Common helper for ECDSA verify using PSA functions. */ /* Common helper for ECDSA verify using PSA functions. */
static int ecdsa_verify_psa(unsigned char *key, size_t key_len, static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
psa_ecc_family_t curve, size_t curve_bits, psa_ecc_family_t curve, size_t curve_bits,
@ -593,6 +534,7 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY; psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits); size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
size_t converted_sig_len;
unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE]; unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
unsigned char *p; unsigned char *p;
psa_status_t status; psa_status_t status;
@ -617,11 +559,14 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
} }
p = (unsigned char *) sig; p = (unsigned char *) sig;
/* extract_ecdsa_sig's last parameter is the size ret = mbedtls_ecdsa_der_to_raw(curve_bits, p, sig_len, extracted_sig,
* of each integer to be parsed, so it's actually half sizeof(extracted_sig), &converted_sig_len);
* the size of the signature. */ if (ret != 0) {
if ((ret = extract_ecdsa_sig(&p, sig + sig_len, extracted_sig, goto cleanup;
signature_len/2)) != 0) { }
if (converted_sig_len != signature_len) {
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup; goto cleanup;
} }
@ -632,10 +577,6 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
goto cleanup; goto cleanup;
} }
if (p != sig + sig_len) {
ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
goto cleanup;
}
ret = 0; ret = 0;
cleanup: cleanup:
@ -737,90 +678,6 @@ static int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* Simultaneously convert and move raw MPI from the beginning of a buffer
* to an ASN.1 MPI at the end of the buffer.
* See also mbedtls_asn1_write_mpi().
*
* p: pointer to the end of the output buffer
* start: start of the output buffer, and also of the mpi to write at the end
* n_len: length of the mpi to read from start
*/
static int asn1_write_mpibuf(unsigned char **p, unsigned char *start,
size_t n_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if ((size_t) (*p - start) < n_len) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
len = n_len;
*p -= len;
memmove(*p, start, len);
/* ASN.1 DER encoding requires minimal length, so skip leading 0s.
* Neither r nor s should be 0, but as a failsafe measure, still detect
* that rather than overflowing the buffer in case of a PSA error. */
while (len > 0 && **p == 0x00) {
++(*p);
--len;
}
/* this is only reached if the signature was invalid */
if (len == 0) {
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
}
/* if the msb is 1, ASN.1 requires that we prepend a 0.
* Neither r nor s can be 0, so we can assume len > 0 at all times. */
if (**p & 0x80) {
if (*p - start < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
*--(*p) = 0x00;
len += 1;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
MBEDTLS_ASN1_INTEGER));
return (int) len;
}
/* Transcode signature from PSA format to ASN.1 sequence.
* See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
* MPIs, and in-place.
*
* [in/out] sig: the signature pre- and post-transcoding
* [in/out] sig_len: signature length pre- and post-transcoding
* [int] buf_len: the available size the in/out buffer
*/
static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
size_t buf_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
const size_t rs_len = *sig_len / 2;
unsigned char *p = sig + buf_len;
MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len));
MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
memmove(sig, p, len);
*sig_len = len;
return 0;
}
/* Common helper for ECDSA sign using PSA functions. /* Common helper for ECDSA sign using PSA functions.
* Instead of extracting key's properties in order to check which kind of ECDSA * Instead of extracting key's properties in order to check which kind of ECDSA
* signature it supports, we try both deterministic and non-deterministic. * signature it supports, we try both deterministic and non-deterministic.
@ -831,6 +688,15 @@ static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status; psa_status_t status;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
size_t key_bits = 0;
status = psa_get_key_attributes(key_id, &key_attr);
if (status != PSA_SUCCESS) {
return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
}
key_bits = psa_get_key_bits(&key_attr);
psa_reset_key_attributes(&key_attr);
status = psa_sign_hash(key_id, status = psa_sign_hash(key_id,
PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)), PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
@ -849,7 +715,7 @@ static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
} }
done: done:
ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size); ret = mbedtls_ecdsa_raw_to_der(key_bits, sig, *sig_len, sig, sig_size, sig_len);
return ret; return ret;
} }

View file

@ -8,14 +8,20 @@
#include "common.h" #include "common.h"
/* This is needed for MBEDTLS_ERR_XXX macros */
#include <mbedtls/error.h>
#if defined(MBEDTLS_ASN1_WRITE_C)
#include <mbedtls/asn1write.h>
#include <psa/crypto_sizes.h>
#endif
#include "psa_util_internal.h"
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
#include <psa/crypto.h> #include <psa/crypto.h>
#include "psa_util_internal.h"
/* The following includes are needed for MBEDTLS_ERR_XXX macros */
#include <mbedtls/error.h>
#if defined(MBEDTLS_MD_LIGHT) #if defined(MBEDTLS_MD_LIGHT)
#include <mbedtls/md.h> #include <mbedtls/md.h>
#endif #endif
@ -331,3 +337,239 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
#endif /* MBEDTLS_PSA_CRYPTO_C */ #endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Convert a single raw coordinate to DER ASN.1 format. The output der
* buffer is filled backward (i.e. starting from its end).
*
* \param raw_buf Buffer containing the raw coordinate to be
* converted.
* \param raw_len Length of raw_buf in bytes. This must be > 0.
* \param der_buf_start Pointer to the beginning of the buffer which
* will be filled with the DER converted data.
* \param der_buf_end End of the buffer used to store the DER output.
*
* \return On success, the amount of data (in bytes) written to
* the DER buffer.
* \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
* buffer is too small to contain all the converted data.
* \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
* coordinate is null (i.e. all zeros).
*
* \warning Raw and der buffer must not be overlapping.
*/
static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
unsigned char *der_buf_start,
unsigned char *der_buf_end)
{
unsigned char *p = der_buf_end;
int len;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* ASN.1 DER encoding requires minimal length, so skip leading 0s.
* Provided input MPIs should not be 0, but as a failsafe measure, still
* detect that and return error in case. */
while (*raw_buf == 0x00) {
++raw_buf;
--raw_len;
if (raw_len == 0) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
}
len = (int) raw_len;
/* Copy the raw coordinate to the end of der_buf. */
if ((p - der_buf_start) < len) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
p -= len;
memcpy(p, raw_buf, len);
/* If MSb is 1, ASN.1 requires that we prepend a 0. */
if (*p & 0x80) {
if ((p - der_buf_start) < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
--p;
*p = 0x00;
++len;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
return len;
}
int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
unsigned char *der, size_t der_size, size_t *der_len)
{
unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
size_t len = 0;
unsigned char *p = der + der_size;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if (raw_len != (2 * coordinate_len)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
/* Since raw and der buffers might overlap, dump r and s before starting
* the conversion. */
memcpy(r, raw, coordinate_len);
memcpy(s, raw + coordinate_len, coordinate_len);
/* der buffer will initially be written starting from its end so we pick s
* first and then r. */
ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
if (ret < 0) {
return ret;
}
p -= ret;
len += ret;
ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
if (ret < 0) {
return ret;
}
p -= ret;
len += ret;
/* Add ASN.1 header (len + tag). */
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
/* memmove the content of der buffer to its beginnig. */
memmove(der, p, len);
*der_len = len;
return 0;
}
/**
* \brief Convert a single integer from ASN.1 DER format to raw.
*
* \param der Buffer containing the DER integer value to be
* converted.
* \param der_len Length of the der buffer in bytes.
* \param raw Output buffer that will be filled with the
* converted data. This should be at least
* coordinate_size bytes and it must be zeroed before
* calling this function.
* \param coordinate_size Size (in bytes) of a single coordinate in raw
* format.
*
* \return On success, the amount of DER data parsed from the
* provided der buffer.
* \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
* is missing in the der buffer.
* \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
* is null (i.e. all zeros) or if the output raw buffer
* is too small to contain the converted raw value.
*
* \warning Der and raw buffers must not be overlapping.
*/
static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
unsigned char *raw, size_t coordinate_size)
{
unsigned char *p = der;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t unpadded_len, padding_len = 0;
/* Get the length of ASN.1 element (i.e. the integer we need to parse). */
ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
MBEDTLS_ASN1_INTEGER);
if (ret != 0) {
return ret;
}
/* It's invalid to have:
* - unpadded_len == 0.
* - MSb set without a leading 0x00 (leading 0x00 is checked below). */
if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
/* Skip possible leading zero */
if (*p == 0x00) {
p++;
unpadded_len--;
/* It is not allowed to have more than 1 leading zero.
* Ignore the case in which unpadded_len = 0 because that's a 0 encoded
* in ASN.1 format (i.e. 020100). */
if ((unpadded_len > 0) && (*p == 0x00)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
}
if (unpadded_len > coordinate_size) {
/* Parsed number is longer than the maximum expected value. */
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
padding_len = coordinate_size - unpadded_len;
/* raw buffer was already zeroed by the calling function so zero-padding
* operation is skipped here. */
memcpy(raw + padding_len, p, unpadded_len);
p += unpadded_len;
return (int) (p - der);
}
int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
unsigned char *raw, size_t raw_size, size_t *raw_len)
{
unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
unsigned char *p = (unsigned char *) der;
size_t data_len;
size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
int ret;
/* The output raw buffer should be at least twice the size of a raw
* coordinate in order to store r and s. */
if (raw_size < coordinate_size * 2) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
/* Check that the provided input DER buffer has the right header. */
ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
if (ret != 0) {
return ret;
}
memset(raw_tmp, 0, 2 * coordinate_size);
/* Extract r */
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
if (ret < 0) {
return ret;
}
p += ret;
data_len -= ret;
/* Extract s */
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
coordinate_size);
if (ret < 0) {
return ret;
}
p += ret;
data_len -= ret;
/* Check that we consumed all the input der data. */
if ((size_t) (p - der) != der_len) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
memcpy(raw, raw_tmp, 2 * coordinate_size);
*raw_len = 2 * coordinate_size;
return 0;
}
#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */

View file

@ -1079,8 +1079,8 @@ component_check_test_dependencies () {
echo "!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH" >> $expected echo "!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH" >> $expected
# No PSA equivalent - used to skip decryption tests in PSA-ECB, CBC/XTS/NIST_KW/DES # No PSA equivalent - used to skip decryption tests in PSA-ECB, CBC/XTS/NIST_KW/DES
echo "!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT" >> $expected echo "!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT" >> $expected
# This is used by import_rsa_made_up() in test_suite_psa_crypto in order # MBEDTLS_ASN1_WRITE_C is used by import_rsa_made_up() in test_suite_psa_crypto
# to build a fake RSA key of the wanted size based on # in order to build a fake RSA key of the wanted size based on
# PSA_VENDOR_RSA_MAX_KEY_BITS. The legacy module is only used by # PSA_VENDOR_RSA_MAX_KEY_BITS. The legacy module is only used by
# the test code and that's probably the most convenient way of achieving # the test code and that's probably the most convenient way of achieving
# the test's goal. # the test's goal.

View file

@ -0,0 +1,167 @@
ECDSA Raw -> DER, 256bit, Success
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":0
ECDSA Raw -> DER, 256bit, DER buffer too small
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"304402201111111111111111111111111111111111111111111111111111111111111111022022222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ECDSA Raw -> DER, 256bit, Null r
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA Raw -> DER, 256bit, Null s
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA Raw -> DER, 256bit, r with MSb set
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"91111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"3045022100911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":0
ECDSA Raw -> DER, 256bit, s with MSb set
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"1111111111111111111111111111111111111111111111111111111111111111A222222222222222222222222222222222222222222222222222222222222222":"304502201111111111111111111111111111111111111111111111111111111111111111022100A222222222222222222222222222222222222222222222222222222222222222":0
ECDSA Raw -> DER, 256bit, both r and s with MSb set
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"A111111111111111111111111111111111111111111111111111111111111111A222222222222222222222222222222222222222222222222222222222222222":"3046022100A111111111111111111111111111111111111111111111111111111111111111022100A222222222222222222222222222222222222222222222222222222222222222":0
ECDSA Raw -> DER, 256bit, r and s only 1 byte of data
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"00000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000022":"3006020111020122":0
ECDSA Raw -> DER, 256bit, r and s only 1 byte of data with MSb set
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000A2":"300802020091020200A2":0
ECDSA Raw -> DER, 256bit, Invalid raw signature (r 1 byte shorter)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA Raw -> DER, 256bit, Invalid raw signature (r and s 1 byte shorter)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"1111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA Raw -> DER, 256bit, Invalid raw signature (r 1 byte longer)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"1111111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA Raw -> DER, 256bit, Invalid raw signature (r and s 1 byte longer)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der:256:"111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Success
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":0
ECDSA DER -> Raw, 256bit, Raw buffer too small
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ECDSA DER -> Raw, 256bit, Wrong sequence tag
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"40440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
ECDSA DER -> Raw, 256bit, Invalid sequence length
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30ff0220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_LENGTH
ECDSA DER -> Raw, 256bit, Wrong integer tag
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440120111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
ECDSA DER -> Raw, 256bit, Wrong r integer length (1 byte smaller than the actual size)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440219111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
ECDSA DER -> Raw, 256bit, Wrong r integer length (1 byte larger than the actual size)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440221111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Wrong s integer length (1 byte smaller than the actual size)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102192222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
ECDSA DER -> Raw, 256bit, Wrong s integer length (1 byte larger than the actual size)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102212222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_OUT_OF_DATA
ECDSA DER -> Raw, 256bit, r size 1 byte larger than allowed for output raw coordinate
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"3045022111111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, r with MSb set
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"3045022100911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"91111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":0
ECDSA DER -> Raw, 256bit, Invalid r all zeros
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440220000000000000000000000000000000000000000000000000000000000000000002202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Invalid s all zeros
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102200000000000000000000000000000000000000000000000000000000000000000":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Valid r only 1 zero byte
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"302502010002202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":0
ECDSA DER -> Raw, 256bit, Valid s only 1 zero byte
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"302502201111111111111111111111111111111111111111111111111111111111111111020100":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":0
ECDSA DER -> Raw, 256bit, Invalid 0-length r
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"3024020002202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Invalid 0-length s
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"3024022011111111111111111111111111111111111111111111111111111111111111110200":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Invalid r 2 leading zeros
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"3027020300000102202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Invalid s 2 leading zeros
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"3027022011111111111111111111111111111111111111111111111111111111111111110203000001":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":MBEDTLS_ERR_ASN1_INVALID_DATA
ECDSA DER -> Raw, 256bit, Invalid r: MSb set without leading zero
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_der_to_raw:256:"30440220911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
ECDSA Raw -> DER, 512bit, Success
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 512
ecdsa_raw_to_der:512:"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"308184024011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111024022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
ECDSA DER -> Raw, 512bit, Success
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 512
ecdsa_der_to_raw:512:"308184024011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111024022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
ECDSA Raw -> DER, 521bit, Success
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 521
ecdsa_raw_to_der:521:"011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"30818802420111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110242012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
ECDSA DER -> Raw, 521bit, Success
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 521
ecdsa_der_to_raw:521:"30818802420111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110242012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
ECDSA Raw -> DER, 256bit, Incremental DER buffer sizes
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der_incremental:256:"91111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"3045022100911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222"
ECDSA Raw -> DER, 512bit, Incremental DER buffer sizes
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 512
ecdsa_raw_to_der_incremental:512:"9111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"30818502410091111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111024022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
ECDSA Raw -> DER, 521bit, Incremental DER buffer sizes
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 521
ecdsa_raw_to_der_incremental:521:"011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"30818802420111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110242012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
ECDSA Raw -> DER, 256bit, DER buffer of minimal length (1 byte per integer)
depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
ecdsa_raw_to_der_incremental:256:"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002":"3006020101020102"

View file

@ -0,0 +1,91 @@
/* BEGIN_HEADER */
#include <test/helpers.h>
#include <mbedtls/psa_util.h>
/* END_HEADER */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_UTIL_HAVE_ECDSA */
void ecdsa_raw_to_der(int key_bits, data_t *input, data_t *exp_result, int exp_ret)
{
unsigned char *tmp_buf = NULL;
size_t tmp_buf_len = exp_result->len;
size_t ret_len;
TEST_CALLOC(tmp_buf, tmp_buf_len);
TEST_EQUAL(mbedtls_ecdsa_raw_to_der(key_bits, input->x, input->len,
tmp_buf, tmp_buf_len, &ret_len), exp_ret);
if (exp_ret == 0) {
ASSERT_COMPARE(exp_result->x, exp_result->len, tmp_buf, ret_len);
}
exit:
mbedtls_free(tmp_buf);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_UTIL_HAVE_ECDSA */
void ecdsa_raw_to_der_incremental(int key_bits, data_t *input, data_t *exp_result)
{
unsigned char *tmp_buf = NULL;
size_t ret_len;
size_t i;
/* Test with an output buffer smaller than required (expexted to fail). */
for (i = 1; i < exp_result->len; i++) {
TEST_CALLOC(tmp_buf, i);
TEST_ASSERT(mbedtls_ecdsa_raw_to_der(key_bits, input->x, input->len,
tmp_buf, i, &ret_len) != 0);
mbedtls_free(tmp_buf);
tmp_buf = NULL;
}
/* Test with an output buffer larger/equal than required (expexted to
* succeed). */
for (i = exp_result->len; i < (2 * exp_result->len); i++) {
TEST_CALLOC(tmp_buf, i);
TEST_ASSERT(mbedtls_ecdsa_raw_to_der(key_bits, input->x, input->len,
tmp_buf, i, &ret_len) == 0);
mbedtls_free(tmp_buf);
tmp_buf = NULL;
}
exit:
mbedtls_free(tmp_buf);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_UTIL_HAVE_ECDSA */
void ecdsa_der_to_raw(int key_bits, data_t *input, data_t *exp_result, int exp_ret)
{
unsigned char *in_buf = NULL;
size_t in_buf_len;
unsigned char *out_buf = NULL;
size_t out_buf_len = exp_result->len;
size_t ret_len;
TEST_CALLOC(out_buf, out_buf_len);
/* Verify that parsing of truncated input always fails. */
for (in_buf_len = 1; in_buf_len < input->len; in_buf_len++) {
/* We alloc a copy of input buffer with limited length so that sanitizers
* can detect overreads. */
TEST_CALLOC(in_buf, in_buf_len);
memcpy(in_buf, input->x, in_buf_len);
TEST_ASSERT(mbedtls_ecdsa_der_to_raw(key_bits, in_buf, in_buf_len,
out_buf, out_buf_len, &ret_len) != 0);
mbedtls_free(in_buf);
in_buf = NULL;
}
TEST_EQUAL(mbedtls_ecdsa_der_to_raw(key_bits, input->x, input->len,
out_buf, out_buf_len, &ret_len), exp_ret);
if (exp_ret == 0) {
ASSERT_COMPARE(exp_result->x, exp_result->len, out_buf, ret_len);
}
exit:
mbedtls_free(in_buf);
mbedtls_free(out_buf);
}
/* END_CASE */