1 // SPDX-License-Identifier: BSD-3-Clause 2 /* ========================================================================== 3 * Copyright (c) 2016-2018, The Linux Foundation. 4 * Copyright (c) 2018-2024, Laurence Lundblade. 5 * Copyright (c) 2021, Arm Limited. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are 10 * met: 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * * Neither the name of The Linux Foundation nor the names of its 18 * contributors, nor the name "Laurence Lundblade" may be used to 19 * endorse or promote products derived from this software without 20 * specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 32 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * ========================================================================= */ 34 35 36 #ifndef qcbor_private_h 37 #define qcbor_private_h 38 39 40 #include <stdint.h> 41 #include "UsefulBuf.h" 42 #include "qcbor/qcbor_common.h" 43 44 45 #ifdef __cplusplus 46 extern "C" { 47 #if 0 48 } // Keep editor indention formatting happy 49 #endif 50 #endif 51 52 53 /* This was originally defined as QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA, 54 * but this is inconsistent with all the other QCBOR_DISABLE_ 55 * #defines, so the name was changed and this was added for backwards 56 * compatibility 57 */ 58 #ifdef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA 59 #define QCBOR_DISABLE_EXP_AND_MANTISSA 60 #endif 61 62 /* If USEFULBUF_DISABLE_ALL_FLOATis defined then define 63 * QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT 64 */ 65 #ifdef USEFULBUF_DISABLE_ALL_FLOAT 66 #ifndef QCBOR_DISABLE_FLOAT_HW_USE 67 #define QCBOR_DISABLE_FLOAT_HW_USE 68 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */ 69 #ifndef QCBOR_DISABLE_PREFERRED_FLOAT 70 #define QCBOR_DISABLE_PREFERRED_FLOAT 71 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */ 72 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */ 73 74 75 /* 76 * Convenience macro for selecting the proper return value in case floating 77 * point feature(s) are disabled. 78 * 79 * The macros: 80 * 81 * FLOAT_ERR_CODE_NO_FLOAT(x) Can be used when disabled floating point should 82 * result error, and all other cases should return 83 * 'x'. 84 * 85 * The below macros always return QCBOR_ERR_ALL_FLOAT_DISABLED when all 86 * floating point is disabled. 87 * 88 * FLOAT_ERR_CODE_NO_HALF_PREC(x) Can be used when disabled preferred float 89 * results in error, and all other cases should 90 * return 'x'. 91 * FLOAT_ERR_CODE_NO_FLOAT_HW(x) Can be used when disabled hardware floating 92 * point results in error, and all other cases 93 * should return 'x'. 94 * FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) Can be used when either disabled 95 * preferred float or disabling 96 * hardware floating point results in 97 * error, and all other cases should 98 * return 'x'. 99 */ 100 #ifdef USEFULBUF_DISABLE_ALL_FLOAT 101 #define FLOAT_ERR_CODE_NO_FLOAT(x) QCBOR_ERR_ALL_FLOAT_DISABLED 102 #define FLOAT_ERR_CODE_NO_HALF_PREC(x) QCBOR_ERR_ALL_FLOAT_DISABLED 103 #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) QCBOR_ERR_ALL_FLOAT_DISABLED 104 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_ALL_FLOAT_DISABLED 105 #else /* USEFULBUF_DISABLE_ALL_FLOAT*/ 106 #define FLOAT_ERR_CODE_NO_FLOAT(x) x 107 #ifdef QCBOR_DISABLE_PREFERRED_FLOAT 108 #define FLOAT_ERR_CODE_NO_HALF_PREC(x) QCBOR_ERR_HALF_PRECISION_DISABLED 109 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_HALF_PRECISION_DISABLED 110 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */ 111 #define FLOAT_ERR_CODE_NO_HALF_PREC(x) x 112 #ifdef QCBOR_DISABLE_FLOAT_HW_USE 113 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_HW_FLOAT_DISABLED 114 #else 115 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) x 116 #endif 117 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */ 118 #ifdef QCBOR_DISABLE_FLOAT_HW_USE 119 #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) QCBOR_ERR_HW_FLOAT_DISABLED 120 #else /* QCBOR_DISABLE_FLOAT_HW_USE */ 121 #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) x 122 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */ 123 #endif /*USEFULBUF_DISABLE_ALL_FLOAT*/ 124 125 126 /* 127 * These are special values for the AdditionalInfo bits that are part of 128 * the first byte. Mostly they encode the length of the data item. 129 */ 130 #define LEN_IS_ONE_BYTE 24 131 #define LEN_IS_TWO_BYTES 25 132 #define LEN_IS_FOUR_BYTES 26 133 #define LEN_IS_EIGHT_BYTES 27 134 #define ADDINFO_RESERVED1 28 135 #define ADDINFO_RESERVED2 29 136 #define ADDINFO_RESERVED3 30 137 #define LEN_IS_INDEFINITE 31 138 139 140 /* 141 * 24 is a special number for CBOR. Integers and lengths 142 * less than it are encoded in the same byte as the major type. 143 */ 144 #define CBOR_TWENTY_FOUR 24 145 146 147 /* 148 * Values for the 5 bits for items of major type 7 149 */ 150 #define CBOR_SIMPLEV_FALSE 20 151 #define CBOR_SIMPLEV_TRUE 21 152 #define CBOR_SIMPLEV_NULL 22 153 #define CBOR_SIMPLEV_UNDEF 23 154 #define CBOR_SIMPLEV_ONEBYTE 24 155 #define HALF_PREC_FLOAT 25 156 #define SINGLE_PREC_FLOAT 26 157 #define DOUBLE_PREC_FLOAT 27 158 #define CBOR_SIMPLE_BREAK 31 159 #define CBOR_SIMPLEV_RESERVED_START CBOR_SIMPLEV_ONEBYTE 160 #define CBOR_SIMPLEV_RESERVED_END CBOR_SIMPLE_BREAK 161 162 163 /* The largest offset to the start of an array or map. It is slightly 164 * less than UINT32_MAX so the error condition can be tested on 32-bit 165 * machines. UINT32_MAX comes from uStart in QCBORTrackNesting being 166 * a uin32_t. 167 * 168 * This will cause trouble on a machine where size_t is less than 32-bits. 169 */ 170 #define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100) 171 172 173 /* The number of tags that are 16-bit or larger that can be handled 174 * in a decode. 175 */ 176 #define QCBOR_NUM_MAPPED_TAGS 4 177 178 /* The number of tags (of any size) recorded for an individual item. */ 179 #define QCBOR_MAX_TAGS_PER_ITEM1 4 180 181 182 183 184 /* 185 * PRIVATE DATA STRUCTURE 186 * 187 * Holds the data for tracking array and map nesting during 188 * encoding. Pairs up with the Nesting_xxx functions to make an 189 * "object" to handle nesting encoding. 190 * 191 * uStart is a uint32_t instead of a size_t to keep the size of this 192 * struct down so it can be on the stack without any concern. It 193 * would be about double if size_t was used instead. 194 * 195 * Size approximation (varies with CPU/compiler): 196 * 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes 197 * 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes 198 */ 199 typedef struct __QCBORTrackNesting { 200 /* PRIVATE DATA STRUCTURE */ 201 struct { 202 /* See QCBOREncode_OpenMapOrArray() for details on how this works */ 203 uint32_t uStart; /* uStart is the position where the array starts */ 204 uint16_t uCount; /* Number of items in the arrary or map; counts items 205 * in a map, not pairs of items */ 206 uint8_t uMajorType; /* Indicates if item is a map or an array */ 207 } pArrays[QCBOR_MAX_ARRAY_NESTING+1], /* stored state for nesting levels */ 208 *pCurrentNesting; /* the current nesting level */ 209 } QCBORTrackNesting; 210 211 212 /* 213 * PRIVATE DATA STRUCTURE 214 * 215 * Context / data object for encoding some CBOR. Used by all encode 216 * functions to form a public "object" that does the job of encdoing. 217 * 218 * Size approximation (varies with CPU/compiler): 219 * 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes 220 * 32-bit machine: 15 + 1 + 132 = 148 bytes 221 */ 222 struct _QCBOREncodeContext { 223 /* PRIVATE DATA STRUCTURE */ 224 UsefulOutBuf OutBuf; /* Pointer to output buffer, its length and 225 * position in it. */ 226 uint8_t uError; /* Error state, always from QCBORError enum */ 227 QCBORTrackNesting nesting; /* Keep track of array and map nesting */ 228 }; 229 230 231 /* 232 * PRIVATE DATA STRUCTURE 233 * 234 * Holds the data for array and map nesting for decoding work. This 235 * structure and the DecodeNesting_Xxx() functions in qcbor_decode.c 236 * form an "object" that does the work for arrays and maps. All access 237 * to this structure is through DecodeNesting_Xxx() functions. 238 * 239 * 64-bit machine size 240 * 128 = 16 * 8 for the two unions 241 * 64 = 16 * 4 for the uLevelType, 1 byte padded to 4 bytes for alignment 242 * 16 = 16 bytes for two pointers 243 * 208 TOTAL 244 * 245 * 32-bit machine size is 200 bytes 246 */ 247 typedef struct __QCBORDecodeNesting { 248 /* PRIVATE DATA STRUCTURE */ 249 struct nesting_decode_level { 250 /* 251 * This keeps tracking info for each nesting level. There are two 252 * main types of levels: 253 * 1) Byte count tracking. This is for the top level input CBOR 254 * which might be a single item or a CBOR sequence and byte 255 * string wrapped encoded CBOR. 256 * 2) Item count tracking. This is for maps and arrays. 257 * 258 * uLevelType has value QCBOR_TYPE_BYTE_STRING for 1) and 259 * QCBOR_TYPE_MAP or QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP_AS_ARRAY 260 * for 2). 261 * 262 * Item count tracking is either for definite or indefinite-length 263 * maps/arrays. For definite lengths, the total count and items 264 * unconsumed are tracked. For indefinite-length, uTotalCount is 265 * QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH (UINT16_MAX) and 266 * there is no per-item count of members. For indefinite-length 267 * maps and arrays, uCountCursor is UINT16_MAX if not consumed 268 * and zero if it is consumed in the pre-order 269 * traversal. Additionally, if entered in bounded mode, 270 * uCountCursor is QCBOR_COUNT_INDICATES_ZERO_LENGTH to indicate 271 * it is empty. 272 * 273 * This also records whether a level is bounded or not. All 274 * byte-count tracked levels (the top-level sequence and 275 * bstr-wrapped CBOR) are bounded implicitly. Maps and arrays 276 * may or may not be bounded. They are bounded if they were 277 * Entered() and not if they were traversed with GetNext(). They 278 * are marked as bounded by uStartOffset not being @c UINT32_MAX. 279 */ 280 /* 281 * If uLevelType can put in a separately indexed array, the 282 * union/struct will be 8 bytes rather than 9 and a lot of 283 * wasted padding for alignment will be saved. 284 */ 285 uint8_t uLevelType; 286 union { 287 struct { 288 #define QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH UINT16_MAX 289 #define QCBOR_COUNT_INDICATES_ZERO_LENGTH UINT16_MAX-1 290 uint16_t uCountTotal; 291 uint16_t uCountCursor; 292 #define QCBOR_NON_BOUNDED_OFFSET UINT32_MAX 293 /* The start of the array or map in bounded mode so 294 * the input can be rewound for GetInMapXx() by label. */ 295 uint32_t uStartOffset; 296 } ma; /* for maps and arrays */ 297 struct { 298 /* The end of the input before the bstr was entered so that 299 * it can be restored when the bstr is exited. */ 300 uint32_t uSavedEndOffset; 301 /* The beginning of the bstr so that it can be rewound. */ 302 uint32_t uBstrStartOffset; 303 } bs; /* for top-level sequence and bstr-wrapped CBOR */ 304 } u; 305 } pLevels[QCBOR_MAX_ARRAY_NESTING+1], 306 *pCurrent, 307 *pCurrentBounded; 308 /* 309 * pCurrent is for item-by-item pre-order traversal. 310 * 311 * pCurrentBounded points to the current bounding level or is NULL 312 * if there isn't one. 313 * 314 * pCurrent must always be below pCurrentBounded as the pre-order 315 * traversal is always bounded by the bounding level. 316 * 317 * When a bounded level is entered, the pre-order traversal is set 318 * to the first item in the bounded level. When a bounded level is 319 * exited, the pre-order traversl is set to the next item after the 320 * map, array or bstr. This may be more than one level up, or even 321 * the end of the input CBOR. 322 */ 323 } QCBORDecodeNesting; 324 325 326 typedef struct { 327 /* PRIVATE DATA STRUCTURE */ 328 void *pAllocateCxt; 329 UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize); 330 } QCBORInternalAllocator; 331 332 333 /* 334 * PRIVATE DATA STRUCTURE 335 * 336 * The decode context. This data structure plus the public 337 * QCBORDecode_xxx functions form an "object" that does CBOR decoding. 338 * 339 * Size approximation (varies with CPU/compiler): 340 * 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes 341 * 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes 342 */ 343 struct _QCBORDecodeContext { 344 /* PRIVATE DATA STRUCTURE */ 345 UsefulInputBuf InBuf; 346 347 QCBORDecodeNesting nesting; 348 349 /* If a string allocator is configured for indefinite-length 350 * strings, it is configured here. 351 */ 352 QCBORInternalAllocator StringAllocator; 353 354 /* These are special for the internal MemPool allocator. They are 355 * not used otherwise. We tried packing these in the MemPool 356 * itself, but there are issues with memory alignment. 357 */ 358 uint32_t uMemPoolSize; 359 uint32_t uMemPoolFreeOffset; 360 361 /* A cached offset to the end of the current map 0 if no value is 362 * cached. 363 */ 364 #define QCBOR_MAP_OFFSET_CACHE_INVALID UINT32_MAX 365 uint32_t uMapEndOffsetCache; 366 367 uint8_t uDecodeMode; 368 uint8_t bStringAllocateAll; 369 uint8_t uLastError; /* QCBORError stuffed into a uint8_t */ 370 371 /* See MapTagNumber() for description of how tags are mapped. */ 372 uint64_t auMappedTags[QCBOR_NUM_MAPPED_TAGS]; 373 374 uint16_t uLastTags[QCBOR_MAX_TAGS_PER_ITEM1]; 375 }; 376 377 378 /* Used internally in the impementation here Must not conflict with 379 * any of the official CBOR types 380 */ 381 #define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10 382 #define CBOR_MAJOR_NONE_TYPE_OPEN_BSTR 12 383 384 385 /* Add this to types to indicate they are to be encoded as indefinite lengths */ 386 #define QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 0x80 387 #define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN \ 388 CBOR_MAJOR_TYPE_ARRAY + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 389 #define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN \ 390 CBOR_MAJOR_TYPE_MAP + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 391 #define CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK \ 392 CBOR_MAJOR_TYPE_SIMPLE + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 393 394 395 /* Value of QCBORItem.val.string.len when the string length is 396 * indefinite. Used temporarily in the implementation and never 397 * returned in the public interface. 398 */ 399 #define QCBOR_STRING_LENGTH_INDEFINITE SIZE_MAX 400 401 402 /* The number of elements in a C array of a particular type */ 403 #define C_ARRAY_COUNT(array, type) (sizeof(array)/sizeof(type)) 404 405 406 #ifdef __cplusplus 407 } 408 #endif 409 410 #endif /* qcbor_private_h */ 411