hc
2023-02-13 e440ec23c5a540cdd3f7464e8779219be6fd3d95
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2019, Linaro Limited
 */
 
#include <ctype.h>
#include <endian.h>
#ifdef OPENSSL_FOUND
#include <openssl/evp.h>
#endif
#include <stdint.h>
#include <string.h>
#include <tee_api_types.h>
#include <tee_client_api.h>
#include "xtest_uuid_helpers.h"
 
static int hex(char c)
{
   char lc = tolower(c);
 
   if (isdigit(lc))
       return lc - '0';
   if (isxdigit(lc))
       return lc - 'a' + 10;
   return -1;
}
 
static uint32_t parse_hex(const char *s, size_t nchars, uint32_t *res)
{
   uint32_t v = 0;
   size_t n = 0;
   int c = 0;
 
   for (n = 0; n < nchars; n++) {
       c = hex(s[n]);
       if (c == -1) {
           *res = TEE_ERROR_BAD_FORMAT;
           goto out;
       }
       v = (v << 4) + c;
   }
   *res = TEE_SUCCESS;
out:
   return v;
}
 
TEEC_Result xtest_uuid_from_str(TEEC_UUID *uuid, const char *s)
{
   TEEC_Result res = TEEC_SUCCESS;
   TEEC_UUID u = { };
   const char *p = s;
   size_t i = 0;
 
   if (!p || strnlen(p, 37) != 36)
       return TEEC_ERROR_BAD_FORMAT;
   if (p[8] != '-' || p[13] != '-' || p[18] != '-' || p[23] != '-')
       return TEEC_ERROR_BAD_FORMAT;
 
   u.timeLow = parse_hex(p, 8, &res);
   if (res)
       goto out;
   p += 9;
   u.timeMid = parse_hex(p, 4, &res);
   if (res)
       goto out;
   p += 5;
   u.timeHiAndVersion = parse_hex(p, 4, &res);
   if (res)
       goto out;
   p += 5;
   for (i = 0; i < 8; i++) {
       u.clockSeqAndNode[i] = parse_hex(p, 2, &res);
       if (res)
           goto out;
       if (i == 1)
           p += 3;
       else
           p += 2;
   }
   *uuid = u;
out:
   return res;
}
 
#ifdef OPENSSL_FOUND
TEEC_Result xtest_uuid_v5(TEEC_UUID *uuid, const TEEC_UUID *ns,
             const void *name, size_t size)
{
   TEEC_Result res = TEEC_SUCCESS;
   EVP_MD_CTX *mdctx = NULL;
   const EVP_MD *md = NULL;
   unsigned char hash[EVP_MAX_MD_SIZE] = { };
   unsigned int md_len = 0;
   unsigned char nsbe[16] = { };
   uint32_t be32 = 0;
   uint16_t be16 = 0;
   int ret = 0;
 
   /* Convert from host to big endian */
   be32 = htobe32(ns->timeLow);
   memcpy(&nsbe[0], &be32, sizeof(be32));
   be16 = htobe16(ns->timeMid);
   memcpy(&nsbe[4], &be16, sizeof(be16));
   be16 = htobe16(ns->timeHiAndVersion);
   memcpy(&nsbe[6], &be16, sizeof(be16));
   memcpy(&nsbe[8], &ns->clockSeqAndNode, sizeof(ns->clockSeqAndNode));
 
   mdctx = EVP_MD_CTX_create();
   if (!mdctx)
       return TEEC_ERROR_OUT_OF_MEMORY;
   md = EVP_sha1();
   if (!md) {
       res = TEEC_ERROR_NOT_SUPPORTED;
       goto out;
   }
   ret = EVP_DigestInit_ex(mdctx, md, NULL);
   if (!ret) {
       res = TEEC_ERROR_GENERIC;
       goto out;
   }
   ret = EVP_DigestUpdate(mdctx, nsbe, sizeof(nsbe));
   if (!ret) {
       res = TEEC_ERROR_GENERIC;
       goto out;
   }
   ret = EVP_DigestUpdate(mdctx, name, size);
   if (!ret) {
       res = TEEC_ERROR_GENERIC;
       goto out;
   }
   ret = EVP_DigestFinal_ex(mdctx, hash, &md_len);
   if (!ret) {
       res = TEEC_ERROR_GENERIC;
       goto out;
   }
 
   /* Mark it as UUIDv5 */
   hash[6] = (hash[6] & 0x0F) | 0x50;
   hash[8] = (hash[8] & 0x3F) | 0x80;
 
   /* Convert from big endian to host */
   memcpy(&be32, &hash[0], sizeof(uint32_t));
   uuid->timeLow = be32toh(be32);
   memcpy(&be16, &hash[4], sizeof(uint16_t));
   uuid->timeMid = be16toh(be16);
   memcpy(&be16, &hash[6], sizeof(uint16_t));
   uuid->timeHiAndVersion = be16toh(be16);
   memcpy(uuid->clockSeqAndNode, &hash[8], sizeof(uuid->clockSeqAndNode));
out:
   EVP_MD_CTX_destroy(mdctx);
   return res;
}
#endif /*OPENSSL_FOUND*/