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:
commit
b7307630bb
12 changed files with 596 additions and 169 deletions
3
ChangeLog.d/7765.txt
Normal file
3
ChangeLog.d/7765.txt
Normal 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.
|
|
@ -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)
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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)
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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.
|
||||||
|
|
167
tests/suites/test_suite_psa_crypto_util.data
Normal file
167
tests/suites/test_suite_psa_crypto_util.data
Normal 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"
|
91
tests/suites/test_suite_psa_crypto_util.function
Normal file
91
tests/suites/test_suite_psa_crypto_util.function
Normal 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 */
|
Loading…
Reference in a new issue