Infineon: Add cyw20829 platform, shared slot feature, json memory map, psoc6 xip

Based in 1.8.0 release of MCUBoot library

This commit adds CYW20829 Infineon platform support with following capabilities:
1. Overwrite and swap upgrade mode support
2. Multi-image with up to 4 images
3. Hardware security counter is supported for CYW20829 platform

Add XIP support for PSOC6 platform - place BOOT slot in external memory and execute it in place using SMIF in XIP mode

and some new features for Infineon devices.

1. Shared upgrade slot feature - use one shared area for upgrade slots of multiple images
2. Memory map defined using JSON file - define memory regions for bootloader and user app in conventional way using JSON file
diff --git a/ext/mbedtls-asn1/include/mbedtls/asn1.h b/ext/mbedtls-asn1/include/mbedtls/asn1.h
index 96c1c9a..4668581 100644
--- a/ext/mbedtls-asn1/include/mbedtls/asn1.h
+++ b/ext/mbedtls-asn1/include/mbedtls/asn1.h
@@ -4,7 +4,7 @@
  * \brief Generic ASN.1 parsing
  */
 /*
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Copyright The Mbed TLS Contributors
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,22 +18,17 @@
  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
- *
- *  This file is part of mbed TLS (https://tls.mbed.org)
  */
 #ifndef MBEDTLS_ASN1_H
 #define MBEDTLS_ASN1_H
+#include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
 #if defined(MBEDTLS_BIGNUM_C)
-#include "bignum.h"
+#include "mbedtls/bignum.h"
 #endif
 
 /**
@@ -52,7 +47,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. */
 
@@ -75,6 +70,7 @@
 #define MBEDTLS_ASN1_OCTET_STRING            0x04
 #define MBEDTLS_ASN1_NULL                    0x05
 #define MBEDTLS_ASN1_OID                     0x06
+#define MBEDTLS_ASN1_ENUMERATED              0x0A
 #define MBEDTLS_ASN1_UTF8_STRING             0x0C
 #define MBEDTLS_ASN1_SEQUENCE                0x10
 #define MBEDTLS_ASN1_SET                     0x11
@@ -89,6 +85,18 @@
 #define MBEDTLS_ASN1_CONSTRUCTED             0x20
 #define MBEDTLS_ASN1_CONTEXT_SPECIFIC        0x80
 
+/* Slightly smaller way to check if tag is a string tag
+ * compared to canonical implementation. */
+#define MBEDTLS_ASN1_IS_STRING_TAG( tag )                                     \
+    ( ( tag ) < 32u && (                                                      \
+        ( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING )       |     \
+                                ( 1u << MBEDTLS_ASN1_UTF8_STRING )      |     \
+                                ( 1u << MBEDTLS_ASN1_T61_STRING )       |     \
+                                ( 1u << MBEDTLS_ASN1_IA5_STRING )       |     \
+                                ( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) |     \
+                                ( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) |     \
+                                ( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) )
+
 /*
  * Bit masks for each of the components of an ASN.1 tag as specified in
  * ITU X.690 (08/2015), section 8.1 "General rules for encoding",
@@ -119,6 +127,10 @@
         ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) ||                \
           memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
 
+#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len)              \
+        ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) ||             \
+          memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -133,9 +145,9 @@
  */
 typedef struct mbedtls_asn1_buf
 {
-    int tag;                /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
-    size_t len;             /**< ASN1 length, in octets. */
-    unsigned char *p;       /**< ASN1 data, e.g. in ASCII. */
+    int MBEDTLS_PRIVATE(tag);                /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
+    size_t MBEDTLS_PRIVATE(len);             /**< ASN1 length, in octets. */
+    unsigned char *MBEDTLS_PRIVATE(p);       /**< ASN1 data, e.g. in ASCII. */
 }
 mbedtls_asn1_buf;
 
@@ -144,9 +156,9 @@
  */
 typedef struct mbedtls_asn1_bitstring
 {
-    size_t len;                 /**< ASN1 length, in octets. */
-    unsigned char unused_bits;  /**< Number of unused bits at the end of the string */
-    unsigned char *p;           /**< Raw ASN1 data for the bit string */
+    size_t MBEDTLS_PRIVATE(len);                 /**< ASN1 length, in octets. */
+    unsigned char MBEDTLS_PRIVATE(unused_bits);  /**< Number of unused bits at the end of the string */
+    unsigned char *MBEDTLS_PRIVATE(p);           /**< Raw ASN1 data for the bit string */
 }
 mbedtls_asn1_bitstring;
 
@@ -155,8 +167,8 @@
  */
 typedef struct mbedtls_asn1_sequence
 {
-    mbedtls_asn1_buf buf;                   /**< Buffer containing the given ASN.1 item. */
-    struct mbedtls_asn1_sequence *next;    /**< The next entry in the sequence. */
+    mbedtls_asn1_buf MBEDTLS_PRIVATE(buf);                   /**< Buffer containing the given ASN.1 item. */
+    struct mbedtls_asn1_sequence *MBEDTLS_PRIVATE(next);    /**< The next entry in the sequence. */
 }
 mbedtls_asn1_sequence;
 
@@ -165,10 +177,10 @@
  */
 typedef struct mbedtls_asn1_named_data
 {
-    mbedtls_asn1_buf oid;                   /**< The object identifier. */
-    mbedtls_asn1_buf val;                   /**< The named value. */
-    struct mbedtls_asn1_named_data *next;  /**< The next entry in the sequence. */
-    unsigned char next_merged;      /**< Merge next item into the current one? */
+    mbedtls_asn1_buf MBEDTLS_PRIVATE(oid);                   /**< The object identifier. */
+    mbedtls_asn1_buf MBEDTLS_PRIVATE(val);                   /**< The named value. */
+    struct mbedtls_asn1_named_data *MBEDTLS_PRIVATE(next);  /**< The next entry in the sequence. */
+    unsigned char MBEDTLS_PRIVATE(next_merged);      /**< Merge next item into the current one? */
 }
 mbedtls_asn1_named_data;
 
@@ -176,119 +188,342 @@
  * \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.
  */
 int mbedtls_asn1_get_int( unsigned char **p,
-                  const unsigned char *end,
-                  int *val );
+                          const unsigned char *end,
+                          int *val );
+
+/**
+ * \brief       Retrieve an enumerated ASN.1 tag and its value.
+ *              Updates the pointer to immediately behind the full 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
+ *              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.
+ * \return      An ASN.1 error code if the input does not start with
+ *              a valid ASN.1 ENUMERATED.
+ * \return      #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ *              not fit in an \c int.
+ */
+int mbedtls_asn1_get_enum( unsigned char **p,
+                           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
+ * This function allocates memory for the sequence elements. You can free
+ * the allocated memory with mbedtls_asn1_sequence_free().
  *
- * \return      0 if successful or a specific ASN.1 error code.
+ * \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.
+ *
+ * \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_UNEXPECTED_TAG if the input starts with
+ *              an ASN.1 SEQUENCE in which an element has a tag that
+ *              is different from \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 SEQUENCE.
  */
 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 );
+/**
+ * \brief          Free a heap-allocated linked list presentation of
+ *                 an ASN.1 sequence, including the first element.
+ *
+ * There are two common ways to manage the memory used for the representation
+ * of a parsed ASN.1 sequence:
+ * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
+ *   Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ *   When you have finished processing the sequence,
+ *   call mbedtls_asn1_sequence_free() on `head`.
+ * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
+ *   for example on the stack. Make sure that `head->next == NULL`.
+ *   Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ *   When you have finished processing the sequence,
+ *   call mbedtls_asn1_sequence_free() on `head->cur`,
+ *   then free `head` itself in the appropriate manner.
+ *
+ * \param seq      The address of the first sequence component. This may
+ *                 be \c NULL, in which case this functions returns
+ *                 immediately.
+ */
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq );
+
+/**
+ * \brief                Traverse an ASN.1 SEQUENCE container and
+ *                       call a callback for each entry.
+ *
+ * This function checks that the input is a SEQUENCE of elements that
+ * each have a "must" tag, and calls a callback function on the elements
+ * that have a "may" tag.
+ *
+ * For example, to validate that the input is a SEQUENCE of `tag1` and call
+ * `cb` on each element, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx);
+ * ```
+ *
+ * To validate that the input is a SEQUENCE of ANY and call `cb` on
+ * each element, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx);
+ * ```
+ *
+ * To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING}
+ * and call `cb` on each element that is an OCTET STRING, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx);
+ * ```
+ *
+ * The callback is called on the elements with a "may" tag from left to
+ * right. If the input is not a valid SEQUENCE of elements with a "must" tag,
+ * the callback is called on the elements up to the leftmost point where
+ * the input is invalid.
+ *
+ * \warning              This function is still experimental and may change
+ *                       at any time.
+ *
+ * \param p              The address of the pointer to the beginning of
+ *                       the ASN.1 SEQUENCE header. This is updated to
+ *                       point to the end of the ASN.1 SEQUENCE container
+ *                       on a successful invocation.
+ * \param end            The end of the ASN.1 SEQUENCE container.
+ * \param tag_must_mask  A mask to be applied to the ASN.1 tags found within
+ *                       the SEQUENCE before comparing to \p tag_must_value.
+ * \param tag_must_val   The required value of each ASN.1 tag found in the
+ *                       SEQUENCE, after masking with \p tag_must_mask.
+ *                       Mismatching tags lead to an error.
+ *                       For example, a value of \c 0 for both \p tag_must_mask
+ *                       and \p tag_must_val means that every tag is allowed,
+ *                       while a value of \c 0xFF for \p tag_must_mask means
+ *                       that \p tag_must_val is the only allowed tag.
+ * \param tag_may_mask   A mask to be applied to the ASN.1 tags found within
+ *                       the SEQUENCE before comparing to \p tag_may_value.
+ * \param tag_may_val    The desired value of each ASN.1 tag found in the
+ *                       SEQUENCE, after masking with \p tag_may_mask.
+ *                       Mismatching tags will be silently ignored.
+ *                       For example, a value of \c 0 for \p tag_may_mask and
+ *                       \p tag_may_val means that any tag will be considered,
+ *                       while a value of \c 0xFF for \p tag_may_mask means
+ *                       that all tags with value different from \p tag_may_val
+ *                       will be ignored.
+ * \param cb             The callback to trigger for each component
+ *                       in the ASN.1 SEQUENCE that matches \p tag_may_val.
+ *                       The callback function is called with the following
+ *                       parameters:
+ *                       - \p ctx.
+ *                       - The tag of the current element.
+ *                       - A pointer to the start of the current element's
+ *                         content inside the input.
+ *                       - The length of the content of the current element.
+ *                       If the callback returns a non-zero value,
+ *                       the function stops immediately,
+ *                       forwarding the callback's return value.
+ * \param ctx            The context to be passed to the callback \p cb.
+ *
+ * \return               \c 0 if successful the entire ASN.1 SEQUENCE
+ *                       was traversed without parsing or callback errors.
+ * \return               #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input
+ *                       contains extra data after a valid SEQUENCE
+ *                       of elements with an accepted tag.
+ * \return               #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts
+ *                       with an ASN.1 SEQUENCE in which an element has a tag
+ *                       that is not accepted.
+ * \return               An ASN.1 error code if the input does not start with
+ *                       a valid ASN.1 SEQUENCE.
+ * \return               A non-zero error code forwarded from the callback
+ *                       \p cb in case the latter returns a non-zero value.
+ */
+int mbedtls_asn1_traverse_sequence_of(
+    unsigned char **p,
+    const unsigned char *end,
+    unsigned char tag_must_mask, unsigned char tag_must_val,
+    unsigned char tag_may_mask, unsigned char tag_may_val,
+    int (*cb)( void *ctx, int tag,
+               unsigned char* start, size_t len ),
+    void *ctx );
 
 #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.
  */
 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 +531,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 +552,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.
  */
@@ -333,21 +575,25 @@
  *
  * \return      NULL if not found, or a pointer to the existing entry.
  */
-mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
+const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
                                        const char *oid, size_t len );
 
 /**
  * \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 );