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