xref: /aosp_15_r20/trusty/kernel/lib/libc-ext/uuid.c (revision 344aa361028b423587d4ef3fa52a23d194628137)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <inttypes.h>
25 #include <stdbool.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <trusty/uuid.h>
29 
uuid_to_str(const struct uuid * uuid,char * str)30 void uuid_to_str(const struct uuid* uuid, char* str) {
31     sprintf(str,
32             "%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 "-%02" PRIx8 "%02" PRIx8
33             "-%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8
34             "%02" PRIx8,
35             uuid->time_low, uuid->time_mid, uuid->time_hi_and_version,
36             uuid->clock_seq_and_node[0], uuid->clock_seq_and_node[1],
37             uuid->clock_seq_and_node[2], uuid->clock_seq_and_node[3],
38             uuid->clock_seq_and_node[4], uuid->clock_seq_and_node[5],
39             uuid->clock_seq_and_node[6], uuid->clock_seq_and_node[7]);
40 }
41 
parse_dash(const char ** str)42 static bool parse_dash(const char** str) {
43     if (**str != '-') {
44         return false;
45     }
46 
47     *str += 1;
48     return true;
49 }
50 
parse_hex_digit(const char ** str,uint8_t * dst)51 static bool parse_hex_digit(const char** str, uint8_t* dst) {
52     char c;
53 
54     c = **str;
55     *str += 1;
56 
57     if (c >= '0' && c <= '9') {
58         *dst = c - '0';
59         return true;
60     }
61 
62     if (c >= 'a' && c <= 'f') {
63         *dst = c - 'a' + 10;
64         return true;
65     }
66 
67     return false;
68 }
69 
parse_u8(const char ** str,uint8_t * dst)70 static bool parse_u8(const char** str, uint8_t* dst) {
71     uint8_t msn;
72     uint8_t lsn;
73 
74     if (!parse_hex_digit(str, &msn)) {
75         return false;
76     }
77 
78     if (!parse_hex_digit(str, &lsn)) {
79         return false;
80     }
81 
82     *dst = (msn << 4) + lsn;
83     return true;
84 }
85 
parse_u16(const char ** str,uint16_t * dst)86 static bool parse_u16(const char** str, uint16_t* dst) {
87     uint8_t msb;
88     uint8_t lsb;
89 
90     if (!parse_u8(str, &msb)) {
91         return false;
92     }
93 
94     if (!parse_u8(str, &lsb)) {
95         return false;
96     }
97 
98     *dst = ((uint16_t)msb << 8) + lsb;
99     return true;
100 }
101 
parse_u32(const char ** str,uint32_t * dst)102 static bool parse_u32(const char** str, uint32_t* dst) {
103     uint16_t msh;
104     uint16_t lsh;
105 
106     if (!parse_u16(str, &msh)) {
107         return false;
108     }
109 
110     if (!parse_u16(str, &lsh)) {
111         return false;
112     }
113 
114     *dst = ((uint32_t)msh << 16) + lsh;
115     return true;
116 }
117 
str_to_uuid(const char * str,struct uuid * uuid)118 int str_to_uuid(const char* str, struct uuid* uuid) {
119     int len;
120 
121     len = strnlen(str, UUID_STR_SIZE);
122     if (len == UUID_STR_SIZE) {
123         return -1;
124     }
125 
126     if (!parse_u32(&str, &uuid->time_low)) {
127         return -1;
128     }
129 
130     if (!parse_dash(&str)) {
131         return -1;
132     }
133 
134     if (!parse_u16(&str, &uuid->time_mid)) {
135         return -1;
136     }
137 
138     if (!parse_dash(&str)) {
139         return -1;
140     }
141 
142     if (!parse_u16(&str, &uuid->time_hi_and_version)) {
143         return -1;
144     }
145 
146     if (!parse_dash(&str)) {
147         return -1;
148     }
149 
150     if (!parse_u8(&str, uuid->clock_seq_and_node)) {
151         return -1;
152     }
153 
154     if (!parse_u8(&str, uuid->clock_seq_and_node + 1)) {
155         return -1;
156     }
157 
158     if (!parse_dash(&str)) {
159         return -1;
160     }
161 
162     for (int i = 2; i < 8; i++) {
163         if (!parse_u8(&str, uuid->clock_seq_and_node + i)) {
164             return -1;
165         }
166     }
167 
168     return 0;
169 }
170