Merge pull request #287 from gilles-peskine-arm/ctr_drbg-doc-nist-crypto
DRBG documentation improvements
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index ab947ab..1a76111 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -52,7 +52,7 @@
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
-#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
+#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. */
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
@@ -176,119 +176,203 @@
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the value
+ * \param p On entry, \c *p points to the first byte of the length,
+ * i.e. immediately after the tag.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
*
- * \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
- * end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
- * unparseable.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
+ * would end beyond \p end.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
- const unsigned char *end,
- size_t *len );
+ const unsigned char *end,
+ size_t *len );
/**
- * \brief Get the tag and length of the tag. Check for the requested tag.
+ * \brief Get the tag and length of the element.
+ * Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the length
- * \param tag The expected tag
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
+ * \param tag The expected tag.
*
- * \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
- * not match requested tag, or another specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start
+ * with the requested tag.
+ * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
+ * would end beyond \p end.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
- const unsigned char *end,
- size_t *len, int tag );
+ const unsigned char *end,
+ size_t *len, int tag );
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value (\c 0 or \c 1).
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BOOLEAN.
*/
int mbedtls_asn1_get_bool( unsigned char **p,
- const unsigned char *end,
- int *val );
+ const unsigned char *end,
+ int *val );
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
*/
int mbedtls_asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val );
+ const unsigned char *end,
+ int *val );
/**
* \brief Retrieve a bitstring ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param bs The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p is equal to \p end.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param bs On success, ::mbedtls_asn1_bitstring information about
+ * the parsed value.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
+ * extra data after a valid BIT STRING.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
- mbedtls_asn1_bitstring *bs);
+ mbedtls_asn1_bitstring *bs );
/**
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
* value.
* Updates the pointer to the beginning of the bit/octet string.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len Length of the actual bit/octect string in bytes
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * of the content of the BIT STRING.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On success, \c *len is the length of the content in bytes.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with
+ * a valid BIT STRING with a nonzero number of unused bits.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BIT STRING.
*/
-int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
- size_t *len );
+int mbedtls_asn1_get_bitstring_null( unsigned char **p,
+ const unsigned char *end,
+ size_t *len );
/**
- * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
- * Updated the pointer to immediately behind the full sequence tag.
+ * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
+ * Updates the pointer to immediately behind the full sequence tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param cur First variable in the chain to fill
- * \param tag Type of sequence
+ * \note On error, this function may return a partial list in \p cur.
+ * You must set `cur->next = NULL` before calling this function!
+ * Otherwise it is impossible to distinguish a previously non-null
+ * pointer from a pointer to an object allocated by this function.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \note If the sequence is empty, this function does not modify
+ * \c *cur. If the sequence is valid and non-empty, this
+ * function sets `cur->buf.tag` to \p tag. This allows
+ * callers to distinguish between an empty sequence and
+ * a one-element sequence.
+ *
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p is equal to \p end.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param cur A ::mbedtls_asn1_sequence which this function fills.
+ * When this function returns, \c *cur is the head of a linked
+ * list. Each node in this list is allocated with
+ * mbedtls_calloc() apart from \p cur itself, and should
+ * therefore be freed with mbedtls_free().
+ * The list describes the content of the sequence.
+ * The head of the list (i.e. \c *cur itself) describes the
+ * first element, `*cur->next` describes the second element, etc.
+ * For each element, `buf.tag == tag`, `buf.len` is the length
+ * of the content of the content of the element, and `buf.p`
+ * points to the first byte of the content (i.e. immediately
+ * past the length of the element).
+ * Note that list elements may be allocated even on error.
+ * \param tag Each element of the sequence must have this tag.
+ *
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
+ * extra data after a valid SEQUENCE OF \p tag.
+ * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_sequence_of( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_sequence *cur,
- int tag);
+ const unsigned char *end,
+ mbedtls_asn1_sequence *cur,
+ int tag );
#if defined(MBEDTLS_BIGNUM_C)
/**
- * \brief Retrieve a MPI value from an integer ASN.1 tag.
+ * \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param X The MPI that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param X On success, the parsed value.
*
- * \return 0 if successful or a specific ASN.1 or MPI error code.
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
+ * \return An MPI error code if the parsed value is too large.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
*/
int mbedtls_asn1_get_mpi( unsigned char **p,
- const unsigned char *end,
- mbedtls_mpi *X );
+ const unsigned char *end,
+ mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
@@ -296,10 +380,14 @@
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param alg The buffer to receive the OID
- * \param params The buffer to receive the params (if any)
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the AlgorithmIdentifier element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param alg The buffer to receive the OID.
+ * \param params The buffer to receive the parameters.
+ * This is zeroized if there are no parameters.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@@ -313,9 +401,12 @@
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param alg The buffer to receive the OID
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the AlgorithmIdentifier element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param alg The buffer to receive the OID.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@@ -339,15 +430,19 @@
/**
* \brief Free a mbedtls_asn1_named_data entry
*
- * \param entry The named data entry to free
+ * \param entry The named data entry to free.
+ * This function calls mbedtls_free() on
+ * `entry->oid.p` and `entry->val.p`.
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
/**
- * \brief Free all entries in a mbedtls_asn1_named_data list
- * Head will be set to NULL
+ * \brief Free all entries in a mbedtls_asn1_named_data list.
*
- * \param head Pointer to the head of the list of named data entries to free
+ * \param head Pointer to the head of the list of named data entries to free.
+ * This function calls mbedtls_asn1_free_named_data() and
+ * mbedtls_free() on each list element and
+ * sets \c *head to \c NULL.
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h
index 336f2da..9824146 100644
--- a/include/mbedtls/asn1write.h
+++ b/include/mbedtls/asn1write.h
@@ -100,6 +100,7 @@
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param X The MPI to write.
+ * It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
@@ -184,6 +185,7 @@
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param val The integer value to write.
+ * It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
@@ -232,7 +234,7 @@
/**
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
- * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
+ * string encoding tag (#MBEDTLS_ASN1_UTF8_STRING).
*
* \note This function works backwards in data buffer.
*
@@ -332,9 +334,13 @@
* through (will be updated in case of a new entry).
* \param oid The OID to look for.
* \param oid_len The size of the OID.
- * \param val The data to store (can be \c NULL if you want to fill
- * it by hand).
+ * \param val The associated data to store. If this is \c NULL,
+ * no data is copied to the new or existing buffer.
* \param val_len The minimum length of the data buffer needed.
+ * If this is 0, do not allocate a buffer for the associated
+ * data.
+ * If the OID was already present, enlarge, shrink or free
+ * the existing buffer to fit \p val_len.
*
* \return A pointer to the new / existing entry on success.
* \return \c NULL if if there was a memory allocation error.
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 68a4f65..d3b7522 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -57,7 +57,7 @@
* algorithms, key types, policies, etc. */
#include "crypto_types.h"
-/** \defgroup API version
+/** \defgroup version API version
* @{
*/
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index f0e4782..c5313d6 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -186,6 +186,9 @@
* \retval #PSA_ERROR_ALREADY_EXISTS
* There is already a key with the identifier specified in
* \p attributes.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The secure element driver for the specified lifetime does not
+ * support registering a key.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p attributes specifies a lifetime which is not located
* in a secure element.
@@ -428,8 +431,9 @@
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM), the group data comes
* from domain parameters set by psa_set_key_domain_parameters().
*/
-/* This value is reserved for private use in the TLS named group registry. */
-#define PSA_DH_GROUP_CUSTOM ((psa_dh_group_t) 0x01fc)
+/* This value is a deprecated value meaning an explicit curve in the IANA
+ * registry. */
+#define PSA_DH_GROUP_CUSTOM ((psa_dh_group_t) 0xff01)
/**
diff --git a/include/psa/crypto_se_driver.h b/include/psa/crypto_se_driver.h
index a43e0db..7ac1ed1 100644
--- a/include/psa/crypto_se_driver.h
+++ b/include/psa/crypto_se_driver.h
@@ -927,7 +927,14 @@
* sake of initial device provisioning or onboarding. Such a mechanism may
* be added to a future version of the PSA Cryptography API specification.
*
+ * This function may update the driver's persistent data through
+ * \p persistent_data. The core will save the updated persistent data at the
+ * end of the key creation process. See the description of
+ * ::psa_drv_se_allocate_key_t for more information.
+ *
* \param[in,out] drv_context The driver context structure.
+ * \param[in,out] persistent_data A pointer to the persistent data
+ * that allows writing.
* \param[in] attributes Attributes of the key.
* \param method The way in which the key is being created.
* \param[in] key_slot Slot where the key is to be stored.
@@ -946,6 +953,7 @@
*/
typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
psa_drv_se_context_t *drv_context,
+ void *persistent_data,
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_key_slot_number_t key_slot);
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index b6b6198..c4f9acd 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -65,10 +65,82 @@
*/
typedef uint32_t psa_key_type_t;
-/** The type of PSA elliptic curve identifiers. */
+/** The type of PSA elliptic curve identifiers.
+ *
+ * The curve identifier is required to create an ECC key using the
+ * PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY()
+ * macros.
+ *
+ * The encoding of curve identifiers is taken from the
+ * TLS Supported Groups Registry (formerly known as the
+ * TLS EC Named Curve Registry)
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
+ *
+ * This specification defines identifiers for some of the curves in the IANA
+ * registry. Implementations that support other curves that are in the IANA
+ * registry should use the IANA value and a implementation-specific identifier.
+ * Implemenations that support non-IANA curves should use one of the following
+ * approaches for allocating a key type:
+ *
+ * 1. Select a ::psa_ecc_curve_t value in the range #PSA_ECC_CURVE_VENDOR_MIN to
+ * #PSA_ECC_CURVE_VENDOR_MAX, which is a subset of the IANA private use
+ * range.
+ * 2. Use a ::psa_key_type_t value that is vendor-defined.
+ *
+ * The first option is recommended.
+ */
typedef uint16_t psa_ecc_curve_t;
-/** The type of PSA Diffie-Hellman group identifiers. */
+/** The type of PSA Diffie-Hellman group identifiers.
+ *
+ * The group identifier is required to create an Diffie-Hellman key using the
+ * PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY()
+ * macros.
+ *
+ * The encoding of group identifiers is taken from the
+ * TLS Supported Groups Registry (formerly known as the
+ * TLS EC Named Curve Registry)
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
+ *
+ * This specification defines identifiers for some of the groups in the IANA
+ * registry. Implementations that support other groups that are in the IANA
+ * registry should use the IANA value and a implementation-specific identifier.
+ * Implemenations that support non-IANA groups should use one of the following
+ * approaches for allocating a key type:
+ *
+ * 1. Select a ::psa_dh_group_t value in the range #PSA_DH_GROUP_VENDOR_MIN to
+ * #PSA_DH_GROUP_VENDOR_MAX, which is a subset of the IANA private use
+ * range.
+ * 2. Select a ::psa_dh_group_t value from the named groups allocated for
+ * GREASE in the IETF draft specification. The GREASE specification and
+ * values are listed below.
+ * 3. Use a ::psa_key_type_t value that is vendor-defined.
+ *
+ * Option 1 or 2 are recommended.
+ *
+ * The current draft of the GREASE specification is
+ * https://datatracker.ietf.org/doc/draft-ietf-tls-grease
+ *
+ * The following GREASE values are allocated for named groups:
+ * \code
+ * 0x0A0A
+ * 0x1A1A
+ * 0x2A2A
+ * 0x3A3A
+ * 0x4A4A
+ * 0x5A5A
+ * 0x6A6A
+ * 0x7A7A
+ * 0x8A8A
+ * 0x9A9A
+ * 0xAAAA
+ * 0xBABA
+ * 0xCACA
+ * 0xDADA
+ * 0xEAEA
+ * 0xFAFA
+ * \endcode
+ */
typedef uint16_t psa_dh_group_t;
/** \brief Encoding of a cryptographic algorithm.
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index 6b6a9f8..1e0c213 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -424,10 +424,18 @@
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000)
#define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x70030000)
#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
-/** Elliptic curve key pair. */
+/** Elliptic curve key pair.
+ *
+ * \param curve A value of type ::psa_ecc_curve_t that identifies the
+ * ECC curve to be used.
+ */
#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \
(PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve))
-/** Elliptic curve public key. */
+/** Elliptic curve public key.
+ *
+ * \param curve A value of type ::psa_ecc_curve_t that identifies the
+ * ECC curve to be used.
+ */
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
@@ -498,13 +506,34 @@
*/
#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e)
+/** Minimum value for a vendor-defined ECC curve identifier
+ *
+ * The range for vendor-defined curve identifiers is a subset of the IANA
+ * registry private use range, `0xfe00` - `0xfeff`.
+ */
+#define PSA_ECC_CURVE_VENDOR_MIN ((psa_ecc_curve_t) 0xfe00)
+/** Maximum value for a vendor-defined ECC curve identifier
+ *
+ * The range for vendor-defined curve identifiers is a subset of the IANA
+ * registry private use range, `0xfe00` - `0xfeff`.
+ */
+#define PSA_ECC_CURVE_VENDOR_MAX ((psa_ecc_curve_t) 0xfe7f)
+
#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x60040000)
#define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x70040000)
#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x0000ffff)
-/** Diffie-Hellman key pair. */
+/** Diffie-Hellman key pair.
+ *
+ * \param group A value of type ::psa_dh_group_t that identifies the
+ * Diffie-Hellman group to be used.
+ */
#define PSA_KEY_TYPE_DH_KEY_PAIR(group) \
(PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group))
-/** Diffie-Hellman public key. */
+/** Diffie-Hellman public key.
+ *
+ * \param group A value of type ::psa_dh_group_t that identifies the
+ * Diffie-Hellman group to be used.
+ */
#define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \
(PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group))
@@ -538,6 +567,19 @@
#define PSA_DH_GROUP_FFDHE6144 ((psa_dh_group_t) 0x0103)
#define PSA_DH_GROUP_FFDHE8192 ((psa_dh_group_t) 0x0104)
+/** Minimum value for a vendor-defined Diffie Hellman group identifier
+ *
+ * The range for vendor-defined group identifiers is a subset of the IANA
+ * registry private use range, `0x01fc` - `0x01ff`.
+ */
+#define PSA_DH_GROUP_VENDOR_MIN ((psa_dh_group_t) 0x01fc)
+/** Maximum value for a vendor-defined Diffie Hellman group identifier
+ *
+ * The range for vendor-defined group identifiers is a subset of the IANA
+ * registry private use range, `0x01fc` - `0x01ff`.
+ */
+#define PSA_DH_GROUP_VENDOR_MAX ((psa_dh_group_t) 0x01fd)
+
/** The block size of a block cipher.
*
* \param type A cipher key type (value of type #psa_key_type_t).
@@ -680,11 +722,15 @@
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff)
-
+/** MD2 */
#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001)
+/** MD4 */
#define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002)
+/** MD5 */
#define PSA_ALG_MD5 ((psa_algorithm_t)0x01000003)
+/** PSA_ALG_RIPEMD160 */
#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x01000004)
+/** SHA1 */
#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x01000005)
/** SHA2-224 */
#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x01000008)
diff --git a/library/asn1parse.c b/library/asn1parse.c
index 171c340..4764ca4 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -149,11 +149,18 @@
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
return( ret );
- if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
+ if( len == 0 || ( **p & 0x80 ) != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+ while( len > 0 && **p == 0 )
+ {
+ ++( *p );
+ --len;
+ }
+ if( len > sizeof( int ) )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
*val = 0;
-
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
@@ -223,8 +230,13 @@
if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
return( ret );
- if( (*len)-- < 2 || *(*p)++ != 0 )
+ if( *len == 0 )
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ --( *len );
+
+ if( **p != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ ++( *p );
return( 0 );
}
diff --git a/library/asn1write.c b/library/asn1write.c
index b54e26b..a138d0b 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -236,17 +236,20 @@
int ret;
size_t len = 0;
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
-
- len += 1;
- *--(*p) = val;
-
- if( val > 0 && **p & 0x80 )
+ do
{
if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ len += 1;
+ *--(*p) = val & 0xff;
+ val >>= 8;
+ }
+ while( val > 0 );
+ if( **p & 0x80 )
+ {
+ if( *p - start < 1 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
@@ -429,18 +432,26 @@
memcpy( cur->oid.p, oid, oid_len );
cur->val.len = val_len;
- cur->val.p = mbedtls_calloc( 1, val_len );
- if( cur->val.p == NULL )
+ if( val_len != 0 )
{
- mbedtls_free( cur->oid.p );
- mbedtls_free( cur );
- return( NULL );
+ cur->val.p = mbedtls_calloc( 1, val_len );
+ if( cur->val.p == NULL )
+ {
+ mbedtls_free( cur->oid.p );
+ mbedtls_free( cur );
+ return( NULL );
+ }
}
cur->next = *head;
*head = cur;
}
- else if( cur->val.len < val_len )
+ else if( val_len == 0 )
+ {
+ mbedtls_free( cur->val.p );
+ cur->val.p = NULL;
+ }
+ else if( cur->val.len != val_len )
{
/*
* Enlarge existing value buffer if needed
diff --git a/library/error.c b/library/error.c
index 7d7155b..649b3ba 100644
--- a/library/error.c
+++ b/library/error.c
@@ -467,7 +467,7 @@
if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
+ mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid" );
if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index b9ea00f..e26a7ec 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1579,7 +1579,7 @@
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* For a key in a secure element, we need to do three things
- * when creating a key (but not when registering an existing key):
+ * when creating or registering a key:
* create the key file in internal storage, create the
* key inside the secure element, and update the driver's
* persistent data. Start a transaction that will encompass these
@@ -1592,7 +1592,7 @@
* secure element driver updates its persistent state, but we do not yet
* save the driver's persistent state, so that if the power fails,
* we can roll back to a state where the key doesn't exist. */
- if( *p_drv != NULL && method != PSA_KEY_CREATION_REGISTER )
+ if( *p_drv != NULL )
{
status = psa_find_se_slot_for_key( attributes, method, *p_drv,
&slot->data.se.slot_number );
@@ -1609,6 +1609,12 @@
return( status );
}
}
+
+ if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
+ {
+ /* Key registration only makes sense with a secure element. */
+ return( PSA_ERROR_INVALID_ARGUMENT );
+ }
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
return( status );
@@ -1883,7 +1889,6 @@
psa_status_t status;
psa_key_slot_t *slot = NULL;
psa_se_drv_table_entry_t *driver = NULL;
- const psa_drv_se_t *drv;
psa_key_handle_t handle = 0;
/* Leaving attributes unspecified is not currently supported.
@@ -1900,37 +1905,6 @@
if( status != PSA_SUCCESS )
goto exit;
- if( driver == NULL )
- {
- status = PSA_ERROR_INVALID_ARGUMENT;
- goto exit;
- }
- drv = psa_get_se_driver_methods( driver );
-
- if ( psa_get_key_slot_number( attributes,
- &slot->data.se.slot_number ) != PSA_SUCCESS )
- {
- /* The application didn't specify a slot number. This doesn't
- * make sense when registering a slot. */
- status = PSA_ERROR_INVALID_ARGUMENT;
- goto exit;
- }
-
- /* If the driver has a slot number validation method, call it.
- * If it doesn't, it means the secure element is unable to validate
- * anything and so we have to trust the application. */
- if( drv->key_management != NULL &&
- drv->key_management->p_validate_slot_number != NULL )
- {
- status = drv->key_management->p_validate_slot_number(
- psa_get_se_driver_context( driver ),
- attributes,
- PSA_KEY_CREATION_REGISTER,
- slot->data.se.slot_number );
- if( status != PSA_SUCCESS )
- goto exit;
- }
-
status = psa_finish_key_creation( slot, driver );
exit:
@@ -5713,6 +5687,12 @@
if( status != PSA_SUCCESS )
goto exit;
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+ status = psa_init_all_se_drivers( );
+ if( status != PSA_SUCCESS )
+ goto exit;
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
status = psa_crypto_load_transaction( );
if( status == PSA_SUCCESS )
diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c
index 523c621..b7fa0c5 100644
--- a/library/psa_crypto_se.c
+++ b/library/psa_crypto_se.c
@@ -222,9 +222,16 @@
if( p_validate_slot_number == NULL )
return( PSA_ERROR_NOT_SUPPORTED );
status = p_validate_slot_number( &driver->context,
+ driver->internal.persistent_data,
attributes, method,
*slot_number );
}
+ else if( method == PSA_KEY_CREATION_REGISTER )
+ {
+ /* The application didn't specify a slot number. This doesn't
+ * make sense when registering a slot. */
+ return( PSA_ERROR_INVALID_ARGUMENT );
+ }
else
{
/* The application didn't tell us which slot to use. Let the driver
@@ -265,6 +272,31 @@
return( status == PSA_SUCCESS ? storage_status : status );
}
+psa_status_t psa_init_all_se_drivers( void )
+{
+ size_t i;
+ for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
+ {
+ psa_se_drv_table_entry_t *driver = &driver_table[i];
+ if( driver->lifetime == 0 )
+ continue; /* skipping unused entry */
+ const psa_drv_se_t *methods = psa_get_se_driver_methods( driver );
+ if( methods->p_init != NULL )
+ {
+ psa_status_t status = methods->p_init(
+ &driver->context,
+ driver->internal.persistent_data,
+ driver->lifetime );
+ if( status != PSA_SUCCESS )
+ return( status );
+ status = psa_save_se_persistent_data( driver );
+ if( status != PSA_SUCCESS )
+ return( status );
+ }
+ }
+ return( PSA_SUCCESS );
+}
+
/****************************************************************/
@@ -309,6 +341,8 @@
driver_table[i].lifetime = lifetime;
driver_table[i].methods = methods;
+ driver_table[i].internal.persistent_data_size =
+ methods->persistent_data_size;
if( methods->persistent_data_size != 0 )
{
@@ -326,8 +360,6 @@
if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST )
goto error;
}
- driver_table[i].internal.persistent_data_size =
- methods->persistent_data_size;
return( PSA_SUCCESS );
diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h
index 900a72b..86bf7a7 100644
--- a/library/psa_crypto_se.h
+++ b/library/psa_crypto_se.h
@@ -66,6 +66,12 @@
*/
void psa_unregister_all_se_drivers( void );
+/** Initialize all secure element drivers.
+ *
+ * Called from psa_crypto_init().
+ */
+psa_status_t psa_init_all_se_drivers( void );
+
/** A structure that describes a registered secure element driver.
*
* A secure element driver table entry contains a pointer to the
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7dcc98d..bcf462f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -79,6 +79,7 @@
add_test_suite(aes aes.xts)
add_test_suite(arc4)
add_test_suite(aria)
+add_test_suite(asn1parse)
add_test_suite(asn1write)
add_test_suite(base64)
add_test_suite(blowfish)
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 1a524a6..00320bc 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -158,6 +158,26 @@
} \
while( 0 )
+/** Allocate memory dynamically. Exit the test if this fails, but do
+ * not mark the test as failed.
+ *
+ * This macro behaves like #ASSERT_ALLOC, except that if the allocation
+ * fails, it jumps to the \c exit label without calling test_fail().
+ */
+#define ASSERT_ALLOC_WEAK( pointer, length ) \
+ do \
+ { \
+ TEST_ASSERT( ( pointer ) == NULL ); \
+ if( ( length ) != 0 ) \
+ { \
+ ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
+ ( length ) ); \
+ if( ( pointer ) == NULL ) \
+ goto exit; \
+ } \
+ } \
+ while( 0 )
+
/** Compare two buffers and fail the test case if they differ.
*
* This macro expands to an instruction, not an expression.
@@ -393,6 +413,7 @@
const char *test;
const char *filename;
int line_no;
+ unsigned long step;
}
test_info;
@@ -423,6 +444,19 @@
/*----------------------------------------------------------------------------*/
/* Helper Functions */
+/** Set the test step number for failure reports.
+ *
+ * Call this function to display "step NNN" in addition to the line number
+ * and file name if a test fails. Typically the "step number" is the index
+ * of a for loop but it can be whatever you want.
+ *
+ * \param step The step number to report.
+ */
+void test_set_step( unsigned long step )
+{
+ test_info.step = step;
+}
+
void test_fail( const char *test, int line_no, const char* filename )
{
test_info.result = TEST_RESULT_FAILED;
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 0f98d23..24d9b97 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -548,6 +548,7 @@
{
test_info.result = TEST_RESULT_SUCCESS;
test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_IDLE;
+ test_info.step = (unsigned long)( -1 );
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
/* Suppress all output from the library unless we're verbose
@@ -624,9 +625,15 @@
{
total_errors++;
mbedtls_fprintf( stdout, "FAILED\n" );
- mbedtls_fprintf( stdout, " %s\n at line %d, %s\n",
- test_info.test, test_info.line_no,
- test_info.filename );
+ mbedtls_fprintf( stdout, " %s\n at ",
+ test_info.test );
+ if( test_info.step != (unsigned long)( -1 ) )
+ {
+ mbedtls_fprintf( stdout, "step %lu, ",
+ test_info.step );
+ }
+ mbedtls_fprintf( stdout, "line %d, %s",
+ test_info.line_no, test_info.filename );
}
fflush( stdout );
}
diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function
index 91f7198..3d88957 100644
--- a/tests/suites/target_test.function
+++ b/tests/suites/target_test.function
@@ -75,7 +75,7 @@
c[1] = greentea_getc();
c[2] = '\0';
- assert( unhexify( &byte, c ) != 2 );
+ TEST_HELPER_ASSERT( unhexify( &byte, c ) != 2 );
return( byte );
}
@@ -90,18 +90,19 @@
uint32_t receive_uint32()
{
uint32_t value;
- const uint8_t c[9] = { greentea_getc(),
- greentea_getc(),
- greentea_getc(),
- greentea_getc(),
- greentea_getc(),
- greentea_getc(),
- greentea_getc(),
- greentea_getc(),
- '\0'
- };
- assert( unhexify( &value, c ) != 8 );
- return( (uint32_t)value );
+ const uint8_t c_be[8] = { greentea_getc(),
+ greentea_getc(),
+ greentea_getc(),
+ greentea_getc(),
+ greentea_getc(),
+ greentea_getc(),
+ greentea_getc(),
+ greentea_getc()
+ };
+ const uint8_t c[9] = { c_be[6], c_be[7], c_be[4], c_be[5], c_be[2],
+ c_be[3], c_be[0], c_be[1], '\0' };
+ TEST_HELPER_ASSERT( unhexify( (uint8_t*)&value, c ) != 8 );
+ return( value );
}
/**
@@ -368,13 +369,14 @@
void ** params = NULL;
uint8_t * data = NULL, * p = NULL;
- GREENTEA_SETUP( 180, "mbedtls_test" );
+ GREENTEA_SETUP( 800, "mbedtls_test" );
greentea_send_kv( "GO", " " );
while ( 1 )
{
ret = 0;
test_info.result = TEST_RESULT_SUCCESS;
+ test_info.step = (unsigned long)( -1 );
data_len = 0;
data = receive_data( &data_len );
diff --git a/tests/suites/test_suite_asn1parse.data b/tests/suites/test_suite_asn1parse.data
new file mode 100644
index 0000000..c5d9136
--- /dev/null
+++ b/tests/suites/test_suite_asn1parse.data
@@ -0,0 +1,438 @@
+Empty length
+parse_prefixes:"04":0:MBEDTLS_ERR_ASN1_INVALID_LENGTH
+
+Prefixes of OCTET STRING, length=0
+parse_prefixes:"04007e":2:0
+
+Prefixes of OCTET STRING, length=0 (0 length bytes)
+parse_prefixes:"04807e":2:MBEDTLS_ERR_ASN1_INVALID_LENGTH
+
+Prefixes of OCTET STRING, length=1
+parse_prefixes:"0401417e":3:0
+
+Prefixes of OCTET STRING, length=2
+parse_prefixes:"040241427e":4:0
+
+Prefixes of BOOLEAN, length=0
+parse_prefixes:"01007e":2:MBEDTLS_ERR_ASN1_INVALID_LENGTH
+
+Prefixes of BOOLEAN, length=1
+parse_prefixes:"0101007e":3:0
+
+Prefixes of BOOLEAN, length=2
+parse_prefixes:"010200007e":4:MBEDTLS_ERR_ASN1_INVALID_LENGTH
+
+Prefixes of INTEGER, length=1
+parse_prefixes:"0201417e":3:0
+
+Prefixes of INTEGER, length=2
+parse_prefixes:"020241427e":4:0
+
+Prefixes of INTEGER, length=5
+parse_prefixes:"020541424344457e":7:0
+
+Prefixes of empty BIT STRING
+parse_prefixes:"03007e":2:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+Prefixes of BIT STRING, unused_bits=0, payload_length=0
+parse_prefixes:"030100":3:0
+
+Prefixes of BIT STRING, unused_bits=0, payload_length=1
+parse_prefixes:"0302002a":4:0
+
+Prefixes of BIT STRING, unused_bits=1, payload_length=1
+parse_prefixes:"0302012a":4:0
+
+Prefixes of empty SEQUENCE
+parse_prefixes:"30007e":2:0
+
+Prefixes of SEQUENCE of BOOLEAN, INTEGER, INTEGER
+parse_prefixes:"300b01010102012a02031234567e":13:0
+
+Prefixes of SEQUENCE of (SEQUENCE of INTEGER, INTEGER), INTEGER
+parse_prefixes:"300b30060201410201420201617e":13:0
+
+length=0 (short form)
+get_len:"00":0
+
+length=0 (1 length byte)
+get_len:"8100":0
+
+length=0 (2 length bytes)
+get_len:"820000":0
+
+length=1 (short form)
+get_len:"01":1
+
+length=1 (1 length byte)
+get_len:"8101":1
+
+length=1 (2 length bytes)
+get_len:"820001":1
+
+length=1 (3 length bytes)
+get_len:"83000001":1
+
+length=1 (4 length bytes)
+get_len:"8400000001":1
+
+length=2 (short form)
+get_len:"02":2
+
+length=2 (1 length byte)
+get_len:"8102":2
+
+length=2 (2 length bytes)
+get_len:"820002":2
+
+length=2 (3 length bytes)
+get_len:"83000002":2
+
+length=2 (4 length bytes)
+get_len:"8400000002":2
+
+length=127 (short form)
+get_len:"7f":127
+
+length=128 (1 length byte)
+get_len:"8180":128
+
+length=128 (2 length bytes)
+get_len:"820080":128
+
+length=255 (1 length byte)
+get_len:"81ff":255
+
+length=255 (2 length bytes)
+get_len:"8200ff":255
+
+length=256 (2 length bytes)
+get_len:"820100":256
+
+length=256 (3 length bytes)
+get_len:"83000100":256
+
+length=258 (2 length bytes)
+get_len:"820102":258
+
+length=258 (3 length bytes)
+get_len:"83000102":258
+
+length=65535 (2 length bytes)
+get_len:"82ffff":65535
+
+length=65535 (3 length bytes)
+get_len:"8300ffff":65535
+
+length=65535 (4 length bytes)
+get_len:"840000ffff":65535
+
+length=65536 (3 length bytes)
+get_len:"83010000":65536
+
+length=65536 (4 length bytes)
+get_len:"8400010000":65536
+
+length=16777215 (3 length bytes)
+get_len:"83ffffff":16777215
+
+length=16777215 (4 length bytes)
+get_len:"8400ffffff":16777215
+
+length=16777216 (4 length bytes)
+get_len:"8401000000":16777216
+
+length=16909060 (4 length bytes)
+get_len:"8401020304":16909060
+
+BOOLEAN FALSE
+get_boolean:"010100":0:0
+
+BOOLEAN TRUE (1)
+get_boolean:"010101":1:0
+
+BOOLEAN TRUE (2)
+get_boolean:"010101":1:0
+
+BOOLEAN TRUE (128)
+get_boolean:"010180":1:0
+
+BOOLEAN TRUE (255)
+get_boolean:"0101ff":1:0
+
+Not BOOLEAN
+get_boolean:"020101":0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+Empty INTEGER
+depends_on:SUPPORT_NEGATIVE_INTEGERS
+get_integer:"0200":"":MBEDTLS_ERR_ASN1_INVALID_LENGTH
+
+INTEGER 0
+get_integer:"020100":"0":0
+
+INTEGER 0, extra leading 0
+get_integer:"02020000":"0":0
+
+INTEGER -0
+depends_on:SUPPORT_NEGATIVE_INTEGERS
+get_integer:"020180":"0":0
+
+INTEGER 1
+get_integer:"020101":"1":0:
+
+INTEGER 1, extra leading 0
+get_integer:"02020001":"1":0:
+
+INTEGER -1
+depends_on:SUPPORT_NEGATIVE_INTEGERS
+get_integer:"020181":"-1":0
+
+INTEGER 0x7f
+get_integer:"02017f":"7f":0
+
+INTEGER -0x7f
+depends_on:SUPPORT_NEGATIVE_INTEGERS
+get_integer:"0201ff":"-7f":0
+
+INTEGER 0x80
+get_integer:"02020080":"80":0
+
+INTEGER 0x80, extra leading 0
+get_integer:"0203000080":"80":0
+
+INTEGER 0xff
+get_integer:"020200ff":"ff":0
+
+INTEGER 0x7fff
+get_integer:"02027fff":"7fff":0
+
+INTEGER 0x12345678
+get_integer:"020412345678":"12345678":0
+
+INTEGER 0x12345678, extra leading 0
+get_integer:"02050012345678":"12345678":0
+
+INTEGER 0x123456789abcdef0
+get_integer:"0208123456789abcdef0":"123456789abcdef0":0
+
+INTEGER with 127 value octets
+get_integer:"027f0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":0
+
+INTEGER with 127 value octets (long length encoding)
+get_integer:"02817f0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":0
+
+INTEGER with 128 value octets
+get_integer:"0281800123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":0
+
+INTEGER with 128 value octets (leading 0 in length)
+get_integer:"028200800123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":0
+
+Not INTEGER
+get_integer:"010101":"":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+INTEGER too large for mpi
+get_mpi_too_large:
+
+BIT STRING: empty
+get_bitstring:"0300":0:0:MBEDTLS_ERR_ASN1_OUT_OF_DATA:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING: octets=0, unused_bits=0
+get_bitstring:"030100":0:0:0:0
+
+BIT STRING: octets=0, unused_bits=7
+get_bitstring:"030107":0:7:0:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING: octets=0, unused_bits=8
+get_bitstring:"030108":0:0:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING: octets=1, unused_bits=0
+get_bitstring:"03020041":1:0:0:0
+
+BIT STRING: octets=1, unused_bits=7
+get_bitstring:"03020741":1:7:0:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING: octets=1, unused_bits=8
+get_bitstring:"03020841":1:8:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING: octets=2, unused_bits=0
+get_bitstring:"0303004142":2:0:0:0
+
+BIT STRING: octets=2, unused_bits=7
+get_bitstring:"0303074142":2:7:0:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING: octets=2, unused_bits=8
+get_bitstring:"0303084142":2:8:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING with trailing garbage, unused_bits=0
+get_bitstring:"030200417e":1:0:MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:0
+
+BIT STRING with trailing garbage, unused_bits=7
+get_bitstring:"030207417e":1:7:MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+BIT STRING with trailing garbage, unused_bits=8
+get_bitstring:"030208417e":1:8:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
+
+Not BIT STRING
+get_bitstring:"04020100":0:0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+SEQUENCE OF 0 OCTET STRING
+get_sequence_of:"3000":0x04:"":0
+
+SEQUENCE OF 0 OCTET STRING plus trailing garbage
+get_sequence_of:"30007e":0x04:"":MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+
+SEQUENCE of 1 OCTET STRING truncated after tag
+get_sequence_of:"300104":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 1 OCTET STRING truncated in length #1
+get_sequence_of:"30020481":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 1 OCTET STRING truncated in length #2
+get_sequence_of:"3003048201":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 1 OCTET STRING truncated in content #1
+get_sequence_of:"30020401":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 1 OCTET STRING truncated in content #2
+get_sequence_of:"3003040241":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 1 OCTET STRING truncated in content #3
+get_sequence_of:"300404034142":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 1 OCTET STRING (0)
+get_sequence_of:"30020400":0x04:"4,0":0
+
+SEQUENCE of 1 OCTET STRING (1)
+get_sequence_of:"3003040141":0x04:"4,1":0
+
+SEQUENCE of 1 OCTET STRING (126)
+get_sequence_of:"308180047e414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141":0x04:"5,126":0
+
+SEQUENCE of 2 OCTET STRINGs, second truncated after tag
+get_sequence_of:"30050402414104":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 2 OCTET STRINGs, second truncated in length #1
+get_sequence_of:"3006040241410481":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 2 OCTET STRINGs, second truncated in length #2
+get_sequence_of:"300704024141048201":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 2 OCTET STRINGs, second truncated in content #1
+get_sequence_of:"3006040241410401":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 2 OCTET STRINGs, second truncated in content #2
+get_sequence_of:"300704024141040241":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 2 OCTET STRINGs, second truncated in content #3
+get_sequence_of:"30080402414104034142":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+SEQUENCE of 2 OCTET STRINGs (2, 0)
+get_sequence_of:"3006040241410400":0x04:"4,2,8,0":0
+
+SEQUENCE of 2 OCTET STRINGs (2, 1)
+get_sequence_of:"300704024141040142":0x04:"4,2,8,1":0
+
+SEQUENCE of 2 OCTET STRINGs (0, 2)
+get_sequence_of:"3006040004024141":0x04:"4,0,6,2":0
+
+SEQUENCE of 2 OCTET STRINGs (1, 2)
+get_sequence_of:"300704014104024242":0x04:"4,1,7,2":0
+
+Not a SEQUENCE (not CONSTRUCTED)
+get_sequence_of:"1000":0x04:"":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+Not a SEQUENCE (not SEQUENCE)
+get_sequence_of:"3100":0x04:"":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+AlgorithmIdentifier, no params
+get_alg:"300506034f4944":4:3:0:0:0:7:0
+
+AlgorithmIdentifier, no params, trailing garbage
+get_alg:"300506034f49447e":4:3:0:0:0:7:0
+
+AlgorithmIdentifier, null params
+get_alg:"300706034f49440500":4:3:0x05:9:0:9:0
+
+AlgorithmIdentifier, null params, trailing garbage
+get_alg:"300706034f494405007e":4:3:0x05:9:0:9:0
+
+AlgorithmIdentifier, OCTET STRING params
+get_alg:"300c06034f494404056162636465":4:3:0x04:9:5:14:0
+
+AlgorithmIdentifier, truncated before OID
+get_alg:"3000":4:3:0:0:0:2:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+AlgorithmIdentifier, truncated in OID after tag
+get_alg:"300106":0:0:0:0:0:3:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+AlgorithmIdentifier, truncated in OID after length
+get_alg:"30020603":4:3:0:0:0:4:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+AlgorithmIdentifier, truncated inside OID content
+get_alg:"300406034f49":4:3:0:0:0:6:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+AlgorithmIdentifier, truncated in params after tag
+get_alg:"300606034f494404":4:3:0x04:0:0:8:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+AlgorithmIdentifier, truncated in params after length
+get_alg:"300706034f49440405":4:3:0x04:9:0:9:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+AlgorithmIdentifier, truncated inside params content
+get_alg:"300806034f4944040561":4:3:0x04:9:5:10:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+Not an AlgorithmIdentifier (not a SEQUENCE)
+get_alg:"310506034f4944":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+Not an AlgorithmIdentifier (empty SEQUENCE)
+get_alg:"3000":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+Not an AlgorithmIdentifier (not an OID)
+get_alg:"3006050006034f4944":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+Not an AlgorithmIdentifier (too many elements)
+get_alg:"300f06034f494406034f494406034f4944":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+
+Find named data: not found
+find_named_data:"414141":"424242":"434343":"444444":"7f7f7f":0:4
+
+Find named data: empty haystack
+find_named_data:"414141":"424242":"434343":"444444":"7f7f7f":4:4
+
+Find named data: first
+find_named_data:"414141":"424242":"434343":"444444":"414141":0:0
+
+Find named data: last
+find_named_data:"414141":"424242":"434343":"444444":"444444":0:3
+
+Find named data: skip suffix
+find_named_data:"41414141":"414141":"434343":"444444":"414141":0:1
+
+Find named data: skip prefix
+find_named_data:"4141":"414141":"434343":"444444":"414141":0:1
+
+Find named data: first match
+find_named_data:"414141":"414141":"434343":"444444":"414141":0:0
+
+Free named data: null pointer
+free_named_data_null:
+
+Free named data: all null
+free_named_data:0:0:0
+
+Free named data: with oid
+free_named_data:1:0:0
+
+Free named data: with val
+free_named_data:0:1:0
+
+Free named data: with next
+free_named_data:0:0:1
+
+Free named data list (empty)
+free_named_data_list:0
+
+Free named data list (1)
+free_named_data_list:1
+
+Free named data list (2)
+free_named_data_list:2
diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function
new file mode 100644
index 0000000..3bfb1c7
--- /dev/null
+++ b/tests/suites/test_suite_asn1parse.function
@@ -0,0 +1,562 @@
+/* BEGIN_HEADER */
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mbedtls/bignum.h"
+#include "mbedtls/asn1.h"
+#if defined(MBEDTLS_ASN1_WRITE_C)
+#include "mbedtls/asn1write.h"
+#endif
+
+#define ERR_PARSE_INCONSISTENCY INT_MAX
+
+static int nested_parse( unsigned char **const p,
+ const unsigned char *const end )
+{
+ int ret;
+ size_t len = 0;
+ size_t len2 = 0;
+ unsigned char *const start = *p;
+ unsigned char *content_start;
+ unsigned char tag;
+
+ /* First get the length, skipping over the tag. */
+ content_start = start + 1;
+ ret = mbedtls_asn1_get_len( &content_start, end, &len );
+ TEST_ASSERT( content_start <= end );
+ if( ret != 0 )
+ return( ret );
+
+ /* Since we have a valid element start (tag and length), retrieve and
+ * check the tag. */
+ tag = start[0];
+ TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len2, tag ^ 1 ),
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ *p = start;
+ TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len2, tag ), 0 );
+ TEST_EQUAL( len, len2 );
+ TEST_ASSERT( *p == content_start );
+ *p = content_start;
+
+ switch( tag & 0x1f )
+ {
+ case MBEDTLS_ASN1_BOOLEAN:
+ {
+ int val = -257;
+ *p = start;
+ ret = mbedtls_asn1_get_bool( p, end, &val );
+ if( ret == 0 )
+ TEST_ASSERT( val == 0 || val == 1 );
+ break;
+ }
+
+ case MBEDTLS_ASN1_INTEGER:
+ {
+#if defined(MBEDTLS_BIGNUM_C)
+ mbedtls_mpi mpi;
+ mbedtls_mpi_init( &mpi );
+ *p = start;
+ ret = mbedtls_asn1_get_mpi( p, end, &mpi );
+ mbedtls_mpi_free( &mpi );
+#endif
+ /* If we're sure that the number fits in an int, also
+ * call mbedtls_asn1_get_int(). */
+ if( ret == 0 && len < sizeof( int ) )
+ {
+ int val = -257;
+ unsigned char *q = start;
+ ret = mbedtls_asn1_get_int( &q, end, &val );
+ TEST_ASSERT( *p == q );
+ }
+ break;
+ }
+
+ case MBEDTLS_ASN1_BIT_STRING:
+ {
+ mbedtls_asn1_bitstring bs;
+ *p = start;
+ ret = mbedtls_asn1_get_bitstring( p, end, &bs );
+ break;
+ }
+
+ case MBEDTLS_ASN1_SEQUENCE:
+ {
+ while( *p <= end && *p < content_start + len && ret == 0 )
+ ret = nested_parse( p, content_start + len );
+ break;
+ }
+
+ case MBEDTLS_ASN1_OCTET_STRING:
+ case MBEDTLS_ASN1_NULL:
+ case MBEDTLS_ASN1_OID:
+ case MBEDTLS_ASN1_UTF8_STRING:
+ case MBEDTLS_ASN1_SET:
+ case MBEDTLS_ASN1_PRINTABLE_STRING:
+ case MBEDTLS_ASN1_T61_STRING:
+ case MBEDTLS_ASN1_IA5_STRING:
+ case MBEDTLS_ASN1_UTC_TIME:
+ case MBEDTLS_ASN1_GENERALIZED_TIME:
+ case MBEDTLS_ASN1_UNIVERSAL_STRING:
+ case MBEDTLS_ASN1_BMP_STRING:
+ default:
+ /* No further testing implemented for this tag. */
+ *p += len;
+ return( 0 );
+ }
+
+ TEST_ASSERT( *p <= end );
+ return( ret );
+
+exit:
+ return( ERR_PARSE_INCONSISTENCY );
+}
+
+int get_len_step( const data_t *input, size_t buffer_size,
+ size_t actual_length )
+{
+ unsigned char *buf = NULL;
+ unsigned char *p = NULL;
+ size_t parsed_length;
+ int ret;
+
+ test_set_step( buffer_size );
+ /* Allocate a new buffer of exactly the length to parse each time.
+ * This gives memory sanitizers a chance to catch buffer overreads. */
+ if( buffer_size == 0 )
+ {
+ ASSERT_ALLOC( buf, 1 );
+ p = buf + 1;
+ }
+ else
+ {
+ ASSERT_ALLOC_WEAK( buf, buffer_size );
+ if( buffer_size > input->len )
+ {
+ memcpy( buf, input->x, input->len );
+ memset( buf + input->len, 'A', buffer_size - input->len );
+ }
+ else
+ {
+ memcpy( buf, input->x, buffer_size );
+ }
+ p = buf;
+ }
+
+ ret = mbedtls_asn1_get_len( &p, buf + buffer_size, &parsed_length );
+
+ if( buffer_size >= input->len + actual_length )
+ {
+ TEST_EQUAL( ret, 0 );
+ TEST_ASSERT( p == buf + input->len );
+ TEST_EQUAL( parsed_length, actual_length );
+ }
+ else
+ {
+ TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ }
+ mbedtls_free( buf );
+ return( 1 );
+
+exit:
+ mbedtls_free( buf );
+ return( 0 );
+}
+
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_ASN1_PARSE_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void parse_prefixes( const data_t *input,
+ int actual_length_arg,
+ int last_result )
+{
+ size_t actual_length = actual_length_arg;
+ unsigned char *buf = NULL;
+ unsigned char *p = NULL;
+ size_t buffer_size;
+ int ret;
+
+ for( buffer_size = 1; buffer_size <= input->len; buffer_size++ )
+ {
+ test_set_step( buffer_size );
+ /* Allocate a new buffer of exactly the length to parse each time.
+ * This gives memory sanitizers a chance to catch buffer overreads. */
+ ASSERT_ALLOC( buf, buffer_size );
+ memcpy( buf, input->x, buffer_size );
+ p = buf;
+ ret = nested_parse( &p, buf + buffer_size );
+ if( ret == ERR_PARSE_INCONSISTENCY )
+ goto exit;
+ if( actual_length > 0 && buffer_size >= actual_length )
+ {
+ TEST_EQUAL( ret, last_result );
+ if( ret == 0 )
+ TEST_ASSERT( p == buf + actual_length );
+ }
+ else
+ {
+ TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ }
+ mbedtls_free( buf );
+ buf = NULL;
+ }
+
+exit:
+ mbedtls_free( buf );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_len( const data_t *input, int actual_length_arg )
+{
+ size_t actual_length = actual_length_arg;
+ size_t buffer_size;
+
+ for( buffer_size = 1; buffer_size <= input->len + 1; buffer_size++ )
+ {
+ if( ! get_len_step( input, buffer_size, actual_length ) )
+ goto exit;
+ }
+ if( ! get_len_step( input, input->len + actual_length - 1, actual_length ) )
+ goto exit;
+ if( ! get_len_step( input, input->len + actual_length, actual_length ) )
+ goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_boolean( const data_t *input,
+ int expected_value, int expected_result )
+{
+ unsigned char *p = input->x;
+ int val;
+ int ret;
+ ret = mbedtls_asn1_get_bool( &p, input->x + input->len, &val );
+ TEST_EQUAL( ret, expected_result );
+ if( expected_result == 0 )
+ {
+ TEST_EQUAL( val, expected_value );
+ TEST_ASSERT( p == input->x + input->len );
+ }
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_integer( const data_t *input,
+ const char *expected_hex, int expected_result )
+{
+ unsigned char *p;
+#if defined(MBEDTLS_BIGNUM_C)
+ mbedtls_mpi expected_mpi;
+ mbedtls_mpi actual_mpi;
+#endif
+ long expected_value;
+ int expected_result_for_int = expected_result;
+ int expected_result_for_mpi = expected_result;
+ int val;
+ int ret;
+
+#if defined(MBEDTLS_BIGNUM_C)
+ mbedtls_mpi_init( &expected_mpi );
+ mbedtls_mpi_init( &actual_mpi );
+#endif
+
+ errno = 0;
+ expected_value = strtol( expected_hex, NULL, 16 );
+ if( expected_result == 0 &&
+ ( errno == ERANGE
+#if LONG_MAX > INT_MAX
+ || expected_value > INT_MAX || expected_value < INT_MIN
+#endif
+ ) )
+ {
+ expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
+ }
+
+ p = input->x;
+ ret = mbedtls_asn1_get_int( &p, input->x + input->len, &val );
+ TEST_EQUAL( ret, expected_result_for_int );
+ if( ret == 0 )
+ {
+ TEST_EQUAL( val, expected_value );
+ TEST_ASSERT( p == input->x + input->len );
+ }
+
+#if defined(MBEDTLS_BIGNUM_C)
+ ret = mbedtls_mpi_read_string( &expected_mpi, 16, expected_hex );
+ TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ if( ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+ {
+ /* The data overflows the maximum MPI size. */
+ expected_result_for_mpi = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+ p = input->x;
+ ret = mbedtls_asn1_get_mpi( &p, input->x + input->len, &actual_mpi );
+ TEST_EQUAL( ret, expected_result_for_mpi );
+ if( ret == 0 )
+ {
+ TEST_ASSERT( mbedtls_mpi_cmp_mpi( &actual_mpi , &expected_mpi ) == 0 );
+ TEST_ASSERT( p == input->x + input->len );
+ }
+#endif
+
+exit:
+#if defined(MBEDTLS_BIGNUM_C)
+ mbedtls_mpi_free( &expected_mpi );
+ mbedtls_mpi_free( &actual_mpi );
+#endif
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
+void get_mpi_too_large( )
+{
+ unsigned char *buf = NULL;
+ unsigned char *p;
+ mbedtls_mpi actual_mpi;
+ size_t too_many_octets =
+ MBEDTLS_MPI_MAX_LIMBS * sizeof(mbedtls_mpi_uint) + 1;
+ size_t size = too_many_octets + 6;
+
+ mbedtls_mpi_init( &actual_mpi );
+
+ ASSERT_ALLOC( buf, size );
+ buf[0] = 0x02; /* tag: INTEGER */
+ buf[1] = 0x84; /* 4-octet length */
+ buf[2] = ( too_many_octets >> 24 ) & 0xff;
+ buf[3] = ( too_many_octets >> 16 ) & 0xff;
+ buf[4] = ( too_many_octets >> 8 ) & 0xff;
+ buf[5] = too_many_octets & 0xff;
+ buf[6] = 0x01; /* most significant octet */
+
+ p = buf;
+ TEST_EQUAL( mbedtls_asn1_get_mpi( &p, buf + size, &actual_mpi ),
+ MBEDTLS_ERR_MPI_ALLOC_FAILED );
+
+exit:
+ mbedtls_mpi_free( &actual_mpi );
+ mbedtls_free( buf );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_bitstring( const data_t *input,
+ int expected_length, int expected_unused_bits,
+ int expected_result, int expected_result_null )
+{
+ mbedtls_asn1_bitstring bs = { 0xdead, 0x21, NULL };
+ unsigned char *p = input->x;
+
+ TEST_EQUAL( mbedtls_asn1_get_bitstring( &p, input->x + input->len, &bs ),
+ expected_result );
+ if( expected_result == 0 )
+ {
+ TEST_EQUAL( bs.len, (size_t) expected_length );
+ TEST_EQUAL( bs.unused_bits, expected_unused_bits );
+ TEST_ASSERT( bs.p != NULL );
+ TEST_EQUAL( bs.p - input->x + bs.len, input->len );
+ TEST_ASSERT( p == input->x + input->len );
+ }
+
+ p = input->x;
+ TEST_EQUAL( mbedtls_asn1_get_bitstring_null( &p, input->x + input->len,
+ &bs.len ),
+ expected_result_null );
+ if( expected_result_null == 0 )
+ {
+ TEST_EQUAL( bs.len, (size_t) expected_length );
+ if( expected_result == 0 )
+ TEST_ASSERT( p == input->x + input->len - bs.len );
+ }
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_sequence_of( const data_t *input, int tag,
+ const char *description,
+ int expected_result )
+{
+ mbedtls_asn1_sequence head = { { 0, 0, NULL }, NULL };
+ mbedtls_asn1_sequence *cur, *next;
+ unsigned char *p = input->x;
+ const char *rest = description;
+ unsigned long n;
+
+ TEST_EQUAL( mbedtls_asn1_get_sequence_of( &p, input->x + input->len,
+ &head, tag ),
+ expected_result );
+ if( expected_result == 0 )
+ {
+ TEST_ASSERT( p == input->x + input->len );
+
+ if( ! *rest )
+ {
+ TEST_EQUAL( head.buf.tag, 0 );
+ TEST_ASSERT( head.buf.p == NULL );
+ TEST_EQUAL( head.buf.len, 0 );
+ TEST_ASSERT( head.next == NULL );
+ }
+ else
+ {
+ cur = &head;
+ while( *rest )
+ {
+ ++test_info.step;
+ TEST_ASSERT( cur != NULL );
+ TEST_EQUAL( cur->buf.tag, tag );
+ n = strtoul( rest, (char **) &rest, 0 );
+ TEST_EQUAL( n, (size_t)( cur->buf.p - input->x ) );
+ ++rest;
+ n = strtoul( rest, (char **) &rest, 0 );
+ TEST_EQUAL( n, cur->buf.len );
+ if( *rest )
+ ++rest;
+ cur = cur->next;
+ }
+ TEST_ASSERT( cur == NULL );
+ }
+ }
+
+exit:
+ cur = head.next;
+ while( cur != NULL )
+ {
+ next = cur->next;
+ mbedtls_free( cur );
+ cur = next;
+ }
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_alg( const data_t *input,
+ int oid_offset, int oid_length,
+ int params_tag, int params_offset, int params_length,
+ int total_length,
+ int expected_result )
+{
+ mbedtls_asn1_buf oid = { -1, 0, NULL };
+ mbedtls_asn1_buf params = { -1, 0, NULL };
+ unsigned char *p = input->x;
+ int ret;
+
+ TEST_EQUAL( mbedtls_asn1_get_alg( &p, input->x + input->len,
+ &oid, ¶ms ),
+ expected_result );
+ if( expected_result == 0 )
+ {
+ TEST_EQUAL( oid.tag, MBEDTLS_ASN1_OID );
+ TEST_EQUAL( oid.p - input->x, oid_offset );
+ TEST_EQUAL( oid.len, (size_t) oid_length );
+ TEST_EQUAL( params.tag, params_tag );
+ if( params_offset != 0 )
+ TEST_EQUAL( params.p - input->x, params_offset );
+ else
+ TEST_ASSERT( params.p == NULL );
+ TEST_EQUAL( params.len, (size_t) params_length );
+ TEST_EQUAL( p - input->x, total_length );
+ }
+
+ ret = mbedtls_asn1_get_alg_null( &p, input->x + input->len, &oid );
+ if( expected_result == 0 && params_offset == 0 )
+ {
+ TEST_EQUAL( oid.tag, MBEDTLS_ASN1_OID );
+ TEST_EQUAL( oid.p - input->x, oid_offset );
+ TEST_EQUAL( oid.len, (size_t) oid_length );
+ TEST_EQUAL( p - input->x, total_length );
+ }
+ else
+ TEST_ASSERT( ret != 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void find_named_data( data_t *oid0, data_t *oid1, data_t *oid2, data_t *oid3,
+ data_t *needle, int from, int position )
+{
+ mbedtls_asn1_named_data nd[] ={
+ { {0x06, oid0->len, oid0->x}, {0, 0, NULL}, NULL, 0 },
+ { {0x06, oid1->len, oid1->x}, {0, 0, NULL}, NULL, 0 },
+ { {0x06, oid2->len, oid2->x}, {0, 0, NULL}, NULL, 0 },
+ { {0x06, oid3->len, oid3->x}, {0, 0, NULL}, NULL, 0 },
+ };
+ mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
+ size_t i;
+ mbedtls_asn1_named_data *found;
+
+ for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
+ pointers[i] = &nd[i];
+ pointers[ARRAY_LENGTH( nd )] = NULL;
+ for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
+ nd[i].next = pointers[i+1];
+
+ found = mbedtls_asn1_find_named_data( pointers[from],
+ (const char *) needle->x,
+ needle->len );
+ TEST_ASSERT( found == pointers[position] );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void free_named_data_null( )
+{
+ mbedtls_asn1_free_named_data( NULL );
+ goto exit; /* Silence unused label warning */
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void free_named_data( int with_oid, int with_val, int with_next )
+{
+ mbedtls_asn1_named_data next =
+ { {0x06, 0, NULL}, {0, 0xcafe, NULL}, NULL, 0 };
+ mbedtls_asn1_named_data head =
+ { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 };
+
+ if( with_oid )
+ ASSERT_ALLOC( head.oid.p, 1 );
+ if( with_val )
+ ASSERT_ALLOC( head.val.p, 1 );
+ if( with_next )
+ head.next = &next;
+
+ mbedtls_asn1_free_named_data( &head );
+ TEST_ASSERT( head.oid.p == NULL );
+ TEST_ASSERT( head.val.p == NULL );
+ TEST_ASSERT( head.next == NULL );
+ TEST_ASSERT( next.val.len == 0xcafe );
+
+exit:
+ mbedtls_free( head.oid.p );
+ mbedtls_free( head.val.p );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void free_named_data_list( int length )
+{
+ mbedtls_asn1_named_data *head = NULL;
+ int i;
+
+ for( i = 0; i < length; i++ )
+ {
+ mbedtls_asn1_named_data *new = NULL;
+ ASSERT_ALLOC( new, sizeof( mbedtls_asn1_named_data ) );
+ new->next = head;
+ head = new;
+ }
+
+ mbedtls_asn1_free_named_data_list( &head );
+ TEST_ASSERT( head == NULL );
+ /* Most of the point of the test is that it doesn't leak memory.
+ * So this test is only really useful under a memory leak detection
+ * framework. */
+exit:
+ mbedtls_asn1_free_named_data_list( &head );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_asn1write.data b/tests/suites/test_suite_asn1write.data
index 9982d03..fd589fb 100644
--- a/tests/suites/test_suite_asn1write.data
+++ b/tests/suites/test_suite_asn1write.data
@@ -1,53 +1,182 @@
-ASN.1 Write Octet String #0 (Empty string)
-mbedtls_asn1_write_octet_string:"":"0400":2:2
+ASN.1 Write NULL
+mbedtls_asn1_write_null:"0500"
-ASN.1 Write Octet String #1 (Large buffer)
-mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":10:5
+ASN.1 Write BOOLEAN FALSE
+mbedtls_asn1_write_bool:0:"010100"
-ASN.1 Write Octet String #2 (Buffer just fits)
-mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":5:5
+ASN.1 Write BOOLEAN TRUE
+mbedtls_asn1_write_bool:1:"0101ff"
-ASN.1 Write Octet String #3 (Buffer too small for tag)
-mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":4:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 0
+mbedtls_asn1_write_int:0:"020100"
-ASN.1 Write Octet String #4 (Buffer too small for len)
-mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":3:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 1
+mbedtls_asn1_write_int:1:"020101"
-ASN.1 Write Octet String #5 (Buffer too small for string)
-mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":2:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 127
+mbedtls_asn1_write_int:0x7f:"02017f"
-ASN.1 Write Octet String #6 (l = 128, large buffer)
-mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"048180000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":140:131
+ASN.1 Write int 128
+mbedtls_asn1_write_int:0x80:"02020080"
-ASN.1 Write Octet String #7 (l = 128, buffer just fits)
-mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"048180000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":131:131
+ASN.1 Write int 255
+mbedtls_asn1_write_int:0xff:"020200ff"
-ASN.1 Write Octet String #8 (l = 128, buffer too small for tag)
-mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":130:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 256
+mbedtls_asn1_write_int:0x100:"02020100"
-ASN.1 Write Octet String #9 (l = 128, buffer too small for len)
-mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":129:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 32767
+mbedtls_asn1_write_int:0x7fff:"02027fff"
-ASN.1 Write Octet String #9 (l = 128, buffer too small for string)
-mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":127:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 32768
+mbedtls_asn1_write_int:0x8000:"0203008000"
-ASN.1 Write IA5 String #0 (Empty string)
-mbedtls_asn1_write_ia5_string:"":"1600":2:2
+ASN.1 Write int 65535
+mbedtls_asn1_write_int:0xffff:"020300ffff"
-ASN.1 Write IA5 String #1 (Large buffer)
-mbedtls_asn1_write_ia5_string:"ABC":"1603414243":10:5
+ASN.1 Write int 65536
+mbedtls_asn1_write_int:0x10000:"0203010000"
-ASN.1 Write IA5 String #2 (Buffer just fits)
-mbedtls_asn1_write_ia5_string:"ABC":"1603414243":5:5
+ASN.1 Write int 8388607
+mbedtls_asn1_write_int:0x7fffff:"02037fffff"
-ASN.1 Write IA5 String #3 (Buffer too small for tag)
-mbedtls_asn1_write_ia5_string:"ABC":"":4:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 8388608
+mbedtls_asn1_write_int:0x800000:"020400800000"
-ASN.1 Write IA5 String #4 (Buffer too small for len)
-mbedtls_asn1_write_ia5_string:"ABC":"":3:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 0x12345678
+mbedtls_asn1_write_int:0x12345678:"020412345678"
-ASN.1 Write IA5 String #5 (Buffer too small for string)
-mbedtls_asn1_write_ia5_string:"ABC":"":2:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+ASN.1 Write int 2147483647
+mbedtls_asn1_write_int:0x7fffffff:"02047fffffff"
+
+#ASN.1 Write mpi 0
+#mbedtls_asn1_write_mpi:"00":"020100"
+
+ASN.1 Write mpi 1
+mbedtls_asn1_write_mpi:"01":"020101"
+
+ASN.1 Write mpi 0x7f
+mbedtls_asn1_write_mpi:"7f":"02017f"
+
+#ASN.1 Write mpi 0x80
+#mbedtls_asn1_write_mpi:"7f":"02020080"
+
+#ASN.1 Write mpi 0xff
+#mbedtls_asn1_write_mpi:"7f":"020200ff"
+
+ASN.1 Write mpi 0x100
+mbedtls_asn1_write_mpi:"0100":"02020100"
+
+ASN.1 Write mpi, 127*8-1 bits
+mbedtls_asn1_write_mpi:"7f7b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8":"027f7f7b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8"
+
+#ASN.1 Write mpi, 127*8 bits
+#mbedtls_asn1_write_mpi:"e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8":"028180e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8"
+
+ASN.1 Write mpi, 127*8+1 bits
+mbedtls_asn1_write_mpi:"108446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c":"028180108446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c"
+
+ASN.1 Write mpi, 255*8-1 bits
+mbedtls_asn1_write_mpi:"7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c":"0281ff7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c"
+
+#ASN.1 Write mpi, 255*8 bits
+#mbedtls_asn1_write_mpi:"fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c":"0282010000fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c"
+
+ASN.1 Write mpi, 256*8-1 bits
+mbedtls_asn1_write_mpi:"7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c89":"028201007bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c89"
+
+ASN.1 Write OCTET STRING: length=0
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"":"0400"
+
+ASN.1 Write OCTET STRING: length=1
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"41":"040141"
+
+ASN.1 Write OCTET STRING: length=2
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"4142":"04024142"
+
+ASN.1 Write OCTET STRING: length=127
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"99a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"047f99a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
+
+ASN.1 Write OCTET STRING: length=128
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"0481800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
+
+ASN.1 Write OCTET STRING: length=255
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d":"0481ff633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d"
+
+ASN.1 Write OCTET STRING: length=256
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"5a633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d":"048201005a633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d"
+
+ASN.1 Write UTF8 STRING: length=0
+mbedtls_asn1_write_string:MBEDTLS_ASN1_UTF8_STRING:"":"0c00"
+
+ASN.1 Write UTF8 STRING: length=1
+mbedtls_asn1_write_string:MBEDTLS_ASN1_UTF8_STRING:"41":"0c0141"
+
+ASN.1 Write UTF8 STRING: length=128
+mbedtls_asn1_write_string:MBEDTLS_ASN1_UTF8_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"0c81800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
+
+ASN.1 Write PRINTABLE STRING: length=0
+mbedtls_asn1_write_string:MBEDTLS_ASN1_PRINTABLE_STRING:"":"1300"
+
+ASN.1 Write PRINTABLE STRING: length=1
+mbedtls_asn1_write_string:MBEDTLS_ASN1_PRINTABLE_STRING:"41":"130141"
+
+ASN.1 Write PRINTABLE STRING: length=128
+mbedtls_asn1_write_string:MBEDTLS_ASN1_PRINTABLE_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"1381800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
+
+ASN.1 Write IA5 STRING: length=0
+mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING:"":"1600"
+
+ASN.1 Write IA5 STRING: length=1
+mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING:"41":"160141"
+
+ASN.1 Write IA5 STRING: length=128
+mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"1681800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
+
+ASN.1 Write tagged string: length=0
+mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING | MBEDTLS_ASN1_CONTEXT_SPECIFIC:"":"9600"
+
+ASN.1 Write tagged string: length=1
+mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING | MBEDTLS_ASN1_CONTEXT_SPECIFIC:"41":"960141"
+
+ASN.1 Write tagged string: length=128
+mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING | MBEDTLS_ASN1_CONTEXT_SPECIFIC:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"9681800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
+
+ASN.1 Write OID: length=0
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OID:"":"0600"
+
+ASN.1 Write OID: length=1
+mbedtls_asn1_write_string:MBEDTLS_ASN1_OID:"41":"060141"
+
+ASN.1 Write AlgorithmIdentifier, null parameters
+mbedtls_asn1_write_algorithm_identifier:"4f4944":8:"300d06034f4944"
+
+ASN.1 Write AlgorithmIdentifier, parameters (8 bytes)
+mbedtls_asn1_write_algorithm_identifier:"4f4944":8:"300d06034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0x7f
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0x7a:"307f06034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0x80
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0x7b:"30818006034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0xff
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfa:"3081ff06034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0x100
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfb:"3082010006034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0xffff
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffa:"3082ffff06034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0x10000
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffb:"308301000006034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0xffffff
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffffa:"3083ffffff06034f4944"
+
+ASN.1 Write AlgorithmIdentifier, total length=0x1000000
+mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffffb:"30840100000006034f4944"
ASN.1 Write / Read Length #0 (Len = 0, short form)
mbedtls_asn1_write_len:0:"00":1:1
@@ -92,73 +221,121 @@
mbedtls_asn1_write_len:16909060:"8401020304":4:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write Named Bitstring / Unused bits #0
-test_asn1_write_bitstrings:"FF":8:"030200FF":4:1
+test_asn1_write_bitstrings:"FF":8:"030200FF":1
ASN.1 Write Named Bitstring / Unused bits #1
-test_asn1_write_bitstrings:"FE":8:"030201FE":4:1
+test_asn1_write_bitstrings:"FE":8:"030201FE":1
ASN.1 Write Named Bitstring / Unused bits #2
-test_asn1_write_bitstrings:"FC":7:"030202FC":4:1
+test_asn1_write_bitstrings:"FC":7:"030202FC":1
ASN.1 Write Named Bitstring / Unused bits #3
-test_asn1_write_bitstrings:"F8":8:"030203F8":4:1
+test_asn1_write_bitstrings:"F8":8:"030203F8":1
ASN.1 Write Named Bitstring / Unused bits #4
-test_asn1_write_bitstrings:"F0":6:"030204F0":4:1
+test_asn1_write_bitstrings:"F0":6:"030204F0":1
ASN.1 Write Named Bitstring / Unused bits #5
-test_asn1_write_bitstrings:"E0":6:"030205E0":4:1
+test_asn1_write_bitstrings:"E0":6:"030205E0":1
ASN.1 Write Named Bitstring / Unused bits #6
-test_asn1_write_bitstrings:"C0":8:"030206C0":4:1
+test_asn1_write_bitstrings:"C0":8:"030206C0":1
ASN.1 Write Named Bitstring / Unused bits #7
-test_asn1_write_bitstrings:"80":8:"03020780":4:1
+test_asn1_write_bitstrings:"80":8:"03020780":1
ASN.1 Write Named Bitstring / Empty bitstring
-test_asn1_write_bitstrings:"00":7:"030100":3:1
+test_asn1_write_bitstrings:"00":7:"030100":1
ASN.1 Write Named Bitstring / Empty bitstring (bits = 16)
-test_asn1_write_bitstrings:"0000":16:"030100":3:1
+test_asn1_write_bitstrings:"0000":16:"030100":1
ASN.1 Write Named Bitstring / Empty bitstring (bits = 24)
-test_asn1_write_bitstrings:"FFFFFF":0:"030100":3:1
+test_asn1_write_bitstrings:"FFFFFF":0:"030100":1
ASN.1 Write Named Bitstring / 15 trailing bits all unset
-test_asn1_write_bitstrings:"F88000":24:"030307F880":5:1
+test_asn1_write_bitstrings:"F88000":24:"030307F880":1
ASN.1 Write Named Bitstring / 15 trailing bits all set
-test_asn1_write_bitstrings:"F8FFFF":9:"030307F880":5:1
+test_asn1_write_bitstrings:"F8FFFF":9:"030307F880":1
ASN.1 Write Bitstring / Unused bits #0
-test_asn1_write_bitstrings:"FF":8:"030200FF":4:0
+test_asn1_write_bitstrings:"FF":8:"030200FF":0
ASN.1 Write Bitstring / Unused bits #1
-test_asn1_write_bitstrings:"FF":7:"030201FE":4:0
+test_asn1_write_bitstrings:"FF":7:"030201FE":0
ASN.1 Write Bitstring / Unused bits #2
-test_asn1_write_bitstrings:"FF":6:"030202FC":4:0
+test_asn1_write_bitstrings:"FF":6:"030202FC":0
ASN.1 Write Bitstring / Unused bits #3
-test_asn1_write_bitstrings:"FF":5:"030203F8":4:0
+test_asn1_write_bitstrings:"FF":5:"030203F8":0
ASN.1 Write Bitstring / Unused bits #4
-test_asn1_write_bitstrings:"FF":4:"030204F0":4:0
+test_asn1_write_bitstrings:"FF":4:"030204F0":0
ASN.1 Write Bitstring / Unused bits #5
-test_asn1_write_bitstrings:"FF":3:"030205E0":4:0
+test_asn1_write_bitstrings:"FF":3:"030205E0":0
ASN.1 Write Bitstring / Unused bits #6
-test_asn1_write_bitstrings:"FF":2:"030206C0":4:0
+test_asn1_write_bitstrings:"FF":2:"030206C0":0
ASN.1 Write Bitstring / Unused bits #7
-test_asn1_write_bitstrings:"FF":1:"03020780":4:0
+test_asn1_write_bitstrings:"FF":1:"03020780":0
ASN.1 Write Bitstring / 1 trailing bit (bits 15)
-test_asn1_write_bitstrings:"0003":15:"0303010002":5:0
+test_asn1_write_bitstrings:"0003":15:"0303010002":0
ASN.1 Write Bitstring / 0 bits
-test_asn1_write_bitstrings:"":0:"030100":3:0
+test_asn1_write_bitstrings:"":0:"030100":0
ASN.1 Write Bitstring / long string all bits unset except trailing bits
-test_asn1_write_bitstrings:"000000000007":45:"030703000000000000":9:0
+test_asn1_write_bitstrings:"000000000007":45:"030703000000000000":0
+
+Store named data: not found
+store_named_data_find:"414141":"424242":"434343":"444444":"7f7f7f":0:-1
+
+Store named data: empty haystack
+store_named_data_find:"414141":"424242":"434343":"444444":"7f7f7f":4:-1
+
+Store named data: first
+store_named_data_find:"414141":"424242":"434343":"444444":"414141":0:0
+
+Store named data: last
+store_named_data_find:"414141":"424242":"434343":"444444":"444444":0:3
+
+Store named data: skip suffix
+store_named_data_find:"41414141":"414141":"434343":"444444":"414141":0:1
+
+Store named data: skip prefix
+store_named_data_find:"4141":"414141":"434343":"444444":"414141":0:1
+
+Store named data: first match
+store_named_data_find:"414141":"414141":"434343":"444444":"414141":0:0
+
+Store named data: found, null to zero
+store_named_data_val_found:0:0
+
+Store named data: found, null to data
+store_named_data_val_found:0:9
+
+Store named data: found, data to zero
+store_named_data_val_found:9:0
+
+Store named data: found, smaller data
+store_named_data_val_found:9:2
+
+Store named data: found, same-size data
+store_named_data_val_found:9:9
+
+Store named data: found, larger data
+store_named_data_val_found:4:9
+
+Store named data: new, val_len=0
+store_named_data_val_new:0
+
+Store named data: new, val_len=4
+store_named_data_val_new:4
+
+Store named data: new, val_len=4, val=NULL
+store_named_data_val_new:-4
diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function
index e45583c..b69f6b5 100644
--- a/tests/suites/test_suite_asn1write.function
+++ b/tests/suites/test_suite_asn1write.function
@@ -3,6 +3,53 @@
#define GUARD_LEN 4
#define GUARD_VAL 0x2a
+
+typedef struct
+{
+ unsigned char *output;
+ unsigned char *start;
+ unsigned char *end;
+ unsigned char *p;
+ size_t size;
+} generic_write_data_t;
+
+int generic_write_start_step( generic_write_data_t *data )
+{
+ test_set_step( data->size );
+ ASSERT_ALLOC( data->output, data->size == 0 ? 1 : data->size );
+ data->end = data->output + data->size;
+ data->p = data->end;
+ data->start = data->end - data->size;
+ return( 1 );
+exit:
+ return( 0 );
+}
+
+int generic_write_finish_step( generic_write_data_t *data,
+ const data_t *expected, int ret )
+{
+ int ok = 0;
+
+ if( data->size < expected->len )
+ {
+ TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ }
+ else
+ {
+ TEST_EQUAL( ret, data->end - data->p );
+ TEST_ASSERT( data->p >= data->start );
+ TEST_ASSERT( data->p <= data->end );
+ ASSERT_COMPARE( data->p, (size_t)( data->end - data->p ),
+ expected->x, expected->len );
+ }
+ ok = 1;
+
+exit:
+ mbedtls_free( data->output );
+ data->output = NULL;
+ return( ok );
+}
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -11,74 +58,175 @@
*/
/* BEGIN_CASE */
-void mbedtls_asn1_write_octet_string( data_t * str, data_t * asn1,
- int buf_len, int result )
+void mbedtls_asn1_write_null( data_t *expected )
{
+ generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
int ret;
- unsigned char buf[150];
- size_t i;
- unsigned char *p;
- memset( buf, GUARD_VAL, sizeof( buf ) );
-
-
- p = buf + GUARD_LEN + buf_len;
-
- ret = mbedtls_asn1_write_octet_string( &p, buf + GUARD_LEN, str->x, str->len );
-
- /* Check for buffer overwrite on both sides */
- for( i = 0; i < GUARD_LEN; i++ )
+ for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
- TEST_ASSERT( buf[i] == GUARD_VAL );
- TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
+ if( ! generic_write_start_step( &data ) )
+ goto exit;
+ ret = mbedtls_asn1_write_null( &data.p, data.start );
+ if( ! generic_write_finish_step( &data, expected, ret ) )
+ goto exit;
}
- if( result >= 0 )
- {
- TEST_ASSERT( (size_t) ret == asn1->len );
- TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
-
- TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
- }
+exit:
+ mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE */
-void mbedtls_asn1_write_ia5_string( char * str, data_t * asn1,
- int buf_len, int result )
+void mbedtls_asn1_write_bool( int val, data_t *expected )
{
+ generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
int ret;
- unsigned char buf[150];
- size_t str_len;
- size_t i;
- unsigned char *p;
- memset( buf, GUARD_VAL, sizeof( buf ) );
-
- str_len = strlen( str );
-
- p = buf + GUARD_LEN + buf_len;
-
- ret = mbedtls_asn1_write_ia5_string( &p, buf + GUARD_LEN, str, str_len );
-
- /* Check for buffer overwrite on both sides */
- for( i = 0; i < GUARD_LEN; i++ )
+ for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
- TEST_ASSERT( buf[i] == GUARD_VAL );
- TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
+ if( ! generic_write_start_step( &data ) )
+ goto exit;
+ ret = mbedtls_asn1_write_bool( &data.p, data.start, val );
+ if( ! generic_write_finish_step( &data, expected, ret ) )
+ goto exit;
}
- if( result >= 0 )
- {
- TEST_ASSERT( (size_t) ret == asn1->len );
- TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
-
- TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
- }
+exit:
+ mbedtls_free( data.output );
}
/* END_CASE */
-/* BEGIN_CASE depends_on:MBEDTLS_ASN1PARSE_C */
+/* BEGIN_CASE */
+void mbedtls_asn1_write_int( int val, data_t *expected )
+{
+ generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
+ int ret;
+
+ for( data.size = 0; data.size < expected->len + 1; data.size++ )
+ {
+ if( ! generic_write_start_step( &data ) )
+ goto exit;
+ ret = mbedtls_asn1_write_int( &data.p, data.start, val );
+ if( ! generic_write_finish_step( &data, expected, ret ) )
+ goto exit;
+ }
+
+exit:
+ mbedtls_free( data.output );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
+void mbedtls_asn1_write_mpi( data_t *val, data_t *expected )
+{
+ generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
+ mbedtls_mpi mpi;
+ int ret;
+
+ mbedtls_mpi_init( &mpi );
+ TEST_ASSERT( mbedtls_mpi_read_binary( &mpi, val->x, val->len ) == 0 );
+
+ for( data.size = 0; data.size < expected->len + 1; data.size++ )
+ {
+ if( ! generic_write_start_step( &data ) )
+ goto exit;
+ ret = mbedtls_asn1_write_mpi( &data.p, data.start, &mpi );
+ if( ! generic_write_finish_step( &data, expected, ret ) )
+ goto exit;
+ if( expected->len > 10 && data.size == 8 )
+ data.size = expected->len - 2;
+ }
+
+exit:
+ mbedtls_mpi_free( &mpi );
+ mbedtls_free( data.output );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_asn1_write_string( int tag, data_t *content, data_t *expected )
+{
+ generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
+ int ret;
+
+ for( data.size = 0; data.size < expected->len + 1; data.size++ )
+ {
+ if( ! generic_write_start_step( &data ) )
+ goto exit;
+ switch( tag )
+ {
+ case MBEDTLS_ASN1_OCTET_STRING:
+ ret = mbedtls_asn1_write_octet_string(
+ &data.p, data.start, content->x, content->len );
+ break;
+ case MBEDTLS_ASN1_OID:
+ ret = mbedtls_asn1_write_oid(
+ &data.p, data.start,
+ (const char *) content->x, content->len );
+ break;
+ case MBEDTLS_ASN1_UTF8_STRING:
+ ret = mbedtls_asn1_write_utf8_string(
+ &data.p, data.start,
+ (const char *) content->x, content->len );
+ break;
+ case MBEDTLS_ASN1_PRINTABLE_STRING:
+ ret = mbedtls_asn1_write_printable_string(
+ &data.p, data.start,
+ (const char *) content->x, content->len );
+ break;
+ case MBEDTLS_ASN1_IA5_STRING:
+ ret = mbedtls_asn1_write_ia5_string(
+ &data.p, data.start,
+ (const char *) content->x, content->len );
+ break;
+ default:
+ ret = mbedtls_asn1_write_tagged_string(
+ &data.p, data.start, tag,
+ (const char *) content->x, content->len );
+ }
+ if( ! generic_write_finish_step( &data, expected, ret ) )
+ goto exit;
+ if( expected->len > 10 && data.size == 8 )
+ data.size = expected->len - 2;
+ }
+
+exit:
+ mbedtls_free( data.output );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_asn1_write_algorithm_identifier( data_t *oid,
+ int par_len,
+ data_t *expected )
+{
+ generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
+ int ret;
+
+ for( data.size = 0; data.size < expected->len + 1; data.size++ )
+ {
+ if( ! generic_write_start_step( &data ) )
+ goto exit;
+ ret = mbedtls_asn1_write_algorithm_identifier(
+ &data.p, data.start,
+ (const char *) oid->x, oid->len, par_len );
+ /* If params_len != 0, mbedtls_asn1_write_algorithm_identifier()
+ * assumes that the parameters are already present in the buffer
+ * and returns a length that accounts for this, but our test
+ * data omits the parameters. */
+ if( ret >= 0 )
+ ret -= par_len;
+ if( ! generic_write_finish_step( &data, expected, ret ) )
+ goto exit;
+ }
+
+exit:
+ mbedtls_free( data.output );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_C */
void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
int result )
{
@@ -131,44 +279,174 @@
/* BEGIN_CASE */
void test_asn1_write_bitstrings( data_t *bitstring, int bits,
- data_t *expected_asn1, int result,
- int is_named )
+ data_t *expected, int is_named )
{
+ generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
int ret;
- size_t i;
- unsigned char buf[150];
- unsigned char *p;
+ int ( *func )( unsigned char **p, unsigned char *start,
+ const unsigned char *buf, size_t bits ) =
+ ( is_named ? mbedtls_asn1_write_named_bitstring :
+ mbedtls_asn1_write_bitstring );
- memset( buf, GUARD_VAL, sizeof( buf ) );
-
- p = buf + GUARD_LEN + expected_asn1->len;
-
- if ( is_named == 0 )
+ for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
- ret = mbedtls_asn1_write_bitstring( &p,
- buf,
- (unsigned char *)bitstring->x,
- (size_t) bits );
+ if( ! generic_write_start_step( &data ) )
+ goto exit;
+ ret = ( *func )( &data.p, data.start, bitstring->x, bits );
+ if( ! generic_write_finish_step( &data, expected, ret ) )
+ goto exit;
+ }
+
+exit:
+ mbedtls_free( data.output );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void store_named_data_find( data_t *oid0, data_t *oid1,
+ data_t *oid2, data_t *oid3,
+ data_t *needle, int from, int position )
+{
+ data_t *oid[4] = {oid0, oid1, oid2, oid3};
+ mbedtls_asn1_named_data nd[] ={
+ { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
+ { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
+ { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
+ { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
+ };
+ mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
+ size_t i;
+ mbedtls_asn1_named_data *head = NULL;
+ mbedtls_asn1_named_data *found = NULL;
+
+ for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
+ pointers[i] = &nd[i];
+ pointers[ARRAY_LENGTH( nd )] = NULL;
+ for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
+ {
+ ASSERT_ALLOC( nd[i].oid.p, oid[i]->len );
+ memcpy( nd[i].oid.p, oid[i]->x, oid[i]->len );
+ nd[i].oid.len = oid[i]->len;
+ nd[i].next = pointers[i+1];
+ }
+
+ head = pointers[from];
+ found = mbedtls_asn1_store_named_data( &head,
+ (const char *) needle->x,
+ needle->len,
+ NULL, 0 );
+
+ /* In any case, the existing list structure must be unchanged. */
+ for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
+ TEST_ASSERT( nd[i].next == pointers[i+1] );
+
+ if( position >= 0 )
+ {
+ /* position should have been found and modified. */
+ TEST_ASSERT( head == pointers[from] );
+ TEST_ASSERT( found == pointers[position] );
}
else
{
- ret = mbedtls_asn1_write_named_bitstring( &p,
- buf,
- (unsigned char *)bitstring->x,
- (size_t) bits );
- }
- TEST_ASSERT( ret == result );
-
- /* Check for buffer overwrite on both sides */
- for( i = 0; i < GUARD_LEN; i++ )
- {
- TEST_ASSERT( buf[i] == GUARD_VAL );
- TEST_ASSERT( buf[GUARD_LEN + expected_asn1->len + i] == GUARD_VAL );
+ /* A new entry should have been created. */
+ TEST_ASSERT( found == head );
+ TEST_ASSERT( head->next == pointers[from] );
+ for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
+ TEST_ASSERT( found != &nd[i] );
}
- if ( result >= 0 )
+exit:
+ if( found != NULL && found == head && found != pointers[from] )
{
- TEST_ASSERT( memcmp( p, expected_asn1->x, expected_asn1->len ) == 0 );
+ mbedtls_free( found->oid.p );
+ mbedtls_free( found );
}
+ for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
+ mbedtls_free( nd[i].oid.p );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void store_named_data_val_found( int old_len, int new_len )
+{
+ mbedtls_asn1_named_data nd =
+ { {0x06, 3, (unsigned char *) "OID"}, {0, 0, NULL}, NULL, 0 };
+ mbedtls_asn1_named_data *head = &nd;
+ mbedtls_asn1_named_data *found = NULL;
+ unsigned char *old_val = NULL;
+ unsigned char *new_val = (unsigned char *) "new value";
+
+ if( old_len != 0 )
+ {
+ ASSERT_ALLOC( nd.val.p, (size_t) old_len );
+ old_val = nd.val.p;
+ nd.val.len = old_len;
+ memset( old_val, 'x', old_len );
+ }
+ if( new_len <= 0 )
+ {
+ new_len = - new_len;
+ new_val = NULL;
+ }
+
+ found = mbedtls_asn1_store_named_data( &head, "OID", 3,
+ new_val, new_len );
+ TEST_ASSERT( head == &nd );
+ TEST_ASSERT( found == head );
+
+ if( new_val != NULL)
+ ASSERT_COMPARE( found->val.p, found->val.len,
+ new_val, (size_t) new_len );
+ if( new_len == 0)
+ TEST_ASSERT( found->val.p == NULL );
+ else if( new_len == old_len )
+ TEST_ASSERT( found->val.p == old_val );
+ else
+ TEST_ASSERT( found->val.p != old_val );
+
+exit:
+ mbedtls_free( nd.val.p );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void store_named_data_val_new( int new_len )
+{
+ mbedtls_asn1_named_data *head = NULL;
+ mbedtls_asn1_named_data *found = NULL;
+ const unsigned char *oid = (unsigned char *) "OID";
+ size_t oid_len = strlen( (const char *) oid );
+ const unsigned char *new_val = (unsigned char *) "new value";
+
+ if( new_len <= 0 )
+ new_val = NULL;
+ if( new_len < 0 )
+ new_len = - new_len;
+
+ found = mbedtls_asn1_store_named_data( &head,
+ (const char *) oid, oid_len,
+ new_val, (size_t) new_len );
+ TEST_ASSERT( found != NULL );
+ TEST_ASSERT( found == head );
+ TEST_ASSERT( found->oid.p != oid );
+ ASSERT_COMPARE( found->oid.p, found->oid.len, oid, oid_len );
+ if( new_len == 0 )
+ TEST_ASSERT( found->val.p == NULL );
+ else if( new_val == NULL )
+ TEST_ASSERT( found->val.p != NULL );
+ else
+ {
+ TEST_ASSERT( found->val.p != new_val );
+ ASSERT_COMPARE( found->val.p, found->val.len,
+ new_val, (size_t) new_len );
+ }
+
+exit:
+ if( found != NULL )
+ {
+ mbedtls_free( found->oid.p );
+ mbedtls_free( found->val.p );
+ }
+ mbedtls_free( found );
}
/* END_CASE */
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 162cb56..b349075 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -664,7 +664,7 @@
char * input_E, data_t * result_str,
int result )
{
- unsigned char hash_result[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
mbedtls_pk_restart_ctx *rs_ctx = NULL;
@@ -679,7 +679,7 @@
mbedtls_pk_init( &pk );
- memset( hash_result, 0x00, 1000 );
+ memset( hash_result, 0x00, MBEDTLS_MD_MAX_SIZE );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
rsa = mbedtls_pk_rsa( pk );
@@ -713,7 +713,7 @@
data_t * result_str, int pk_type,
int mgf1_hash_id, int salt_len, int result )
{
- unsigned char hash_result[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
mbedtls_pk_rsassa_pss_options pss_opts;
@@ -722,7 +722,7 @@
mbedtls_pk_init( &pk );
- memset( hash_result, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
rsa = mbedtls_pk_rsa( pk );
@@ -976,7 +976,7 @@
char * input_N, int radix_E, char * input_E,
data_t * result, int ret )
{
- unsigned char output[1000];
+ unsigned char output[300];
rnd_pseudo_info rnd_info;
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
@@ -1011,7 +1011,7 @@
int radix_N, char * input_N, int radix_E,
char * input_E, data_t * clear, int ret )
{
- unsigned char output[1000];
+ unsigned char output[256];
rnd_pseudo_info rnd_info;
mbedtls_mpi N, P, Q, E;
mbedtls_rsa_context *rsa;
@@ -1136,8 +1136,8 @@
mbedtls_rsa_context raw;
mbedtls_pk_context rsa, alt;
mbedtls_pk_debug_item dbg_items[10];
- unsigned char hash[50], sig[1000];
- unsigned char msg[50], ciph[1000], test[1000];
+ unsigned char hash[50], sig[64];
+ unsigned char msg[50], ciph[64], test[50];
size_t sig_len, ciph_len, test_len;
int ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
index 3ef4e2c..13fdf58 100644
--- a/tests/suites/test_suite_pkcs1_v15.function
+++ b/tests/suites/test_suite_pkcs1_v15.function
@@ -14,7 +14,7 @@
data_t * message_str, data_t * rnd_buf,
data_t * result_hex_str, int result )
{
- unsigned char output[1000];
+ unsigned char output[128];
mbedtls_rsa_context ctx;
rnd_buf_info info;
mbedtls_mpi N, E;
@@ -24,7 +24,7 @@
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
@@ -54,7 +54,7 @@
char * seed, data_t * message_str,
int result )
{
- unsigned char output[1000];
+ unsigned char output[128];
mbedtls_rsa_context ctx;
size_t output_len;
rnd_pseudo_info rnd_info;
@@ -65,7 +65,7 @@
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
@@ -253,8 +253,8 @@
data_t * message_str, data_t * rnd_buf,
data_t * result_hex_str, int result )
{
- unsigned char hash_result[1000];
- unsigned char output[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+ unsigned char output[128];
mbedtls_rsa_context ctx;
mbedtls_mpi N, P, Q, E;
rnd_buf_info info;
@@ -266,8 +266,8 @@
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
- memset( hash_result, 0x00, 1000 );
- memset( output, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
@@ -303,14 +303,14 @@
int hash, data_t * message_str, char * salt,
data_t * result_str, int result )
{
- unsigned char hash_result[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
mbedtls_rsa_context ctx;
mbedtls_mpi N, E;
((void) salt);
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
- memset( hash_result, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
diff --git a/tests/suites/test_suite_pkcs1_v21.function b/tests/suites/test_suite_pkcs1_v21.function
index 180bc4a..7b8087b 100644
--- a/tests/suites/test_suite_pkcs1_v21.function
+++ b/tests/suites/test_suite_pkcs1_v21.function
@@ -14,7 +14,7 @@
data_t * message_str, data_t * rnd_buf,
data_t * result_hex_str, int result )
{
- unsigned char output[1000];
+ unsigned char output[256];
mbedtls_rsa_context ctx;
rnd_buf_info info;
mbedtls_mpi N, E;
@@ -24,7 +24,7 @@
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
@@ -54,7 +54,7 @@
char * seed, data_t * message_str,
int result )
{
- unsigned char output[1000];
+ unsigned char output[64];
mbedtls_rsa_context ctx;
size_t output_len;
rnd_pseudo_info rnd_info;
@@ -66,7 +66,7 @@
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
@@ -81,11 +81,16 @@
if( result_hex_str->len == 0 )
{
- TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx, &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE, &output_len, message_str->x, NULL, 0 ) == result );
+ TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx, &rnd_pseudo_rand, &rnd_info,
+ MBEDTLS_RSA_PRIVATE, &output_len,
+ message_str->x, NULL, 0 ) == result );
}
else
{
- TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx, &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE, &output_len, message_str->x, output, 1000 ) == result );
+ TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx, &rnd_pseudo_rand, &rnd_info,
+ MBEDTLS_RSA_PRIVATE, &output_len,
+ message_str->x, output,
+ sizeof( output ) ) == result );
if( result == 0 )
{
TEST_ASSERT( hexcmp( output, result_hex_str->x, output_len, result_hex_str->len ) == 0 );
@@ -106,8 +111,8 @@
data_t * message_str, data_t * rnd_buf,
data_t * result_hex_str, int result )
{
- unsigned char hash_result[1000];
- unsigned char output[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+ unsigned char output[256];
mbedtls_rsa_context ctx;
rnd_buf_info info;
mbedtls_mpi N, P, Q, E;
@@ -119,8 +124,8 @@
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash );
- memset( hash_result, 0x00, 1000 );
- memset( output, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
@@ -157,14 +162,14 @@
int hash, data_t * message_str, char * salt,
data_t * result_str, int result )
{
- unsigned char hash_result[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
mbedtls_rsa_context ctx;
mbedtls_mpi N, E;
((void) salt);
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash );
- memset( hash_result, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
@@ -194,14 +199,14 @@
data_t * result_str, int result_simple,
int result_full )
{
- unsigned char hash_result[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
mbedtls_rsa_context ctx;
size_t hash_len;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, ctx_hash );
- memset( hash_result, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.data b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
index 53e3fc5..1b0ef04 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
@@ -121,23 +121,23 @@
generate_key_smoke:PSA_KEY_TYPE_HMAC:256:PSA_ALG_HMAC( PSA_ALG_SHA_256 )
Key registration: smoke test
-register_key_smoke_test:MIN_DRIVER_LIFETIME:-1:PSA_SUCCESS
-
-Key registration: invalid lifetime (volatile)
-register_key_smoke_test:PSA_KEY_LIFETIME_VOLATILE:-1:PSA_ERROR_INVALID_ARGUMENT
-
-Key registration: invalid lifetime (internal storage)
-register_key_smoke_test:PSA_KEY_LIFETIME_PERSISTENT:-1:PSA_ERROR_INVALID_ARGUMENT
-
-Key registration: invalid lifetime (no registered driver)
-register_key_smoke_test:MIN_DRIVER_LIFETIME + 1:-1:PSA_ERROR_INVALID_ARGUMENT
-
-Key registration: with driver validation (accepted)
register_key_smoke_test:MIN_DRIVER_LIFETIME:1:PSA_SUCCESS
-Key registration: with driver validation (rejected)
+Key registration: invalid lifetime (volatile)
+register_key_smoke_test:PSA_KEY_LIFETIME_VOLATILE:1:PSA_ERROR_INVALID_ARGUMENT
+
+Key registration: invalid lifetime (internal storage)
+register_key_smoke_test:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_INVALID_ARGUMENT
+
+Key registration: invalid lifetime (no registered driver)
+register_key_smoke_test:MIN_DRIVER_LIFETIME + 1:1:PSA_ERROR_INVALID_ARGUMENT
+
+Key registration: rejected
register_key_smoke_test:MIN_DRIVER_LIFETIME:0:PSA_ERROR_NOT_PERMITTED
+Key registration: not supported
+register_key_smoke_test:MIN_DRIVER_LIFETIME:-1:PSA_ERROR_NOT_SUPPORTED
+
Import-sign-verify: sign in driver, ECDSA
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
sign_verify:SIGN_IN_DRIVER_AND_PARALLEL_CREATION:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDSA_ANY:0:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
index fc6f668..61fb918 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -5,6 +5,13 @@
#include "psa_crypto_se.h"
#include "psa_crypto_storage.h"
+/* Invasive peeking: check the persistent data */
+#if defined(MBEDTLS_PSA_ITS_FILE_C)
+#include "psa_crypto_its.h"
+#else /* Native ITS implementation */
+#include "psa/error.h"
+#include "psa/internal_trusted_storage.h"
+#endif
/****************************************************************/
@@ -90,11 +97,13 @@
/* Validate a choice of slot number as directed. */
static psa_status_t validate_slot_number_as_directed(
psa_drv_se_context_t *context,
+ void *persistent_data,
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_key_slot_number_t slot_number )
{
(void) context;
+ (void) persistent_data;
(void) attributes;
DRIVER_ASSERT_RETURN( slot_number ==
validate_slot_number_directions.slot_number );
@@ -104,6 +113,11 @@
}
/* Allocate slot numbers with a monotonic counter. */
+static psa_key_slot_number_t shadow_counter;
+static void counter_reset( void )
+{
+ shadow_counter = 0;
+}
static psa_status_t counter_allocate( psa_drv_se_context_t *context,
void *persistent_data,
const psa_key_attributes_t *attributes,
@@ -118,6 +132,7 @@
++*p_counter;
if( *p_counter == 0 )
return( PSA_ERROR_INSUFFICIENT_STORAGE );
+ shadow_counter = *p_counter;
*slot_number = *p_counter;
return( PSA_SUCCESS );
}
@@ -193,12 +208,15 @@
* bit vector indicating which slots are in use. */
typedef uint16_t ram_slot_usage_t;
+static ram_slot_usage_t ram_shadow_slot_usage;
+
static uint8_t ram_min_slot = 0;
static void ram_slots_reset( void )
{
memset( ram_slots, 0, sizeof( ram_slots ) );
ram_min_slot = 0;
+ ram_shadow_slot_usage = 0;
}
/* Common parts of key creation.
@@ -342,6 +360,7 @@
DRIVER_ASSERT_RETURN( slot_number < ARRAY_LENGTH( ram_slots ) );
memset( &ram_slots[slot_number], 0, sizeof( ram_slots[slot_number] ) );
*slot_usage &= ~(ram_slot_usage_t)( 1 << slot_number );
+ ram_shadow_slot_usage = *slot_usage;
return( PSA_SUCCESS );
}
@@ -360,18 +379,23 @@
++( *slot_number ) )
{
if( ! ( *slot_usage & 1 << *slot_number ) )
+ {
+ ram_shadow_slot_usage = *slot_usage;
return( PSA_SUCCESS );
+ }
}
return( PSA_ERROR_INSUFFICIENT_STORAGE );
}
static psa_status_t ram_validate_slot_number(
psa_drv_se_context_t *context,
+ void *persistent_data,
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_key_slot_number_t slot_number )
{
(void) context;
+ (void) persistent_data;
(void) attributes;
(void) method;
if( slot_number >= ARRAY_LENGTH( ram_slots ) )
@@ -522,6 +546,37 @@
return( ok );
}
+/* Get the file UID corresponding to the specified lifetime.
+ * If this changes, the storage format version must change.
+ * See psa_get_se_driver_its_file_uid() in psa_crypto_se.c.
+ */
+psa_storage_uid_t file_uid_for_lifetime( psa_key_lifetime_t lifetime )
+{
+ if( lifetime > PSA_MAX_SE_LIFETIME )
+ return( 0 );
+ return( 0xfffffe00 + lifetime );
+}
+
+/* Check that the persistent data of a driver has its expected content. */
+static int check_persistent_data( psa_key_lifetime_t lifetime,
+ const void *expected_data,
+ size_t size )
+{
+ psa_storage_uid_t uid = file_uid_for_lifetime( lifetime );
+ struct psa_storage_info_t info;
+ uint8_t *loaded = NULL;
+
+ PSA_ASSERT( psa_its_get_info( uid, &info ) );
+ ASSERT_ALLOC( loaded, info.size );
+ PSA_ASSERT( psa_its_get( uid, 0, info.size, loaded, NULL ) );
+ ASSERT_COMPARE( expected_data, size, loaded, info.size );
+ return( 1 );
+
+exit:
+ mbedtls_free( loaded );
+ return( 0 );
+}
+
/* Check that a function's return status is "smoke-free", i.e. that
* it's an acceptable error code when calling an API function that operates
* on a key with potentially bogus parameters. */
@@ -776,6 +831,10 @@
PSA_ASSERT( psa_import_key( &attributes,
key_material, sizeof( key_material ),
&handle ) );
+ if( ! check_persistent_data( lifetime,
+ &ram_shadow_slot_usage,
+ sizeof( ram_shadow_slot_usage ) ) )
+ goto exit;
/* Maybe restart, to check that the information is saved correctly. */
if( restart )
@@ -783,6 +842,10 @@
mbedtls_psa_crypto_free( );
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
PSA_ASSERT( psa_crypto_init( ) );
+ if( ! check_persistent_data( lifetime,
+ &ram_shadow_slot_usage,
+ sizeof( ram_shadow_slot_usage ) ) )
+ goto exit;
PSA_ASSERT( psa_open_key( id, &handle ) );
}
@@ -805,6 +868,10 @@
PSA_ASSERT( psa_destroy_key( handle ) );
handle = 0;
+ if( ! check_persistent_data( lifetime,
+ &ram_shadow_slot_usage,
+ sizeof( ram_shadow_slot_usage ) ) )
+ goto exit;
TEST_EQUAL( psa_open_key( id, &handle ),
PSA_ERROR_DOES_NOT_EXIST );
@@ -860,6 +927,10 @@
if( status != PSA_SUCCESS )
goto exit;
+ if( ! check_persistent_data( lifetime,
+ &ram_shadow_slot_usage,
+ sizeof( ram_shadow_slot_usage ) ) )
+ goto exit;
/* Maybe restart, to check that the information is saved correctly. */
if( restart )
@@ -867,6 +938,10 @@
mbedtls_psa_crypto_free( );
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
PSA_ASSERT( psa_crypto_init( ) );
+ if( ! check_persistent_data( lifetime,
+ &ram_shadow_slot_usage,
+ sizeof( ram_shadow_slot_usage ) ) )
+ goto exit;
PSA_ASSERT( psa_open_key( id, &handle ) );
}
@@ -879,6 +954,10 @@
PSA_ASSERT( psa_destroy_key( handle ) );
handle = 0;
+ if( ! check_persistent_data( lifetime,
+ &ram_shadow_slot_usage,
+ sizeof( ram_shadow_slot_usage ) ) )
+ goto exit;
TEST_EQUAL( psa_open_key( id, &handle ),
PSA_ERROR_DOES_NOT_EXIST );
@@ -926,6 +1005,9 @@
PSA_ASSERT( psa_import_key( &attributes,
key_material->x, key_material->len,
&handle ) );
+ if( ! check_persistent_data( lifetime,
+ &shadow_counter, sizeof( shadow_counter ) ) )
+ goto exit;
/* Do stuff with the key. */
if( ! smoke_test_key( handle ) )
@@ -935,6 +1017,9 @@
mbedtls_psa_crypto_free( );
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
PSA_ASSERT( psa_crypto_init( ) );
+ if( ! check_persistent_data( lifetime,
+ &shadow_counter, sizeof( shadow_counter ) ) )
+ goto exit;
PSA_ASSERT( psa_open_key( id, &handle ) );
if( ! smoke_test_key( handle ) )
goto exit;
@@ -942,11 +1027,15 @@
/* We're done. */
PSA_ASSERT( psa_destroy_key( handle ) );
handle = 0;
+ if( ! check_persistent_data( lifetime,
+ &shadow_counter, sizeof( shadow_counter ) ) )
+ goto exit;
TEST_EQUAL( psa_open_key( id, &handle ),
PSA_ERROR_DOES_NOT_EXIST );
exit:
PSA_DONE( );
+ counter_reset( );
psa_purge_storage( );
}
/* END_CASE */
@@ -983,6 +1072,7 @@
exit:
PSA_DONE( );
+ counter_reset( );
psa_purge_storage( );
}
/* END_CASE */
@@ -1023,6 +1113,9 @@
psa_set_key_type( &attributes, type );
psa_set_key_bits( &attributes, bits );
PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
+ if( ! check_persistent_data( lifetime,
+ &shadow_counter, sizeof( shadow_counter ) ) )
+ goto exit;
/* Do stuff with the key. */
if( ! smoke_test_key( handle ) )
@@ -1032,6 +1125,9 @@
mbedtls_psa_crypto_free( );
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
PSA_ASSERT( psa_crypto_init( ) );
+ if( ! check_persistent_data( lifetime,
+ &shadow_counter, sizeof( shadow_counter ) ) )
+ goto exit;
PSA_ASSERT( psa_open_key( id, &handle ) );
if( ! smoke_test_key( handle ) )
goto exit;
@@ -1039,11 +1135,15 @@
/* We're done. */
PSA_ASSERT( psa_destroy_key( handle ) );
handle = 0;
+ if( ! check_persistent_data( lifetime,
+ &shadow_counter, sizeof( shadow_counter ) ) )
+ goto exit;
TEST_EQUAL( psa_open_key( id, &handle ),
PSA_ERROR_DOES_NOT_EXIST );
exit:
PSA_DONE( );
+ counter_reset( );
psa_purge_storage( );
}
/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data
index dba6875..f60bd76 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data
@@ -1,3 +1,12 @@
+SE init mock test: success
+mock_init:2:PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS:1
+
+SE init mock test: failure
+mock_init:2:PSA_SUCCESS:PSA_ERROR_HARDWARE_FAILURE:PSA_ERROR_HARDWARE_FAILURE:1
+
+SE init mock test: invalid lifetime
+mock_init:1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_BAD_STATE:PSA_SUCCESS:0
+
SE key importing mock test
mock_import:PSA_SUCCESS:PSA_SUCCESS:0:PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
index e6b3f7b..7088a52 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
@@ -8,6 +8,13 @@
static struct
{
uint16_t called;
+ psa_key_lifetime_t lifetime;
+ psa_status_t return_value;
+} mock_init_data;
+
+static struct
+{
+ uint16_t called;
psa_key_slot_number_t key_slot;
psa_key_attributes_t attributes;
size_t pubkey_size;
@@ -92,6 +99,7 @@
static void mock_teardown( void )
{
+ memset( &mock_init_data, 0, sizeof( mock_init_data ) );
memset( &mock_import_data, 0, sizeof( mock_import_data ) );
memset( &mock_export_data, 0, sizeof( mock_export_data ) );
memset( &mock_export_public_data, 0, sizeof( mock_export_public_data ) );
@@ -103,6 +111,18 @@
psa_purge_storage( );
}
+static psa_status_t mock_init( psa_drv_se_context_t *drv_context,
+ void *persistent_data,
+ psa_key_lifetime_t lifetime )
+{
+ (void) drv_context;
+ (void) persistent_data;
+
+ mock_init_data.called++;
+ mock_init_data.lifetime = lifetime;
+ return( mock_init_data.return_value );
+}
+
static psa_status_t mock_generate( psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
const psa_key_attributes_t *attributes,
@@ -259,6 +279,42 @@
*/
/* BEGIN_CASE */
+void mock_init( int lifetime_arg,
+ int expected_register_status_arg,
+ int driver_status_arg,
+ int expected_psa_status_arg,
+ int expected_called )
+{
+ psa_key_lifetime_t lifetime = lifetime_arg;
+ psa_status_t expected_register_status = expected_register_status_arg;
+ psa_status_t driver_status = driver_status_arg;
+ psa_status_t expected_psa_status = expected_psa_status_arg;
+ psa_drv_se_t driver = {
+ .hal_version = PSA_DRV_SE_HAL_VERSION,
+ .p_init = mock_init,
+ };
+ int psa_crypto_init_called = 0;
+
+ mock_init_data.return_value = driver_status;
+
+ TEST_EQUAL( psa_register_se_driver( lifetime, &driver ),
+ expected_register_status );
+
+ psa_crypto_init_called = 1;
+ TEST_EQUAL( psa_crypto_init( ), expected_psa_status );
+
+ TEST_EQUAL( mock_init_data.called, expected_called );
+ if( expected_called )
+ TEST_EQUAL( mock_init_data.lifetime, lifetime );
+
+exit:
+ if( psa_crypto_init_called )
+ PSA_DONE( );
+ mock_teardown( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mock_import( int mock_alloc_return_value,
int mock_import_return_value,
int bits,
@@ -335,6 +391,7 @@
memset( &key_management, 0, sizeof( key_management ) );
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
driver.key_management = &key_management;
+ driver.p_init = mock_init;
key_management.p_import = mock_import;
key_management.p_export = mock_export;
key_management.p_destroy = mock_destroy;
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index 20789e6..3307849 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -272,7 +272,7 @@
RSA PKCS1 Decrypt #1 (Verify)
depends_on:MBEDTLS_PKCS1_V15
-mbedtls_rsa_pkcs1_decrypt:"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":MBEDTLS_RSA_PKCS_V15:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":1000:"4E636AF98E40F3ADCFCCB698F4E80B9F":0
+mbedtls_rsa_pkcs1_decrypt:"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":MBEDTLS_RSA_PKCS_V15:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":32:"4E636AF98E40F3ADCFCCB698F4E80B9F":0
RSA PKCS1 Encrypt #2 (Data too large)
depends_on:MBEDTLS_PKCS1_V15
@@ -280,7 +280,7 @@
RSA PKCS1 Decrypt #2 (Data too small)
depends_on:MBEDTLS_PKCS1_V15
-mbedtls_rsa_pkcs1_decrypt:"deadbeafcafedeadbeeffedcba9876":MBEDTLS_RSA_PKCS_V15:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":1000:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_ERR_RSA_PRIVATE_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+mbedtls_rsa_pkcs1_decrypt:"deadbeafcafedeadbeeffedcba9876":MBEDTLS_RSA_PKCS_V15:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":32:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_ERR_RSA_PRIVATE_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
RSA PKCS1 Decrypt #4 (Output buffer too small)
depends_on:MBEDTLS_PKCS1_V15
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index 89c84e8..d4acc2d 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -472,8 +472,8 @@
char * input_N, int radix_E, char * input_E,
data_t * result_hex_str, int result )
{
- unsigned char hash_result[1000];
- unsigned char output[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+ unsigned char output[256];
mbedtls_rsa_context ctx;
mbedtls_mpi N, P, Q, E;
rnd_pseudo_info rnd_info;
@@ -482,8 +482,8 @@
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
- memset( hash_result, 0x00, 1000 );
- memset( output, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
+ memset( output, 0x00, sizeof( output ) );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
@@ -522,14 +522,14 @@
char * input_N, int radix_E, char * input_E,
data_t * result_str, int result )
{
- unsigned char hash_result[1000];
+ unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
mbedtls_rsa_context ctx;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
- memset( hash_result, 0x00, 1000 );
+ memset( hash_result, 0x00, sizeof( hash_result ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
@@ -557,7 +557,7 @@
int radix_N, char * input_N, int radix_E,
char * input_E, data_t * result_hex_str )
{
- unsigned char output[1000];
+ unsigned char output[256];
mbedtls_rsa_context ctx;
mbedtls_mpi N, P, Q, E;
rnd_pseudo_info rnd_info;
@@ -566,7 +566,7 @@
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
@@ -593,7 +593,7 @@
if( padding_mode == MBEDTLS_RSA_PKCS_V15 )
{
int res;
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output) );
res = mbedtls_rsa_rsaes_pkcs1_v15_encrypt( &ctx,
&rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE,
@@ -627,7 +627,7 @@
char * input_N, int radix_E, char * input_E,
data_t * result_str, int correct )
{
- unsigned char output[1000];
+ unsigned char output[256];
mbedtls_rsa_context ctx;
mbedtls_mpi N, E;
@@ -688,7 +688,7 @@
int radix_E, char * input_E,
data_t * result_hex_str, int result )
{
- unsigned char output[1000];
+ unsigned char output[256];
mbedtls_rsa_context ctx;
rnd_pseudo_info rnd_info;
@@ -698,7 +698,7 @@
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
@@ -729,14 +729,14 @@
int radix_E, char * input_E,
data_t * result_hex_str, int result )
{
- unsigned char output[1000];
+ unsigned char output[256];
mbedtls_rsa_context ctx;
mbedtls_mpi N, E;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, padding_mode, 0 );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
@@ -769,7 +769,7 @@
int max_output, data_t * result_hex_str,
int result )
{
- unsigned char output[1000];
+ unsigned char output[32];
mbedtls_rsa_context ctx;
size_t output_len;
rnd_pseudo_info rnd_info;
@@ -780,7 +780,7 @@
mbedtls_rsa_init( &ctx, padding_mode, 0 );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
@@ -815,7 +815,7 @@
char * input_N, int radix_E, char * input_E,
data_t * result_hex_str, int result )
{
- unsigned char output[1000];
+ unsigned char output[256];
mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
mbedtls_mpi N, E;
@@ -823,7 +823,7 @@
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 );
mbedtls_rsa_init( &ctx2, MBEDTLS_RSA_PKCS_V15, 0 );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
@@ -847,7 +847,7 @@
TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx2 ) == 0 );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_rsa_public( &ctx2, message_str->x, output ) == result );
if( result == 0 )
{
@@ -869,7 +869,7 @@
char * input_E, data_t * result_hex_str,
int result )
{
- unsigned char output[1000];
+ unsigned char output[256];
mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
mbedtls_mpi N, P, Q, E;
rnd_pseudo_info rnd_info;
@@ -896,7 +896,7 @@
/* repeat three times to test updating of blinding values */
for( i = 0; i < 3; i++ )
{
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_rsa_private( &ctx, rnd_pseudo_rand, &rnd_info,
message_str->x, output ) == result );
if( result == 0 )
@@ -913,7 +913,7 @@
TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx2 ) == 0 );
- memset( output, 0x00, 1000 );
+ memset( output, 0x00, sizeof( output ) );
TEST_ASSERT( mbedtls_rsa_private( &ctx2, rnd_pseudo_rand, &rnd_info,
message_str->x, output ) == result );
if( result == 0 )
@@ -1577,11 +1577,11 @@
int successive )
{
/* Exported buffers */
- unsigned char bufNe[1000];
- unsigned char bufPe[1000];
- unsigned char bufQe[1000];
- unsigned char bufDe[1000];
- unsigned char bufEe[1000];
+ unsigned char bufNe[256];
+ unsigned char bufPe[128];
+ unsigned char bufQe[128];
+ unsigned char bufDe[256];
+ unsigned char bufEe[1];
mbedtls_rsa_context ctx;