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