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