in nsm-driver/nsm.c [488:561]
static int cbor_object_get_array(uint8_t *cbor_object, size_t cbor_object_size, uint8_t **cbor_array)
{
uint8_t cbor_short_size;
uint64_t array_len;
uint64_t array_offset;
if (!cbor_object_is_array(cbor_object, cbor_object_size))
return -EFAULT;
if (cbor_array == NULL)
return -EFAULT;
cbor_short_size = (cbor_object[0] & 0x1F);
/* Decoding byte array length */
/* In short field encoding, the object header is 1 byte long and
* contains the type on the 3 MSB and the length on the LSB.
* If the length in the LSB is larger than 23, then the object
* uses long field encoding, and will contain the length over the
* next bytes in the object, depending on the value:
* 24 is u8, 25 is u16, 26 is u32 and 27 is u64.
*/
if (cbor_short_size <= CBOR_SHORT_SIZE_MAX_VALUE) {
/* short encoding */
array_len = cbor_short_size;
array_offset = CBOR_HEADER_SIZE_SHORT;
} else if (cbor_short_size == CBOR_LONG_SIZE_U8) {
if (cbor_object_size < CBOR_HEADER_SIZE_U8)
return -EFAULT;
/* 1 byte */
array_len = cbor_object[1];
array_offset = CBOR_HEADER_SIZE_U8;
} else if (cbor_short_size == CBOR_LONG_SIZE_U16) {
if (cbor_object_size < CBOR_HEADER_SIZE_U16)
return -EFAULT;
/* 2 bytes */
array_len = cbor_object[1] << 8 | cbor_object[2];
array_offset = CBOR_HEADER_SIZE_U16;
} else if (cbor_short_size == CBOR_LONG_SIZE_U32) {
if (cbor_object_size < CBOR_HEADER_SIZE_U32)
return -EFAULT;
/* 4 bytes */
array_len = cbor_object[1] << 24 |
cbor_object[2] << 16 |
cbor_object[3] << 8 |
cbor_object[4];
array_offset = CBOR_HEADER_SIZE_U32;
} else if (cbor_short_size == CBOR_LONG_SIZE_U64) {
if (cbor_object_size < CBOR_HEADER_SIZE_U64)
return -EFAULT;
/* 8 bytes */
array_len = (uint64_t) cbor_object[1] << 56 |
(uint64_t) cbor_object[2] << 48 |
(uint64_t) cbor_object[3] << 40 |
(uint64_t) cbor_object[4] << 32 |
(uint64_t) cbor_object[5] << 24 |
(uint64_t) cbor_object[6] << 16 |
(uint64_t) cbor_object[7] << 8 |
(uint64_t) cbor_object[8];
array_offset = CBOR_HEADER_SIZE_U64;
}
if (cbor_object_size < array_offset)
return -EFAULT;
if (cbor_object_size - array_offset < array_len)
return -EFAULT;
if (array_len > INT_MAX)
return -EFAULT;
*cbor_array = cbor_object + array_offset;
return array_len;
}