1d13dbb6fSDavid Horstmann /* 2d13dbb6fSDavid Horstmann * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. 3d13dbb6fSDavid Horstmann * 4d13dbb6fSDavid Horstmann * SPDX-License-Identifier: BSD-3-Clause 5d13dbb6fSDavid Horstmann */ 6d13dbb6fSDavid Horstmann 7d13dbb6fSDavid Horstmann #include <assert.h> 8d13dbb6fSDavid Horstmann #include <errno.h> 9d13dbb6fSDavid Horstmann #include <stdint.h> 10d13dbb6fSDavid Horstmann #include <string.h> 11d13dbb6fSDavid Horstmann 12d13dbb6fSDavid Horstmann #include <common/debug.h> 13d13dbb6fSDavid Horstmann #include <common/uuid.h> 14d13dbb6fSDavid Horstmann 15d13dbb6fSDavid Horstmann /* Return the hex nibble value of a char */ 16d13dbb6fSDavid Horstmann static int8_t hex_val(char hex) 17d13dbb6fSDavid Horstmann { 18d13dbb6fSDavid Horstmann int8_t val = 0; 19d13dbb6fSDavid Horstmann 20d13dbb6fSDavid Horstmann if ((hex >= '0') && (hex <= '9')) { 21d13dbb6fSDavid Horstmann val = (int8_t)(hex - '0'); 22d13dbb6fSDavid Horstmann } else if ((hex >= 'a') && (hex <= 'f')) { 23d13dbb6fSDavid Horstmann val = (int8_t)(hex - 'a' + 0xa); 24d13dbb6fSDavid Horstmann } else if ((hex >= 'A') && (hex <= 'F')) { 25d13dbb6fSDavid Horstmann val = (int8_t)(hex - 'A' + 0xa); 26d13dbb6fSDavid Horstmann } else { 27d13dbb6fSDavid Horstmann val = -1; 28d13dbb6fSDavid Horstmann } 29d13dbb6fSDavid Horstmann 30d13dbb6fSDavid Horstmann return val; 31d13dbb6fSDavid Horstmann } 32d13dbb6fSDavid Horstmann 33d13dbb6fSDavid Horstmann /* 34d13dbb6fSDavid Horstmann * Read hex_src_len hex characters from hex_src, convert to bytes and 35d13dbb6fSDavid Horstmann * store in buffer pointed to by dest 36d13dbb6fSDavid Horstmann */ 37d13dbb6fSDavid Horstmann static int read_hex(uint8_t *dest, char *hex_src, unsigned int hex_src_len) 38d13dbb6fSDavid Horstmann { 39d13dbb6fSDavid Horstmann int8_t nibble; 40d13dbb6fSDavid Horstmann uint8_t byte; 41d13dbb6fSDavid Horstmann 42d13dbb6fSDavid Horstmann /* 43d13dbb6fSDavid Horstmann * The string length must be a multiple of 2 to represent an 44d13dbb6fSDavid Horstmann * exact number of bytes. 45d13dbb6fSDavid Horstmann */ 46d13dbb6fSDavid Horstmann assert((hex_src_len % 2U) == 0U); 47d13dbb6fSDavid Horstmann 48d13dbb6fSDavid Horstmann for (unsigned int i = 0U; i < (hex_src_len / 2U); i++) { 49d13dbb6fSDavid Horstmann nibble = 0; 50d13dbb6fSDavid Horstmann byte = 0U; 51d13dbb6fSDavid Horstmann 52d13dbb6fSDavid Horstmann nibble = hex_val(hex_src[2U * i]); 53d13dbb6fSDavid Horstmann if (nibble < 0) { 54d13dbb6fSDavid Horstmann return -1; 55d13dbb6fSDavid Horstmann } 56d13dbb6fSDavid Horstmann byte = (uint8_t)nibble; 57d13dbb6fSDavid Horstmann byte <<= 4U; 58d13dbb6fSDavid Horstmann 59d13dbb6fSDavid Horstmann nibble = hex_val(hex_src[(2U * i) + 1U]); 60d13dbb6fSDavid Horstmann if (nibble < 0) { 61d13dbb6fSDavid Horstmann return -1; 62d13dbb6fSDavid Horstmann } 63d13dbb6fSDavid Horstmann byte |= (uint8_t)nibble; 64d13dbb6fSDavid Horstmann 65d13dbb6fSDavid Horstmann *dest = byte; 66d13dbb6fSDavid Horstmann dest++; 67d13dbb6fSDavid Horstmann } 68d13dbb6fSDavid Horstmann 69d13dbb6fSDavid Horstmann return 0; 70d13dbb6fSDavid Horstmann } 71d13dbb6fSDavid Horstmann 72d13dbb6fSDavid Horstmann /* Parse UUIDs of the form aabbccdd-eeff-4099-8877-665544332211 */ 73d13dbb6fSDavid Horstmann int read_uuid(uint8_t *dest, char *uuid) 74d13dbb6fSDavid Horstmann { 75d13dbb6fSDavid Horstmann int err; 76*d0d64245SDavid Horstmann uint8_t *dest_start = dest; 77d13dbb6fSDavid Horstmann 78d13dbb6fSDavid Horstmann /* Check that we have enough characters */ 79d13dbb6fSDavid Horstmann if (strnlen(uuid, UUID_STRING_LENGTH) != UUID_STRING_LENGTH) { 80d13dbb6fSDavid Horstmann WARN("UUID string is too short\n"); 81d13dbb6fSDavid Horstmann return -EINVAL; 82d13dbb6fSDavid Horstmann } 83d13dbb6fSDavid Horstmann 84d13dbb6fSDavid Horstmann /* aabbccdd */ 85d13dbb6fSDavid Horstmann err = read_hex(dest, uuid, 8); 86d13dbb6fSDavid Horstmann uuid += 8; 87d13dbb6fSDavid Horstmann dest += 4; 88d13dbb6fSDavid Horstmann 89d13dbb6fSDavid Horstmann /* Check for '-' */ 90d13dbb6fSDavid Horstmann err |= ((*uuid == '-') ? 0 : -1); 91d13dbb6fSDavid Horstmann uuid++; 92d13dbb6fSDavid Horstmann 93d13dbb6fSDavid Horstmann /* eeff */ 94d13dbb6fSDavid Horstmann err |= read_hex(dest, uuid, 4); 95d13dbb6fSDavid Horstmann uuid += 4; 96d13dbb6fSDavid Horstmann dest += 2; 97d13dbb6fSDavid Horstmann 98d13dbb6fSDavid Horstmann /* Check for '-' */ 99d13dbb6fSDavid Horstmann err |= ((*uuid == '-') ? 0 : -1); 100d13dbb6fSDavid Horstmann uuid++; 101d13dbb6fSDavid Horstmann 102d13dbb6fSDavid Horstmann /* 4099 */ 103d13dbb6fSDavid Horstmann err |= read_hex(dest, uuid, 4); 104d13dbb6fSDavid Horstmann uuid += 4; 105d13dbb6fSDavid Horstmann dest += 2; 106d13dbb6fSDavid Horstmann 107d13dbb6fSDavid Horstmann /* Check for '-' */ 108d13dbb6fSDavid Horstmann err |= ((*uuid == '-') ? 0 : -1); 109d13dbb6fSDavid Horstmann uuid++; 110d13dbb6fSDavid Horstmann 111d13dbb6fSDavid Horstmann /* 8877 */ 112d13dbb6fSDavid Horstmann err |= read_hex(dest, uuid, 4); 113d13dbb6fSDavid Horstmann uuid += 4; 114d13dbb6fSDavid Horstmann dest += 2; 115d13dbb6fSDavid Horstmann 116d13dbb6fSDavid Horstmann /* Check for '-' */ 117d13dbb6fSDavid Horstmann err |= ((*uuid == '-') ? 0 : -1); 118d13dbb6fSDavid Horstmann uuid++; 119d13dbb6fSDavid Horstmann 120d13dbb6fSDavid Horstmann /* 665544332211 */ 121d13dbb6fSDavid Horstmann err |= read_hex(dest, uuid, 12); 122d13dbb6fSDavid Horstmann uuid += 12; 123d13dbb6fSDavid Horstmann dest += 6; 124d13dbb6fSDavid Horstmann 125d13dbb6fSDavid Horstmann if (err < 0) { 126d13dbb6fSDavid Horstmann WARN("Error parsing UUID\n"); 127d13dbb6fSDavid Horstmann /* Clear the buffer on error */ 128*d0d64245SDavid Horstmann memset((void *)dest_start, '\0', UUID_BYTES_LENGTH * sizeof(uint8_t)); 129d13dbb6fSDavid Horstmann return -EINVAL; 130d13dbb6fSDavid Horstmann } 131d13dbb6fSDavid Horstmann 132d13dbb6fSDavid Horstmann return 0; 133d13dbb6fSDavid Horstmann } 134d13dbb6fSDavid Horstmann 135