blob: 7ce46c24dcda4fc977ff429de6c73c65ecdf00b6 [file] [log] [blame]
Julian Halla7e89b02020-11-23 17:33:31 +01001/*
2 * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "uuid.h"
8#include <string.h>
9#include <ctype.h>
10#include <stdio.h>
11
12size_t uuid_is_valid(const char *canonical_form)
13{
14 size_t valid_chars = 0;
15 size_t input_len = strlen(canonical_form);
16
17 if (input_len >= UUID_CANONICAL_FORM_LEN) {
18
19 size_t i;
20 valid_chars = UUID_CANONICAL_FORM_LEN;
21
22 for (i = 0; i < UUID_CANONICAL_FORM_LEN; ++i) {
23
24 if (i == 8 || i == 13 || i == 18 || i == 23) {
25 if (canonical_form[i] != '-') return 0;
26 }
27 else {
28 if (!isxdigit(canonical_form[i])) return 0;
29 }
30 }
31 }
32
33 return valid_chars;
34}
35
36size_t uuid_parse_to_octets(const char *canonical_form, uint8_t *buf, size_t buf_size)
37{
38 size_t octet_index = 0;
39 const char *pos;
40 size_t valid_chars = uuid_is_valid(canonical_form);
41
42 if ((buf_size < UUID_OCTETS_LEN) ||
43 (valid_chars != UUID_CANONICAL_FORM_LEN)) {
44 /* Invalid input */
45 return 0;
46 }
47
48 /*
49 * UUID string has been validates as having the following form:
50 * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
51 * 4 2 2 2 6
52 */
53 pos = &canonical_form[0];
54 while (octet_index < 4) {
55 sscanf(pos, "%02hhX", &buf[octet_index++]);
56 pos += 2;
57 }
58
59 pos = &canonical_form[9];
60 while (octet_index < 6) {
61 sscanf(pos, "%02hhX", &buf[octet_index++]);
62 pos += 2;
63 }
64
65 pos = &canonical_form[14];
66 while (octet_index < 8) {
67 sscanf(pos, "%02hhX", &buf[octet_index++]);
68 pos += 2;
69 }
70
71 pos = &canonical_form[19];
72 while (octet_index < 10) {
73 sscanf(pos, "%02hhX", &buf[octet_index++]);
74 pos += 2;
75 }
76
77 pos = &canonical_form[24];
78 while (octet_index < 16) {
79 sscanf(pos, "%02hhX", &buf[octet_index++]);
80 pos += 2;
81 }
82
83 return valid_chars;
84}
85
86/*
87 * TODO: Temorary workaround for optee compatibility
88 * The byte order is reversed for the first 4 bytes, then 2 bytes, then 2 bytes.
89 * This is because the UUID type in OP-TEE consists of an uint32_t, 2x uint16_t,
90 * then uint8_t array.
91 */
92size_t uuid_parse_to_octets_reversed(const char *canonical_form, uint8_t *buf, size_t buf_size)
93{
94 size_t valid_chars;
95 uint8_t standard_octets[UUID_OCTETS_LEN];
96
97 valid_chars = uuid_parse_to_octets(canonical_form, standard_octets, sizeof(standard_octets));
98
99 if ((valid_chars == UUID_CANONICAL_FORM_LEN) && (buf_size >= UUID_OCTETS_LEN)) {
100 /* Reverse bytes in each section */
101 buf[0] = standard_octets[3];
102 buf[1] = standard_octets[2];
103 buf[2] = standard_octets[1];
104 buf[3] = standard_octets[0];
105
106 buf[4] = standard_octets[5];
107 buf[5] = standard_octets[4];
108
109 buf[6] = standard_octets[7];
110 buf[7] = standard_octets[6];
111
112 buf[8] = standard_octets[8];
113 buf[9] = standard_octets[9];
114
115 buf[10] = standard_octets[10];
116 buf[11] = standard_octets[11];
117 buf[12] = standard_octets[12];
118 buf[13] = standard_octets[13];
119 buf[14] = standard_octets[14];
120 buf[15] = standard_octets[15];
121 }
122
123 return valid_chars;
124}