1 /* 2 * Copyright (c) 2021-2022, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 /** \file cc3xx_internal_asn1_util.h 9 * 10 * This file contains the declaration of the internal functions and 11 * utilities to perform parsing of ASN-1 encoded key buffers 12 * 13 */ 14 15 #ifndef CC3XX_INTERNAL_ASN1_UTIL_H 16 #define CC3XX_INTERNAL_ASN1_UTIL_H 17 18 #include "psa/crypto.h" 19 20 #include "cc_common.h" 21 #include "cc_ecc_internal.h" 22 #include "cc_ecpki_error.h" 23 #include "cc_pal_abort.h" 24 #include "cc_pal_mem.h" 25 #include "cc_pal_types.h" 26 #include "mbedtls_cc_ec_mont_edw_error.h" 27 28 #include "cc_ecpki_build.h" 29 #include "cc_ecpki_domain.h" 30 #include "cc_ecpki_ecdsa.h" 31 #include "cc_ecpki_kg.h" 32 #include "cc_ecpki_local.h" 33 #include "pka_ec_wrst.h" 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 /** 40 * \name DER constants 41 * These constants comply with the DER encoded ASN.1 type tags. 42 * DER encoding uses hexadecimal representation. 43 * An example DER sequence is:\n 44 * - 0x02 -- tag indicating INTEGER 45 * - 0x01 -- length in octets 46 * - 0x05 -- value 47 * Such sequences are typically read into \c ::mbedtls_x509_buf. 48 */ 49 #define CC3XX_TAG_ASN1_INTEGER 0x02 50 #define CC3XX_TAG_ASN1_SEQUENCE 0x10 51 #define CC3XX_TAG_ASN1_CONSTRUCTED 0x20 52 53 /** 54 * \brief Write a length field in ASN.1 format. 55 * 56 * \note This function works backwards in data buffer. 57 * 58 * \param p The reference to the current position pointer. 59 * \param start The start of the buffer, for bounds-checking. 60 * \param len The length value to write. 61 * 62 * \return The number of bytes written to \p p on success. 63 * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small. 64 * \return PSA_ERROR_GENERIC_ERROR if any other error occured. 65 */ 66 int cc3xx_asn1_write_len(unsigned char **p, const unsigned char *start, size_t len); 67 68 /** 69 * \brief Write an ASN.1 tag in ASN.1 format. 70 * 71 * \note This function works backwards in data buffer. 72 * 73 * \param p The reference to the current position pointer. 74 * \param start The start of the buffer, for bounds-checking. 75 * \param tag The tag to write. 76 * 77 * \return The number of bytes written to \p p on success. 78 * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small. 79 */ 80 int cc3xx_asn1_write_tag(unsigned char **p, const unsigned char *start, 81 unsigned char tag); 82 83 /** 84 * \brief Write an int tag and value in ASN.1 format represented as a uint8_t array. 85 * 86 * \note This function works backwards in data buffer. 87 * 88 * \param p The reference to the current position pointer. 89 * \param start The start of the buffer, for bounds-checking. 90 * \param data Buffer containing the integer to be written. 91 * \param data_size Size in bytes of the integer. 92 * 93 * \return The number of bytes written to \p p on success. 94 * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small. 95 * \return PSA_ERROR_GENERIC_ERROR if any other error occured. 96 */ 97 int cc3xx_asn1_write_big_integer(unsigned char **p, const unsigned char *start, 98 uint8_t *data, size_t data_size); 99 100 /** 101 * \brief Write an int tag and value in ASN.1 format. 102 * 103 * \note This function works backwards in data buffer. 104 * 105 * \param p The reference to the current position pointer. 106 * \param start The start of the buffer, for bounds-checking. 107 * \param val The integer value to write. 108 * It must be non-negative. 109 * 110 * \return The number of bytes written to \p p on success. 111 * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small. 112 * \return PSA_ERROR_GENERIC_ERROR if any other error occured. 113 */ 114 int cc3xx_asn1_write_int(unsigned char **p, unsigned char *start, int val); 115 116 /** 117 * \brief Get the tag and length of the element. 118 * Check for the requested tag. 119 * Updates the pointer to immediately behind the tag and length. 120 * 121 * \param p On entry, \c *p points to the start of the ASN.1 element. 122 * On successful completion, \c *p points to the first byte 123 * after the length, i.e. the first byte of the content. 124 * On error, the value of \c *p is undefined. 125 * \param end End of data. 126 * \param len On successful completion, \c *len contains the length 127 * read from the ASN.1 input. 128 * \param tag The expected tag. 129 * 130 * \return PSA_SUCCESS if successful. 131 * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small. 132 * \return PSA_ERROR_GENERIC_ERROR if any other error occured. 133 */ 134 psa_status_t cc3xx_asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, 135 int tag); 136 137 /** 138 * \brief Get the length of an ASN.1 element. 139 * Updates the pointer to immediately behind the length. 140 * 141 * \param p On entry, \c *p points to the first byte of the length, 142 * i.e. immediately after the tag. 143 * On successful completion, \c *p points to the first byte 144 * after the length, i.e. the first byte of the content. 145 * On error, the value of \c *p is undefined. 146 * \param end End of data. 147 * \param len On successful completion, \c *len contains the length 148 * read from the ASN.1 input. 149 * 150 * \return PSA_SUCCESS if successful. 151 * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small. 152 * \return PSA_ERROR_GENERIC_ERROR if any other error occured. 153 */ 154 psa_status_t cc3xx_asn1_get_len(unsigned char **p, const unsigned char *end, 155 size_t *len); 156 157 /** 158 * \brief Retrieve an integer ASN.1 tag and its value. 159 * Updates the pointer to immediately behind the full tag. 160 * 161 * \param p On entry, \c *p points to the start of the ASN.1 element. 162 * On successful completion, \c *p points to the first byte 163 * beyond the ASN.1 element. 164 * On error, the value of \c *p is undefined. 165 * \param end End of data. 166 * \param val On success, the parsed value. 167 * 168 * \return PSA_SUCCESS if successful. 169 * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small. 170 * \return PSA_ERROR_GENERIC_ERROR if any other error occured. 171 */ 172 psa_status_t cc3xx_asn1_get_int(unsigned char **p, const unsigned char *end, int *val); 173 174 #ifdef __cplusplus 175 } 176 #endif 177 #endif /* CC3XX_INTERNAL_ASN1_UTIL_H */ 178 179