Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2018 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/uuid.h"
7 : : #include "spdk/config.h"
8 : : #include "spdk/log.h"
9 : :
10 : : #ifndef SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1
11 : : #include <openssl/evp.h>
12 : : #endif /* SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1 */
13 : :
14 : : #ifndef __FreeBSD__
15 : :
16 : : #include <uuid/uuid.h>
17 : :
18 : : SPDK_STATIC_ASSERT(sizeof(struct spdk_uuid) == sizeof(uuid_t), "Size mismatch");
19 : :
20 : : int
21 : 34014 : spdk_uuid_parse(struct spdk_uuid *uuid, const char *uuid_str)
22 : : {
23 [ + + ]: 34014 : return uuid_parse(uuid_str, (void *)uuid) == 0 ? 0 : -EINVAL;
24 : : }
25 : :
26 : : int
27 : 109877 : spdk_uuid_fmt_lower(char *uuid_str, size_t uuid_str_size, const struct spdk_uuid *uuid)
28 : : {
29 [ - + ]: 109877 : if (uuid_str_size < SPDK_UUID_STRING_LEN) {
30 : 0 : return -EINVAL;
31 : : }
32 : :
33 : 109877 : uuid_unparse_lower((void *)uuid, uuid_str);
34 : 109877 : return 0;
35 : : }
36 : :
37 : : int
38 : 61755 : spdk_uuid_compare(const struct spdk_uuid *u1, const struct spdk_uuid *u2)
39 : : {
40 : 61755 : return uuid_compare((void *)u1, (void *)u2);
41 : : }
42 : :
43 : : void
44 : 9695 : spdk_uuid_generate(struct spdk_uuid *uuid)
45 : : {
46 : 9695 : uuid_generate((void *)uuid);
47 : 9695 : }
48 : :
49 : : void
50 : 19037 : spdk_uuid_copy(struct spdk_uuid *dst, const struct spdk_uuid *src)
51 : : {
52 : 19037 : uuid_copy((void *)dst, (void *)src);
53 : 19037 : }
54 : :
55 : : bool
56 : 45178 : spdk_uuid_is_null(const struct spdk_uuid *uuid)
57 : : {
58 : 45178 : return uuid_is_null((void *)uuid);
59 : : }
60 : :
61 : : void
62 : 13035 : spdk_uuid_set_null(struct spdk_uuid *uuid)
63 : : {
64 : 13035 : uuid_clear((void *)uuid);
65 : 13035 : }
66 : :
67 : : #else
68 : :
69 : : #include <uuid.h>
70 : :
71 : : SPDK_STATIC_ASSERT(sizeof(struct spdk_uuid) == sizeof(uuid_t), "Size mismatch");
72 : :
73 : : int
74 : : spdk_uuid_parse(struct spdk_uuid *uuid, const char *uuid_str)
75 : : {
76 : : uint32_t status;
77 : :
78 : : /* uuid_from_string() differs from uuid_parse() in the way it handles empty strings: the
79 : : * former succeeds and returns a NULL UUID, while the latter treats is an error and returns
80 : : * non-zero exit code. So, to keep the behavior consistent between Linux and FreeBSD, we
81 : : * explicitly check for an empty string here.
82 : : */
83 : : if (strlen(uuid_str) == 0) {
84 : : return -EINVAL;
85 : : }
86 : :
87 : : uuid_from_string(uuid_str, (uuid_t *)uuid, &status);
88 : :
89 : : return status == 0 ? 0 : -EINVAL;
90 : : }
91 : :
92 : : int
93 : : spdk_uuid_fmt_lower(char *uuid_str, size_t uuid_str_size, const struct spdk_uuid *uuid)
94 : : {
95 : : uint32_t status;
96 : : char *str;
97 : :
98 : : if (uuid_str_size < SPDK_UUID_STRING_LEN) {
99 : : return -EINVAL;
100 : : }
101 : :
102 : : uuid_to_string((const uuid_t *)uuid, &str, &status);
103 : :
104 : : if (status == uuid_s_no_memory) {
105 : : return -ENOMEM;
106 : : }
107 : :
108 : : snprintf(uuid_str, uuid_str_size, "%s", str);
109 : : free(str);
110 : :
111 : : return 0;
112 : : }
113 : :
114 : : int
115 : : spdk_uuid_compare(const struct spdk_uuid *u1, const struct spdk_uuid *u2)
116 : : {
117 : : return uuid_compare((const uuid_t *)u1, (const uuid_t *)u2, NULL);
118 : : }
119 : :
120 : : void
121 : : spdk_uuid_generate(struct spdk_uuid *uuid)
122 : : {
123 : : uuid_create((uuid_t *)uuid, NULL);
124 : : }
125 : :
126 : : void
127 : : spdk_uuid_copy(struct spdk_uuid *dst, const struct spdk_uuid *src)
128 : : {
129 : : memcpy(dst, src, sizeof(*dst));
130 : : }
131 : :
132 : : bool
133 : : spdk_uuid_is_null(const struct spdk_uuid *uuid)
134 : : {
135 : : return uuid_is_nil((const uuid_t *)uuid, NULL);
136 : : }
137 : :
138 : : void
139 : : spdk_uuid_set_null(struct spdk_uuid *uuid)
140 : : {
141 : : uuid_create_nil((uuid_t *)uuid, NULL);
142 : : }
143 : :
144 : : #endif
145 : :
146 : : int
147 : 2129 : spdk_uuid_generate_sha1(struct spdk_uuid *uuid, struct spdk_uuid *ns_uuid, const char *name,
148 : : size_t len)
149 : : {
150 : : #ifdef SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1
151 : 1896 : uuid_generate_sha1((void *)uuid, (void *)ns_uuid, name, len);
152 : 1896 : return 0;
153 : : #else
154 : : EVP_MD_CTX *mdctx;
155 : : const EVP_MD *md;
156 : 233 : unsigned char md_value[EVP_MAX_MD_SIZE];
157 : 233 : unsigned int md_len;
158 : :
159 : 233 : md = EVP_sha1();
160 [ - + ]: 233 : assert(md != NULL);
161 : :
162 : 233 : mdctx = EVP_MD_CTX_new();
163 [ - + ]: 233 : if (mdctx == NULL) {
164 : 0 : return -ENOMEM;
165 : : }
166 : :
167 [ - + ]: 233 : if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
168 : 0 : SPDK_ERRLOG("Could not initialize EVP digest!\n");
169 : 0 : goto err;
170 : : }
171 [ - + ]: 233 : if (EVP_DigestUpdate(mdctx, ns_uuid, sizeof(struct spdk_uuid)) != 1) {
172 : 0 : SPDK_ERRLOG("Could update EVP digest with namespace UUID!\n");
173 : 0 : goto err;
174 : : }
175 [ - + ]: 233 : if (EVP_DigestUpdate(mdctx, name, len) != 1) {
176 : 0 : SPDK_ERRLOG("Could update EVP digest with assigned name!\n");
177 : 0 : goto err;
178 : : }
179 [ - + ]: 233 : if (EVP_DigestFinal_ex(mdctx, md_value, &md_len) != 1) {
180 : 0 : SPDK_ERRLOG("Could not generate EVP digest!\n");
181 : 0 : goto err;
182 : : }
183 : 233 : EVP_MD_CTX_free(mdctx);
184 : :
185 : 233 : memcpy(uuid, md_value, 16);
186 : : /* This part mimics original uuid_generate_sha1() from libuuid/src/gen_uuid.c.
187 : : * The original uuid structure included from uuid.h looks like this:
188 : : * struct uuid {
189 : : * uint32_t time_low;
190 : : * uint16_t time_mid;
191 : : * uint16_t time_hi_and_version;
192 : : * uint16_t clock_seq;
193 : : * uint8_t node[6];
194 : : * };
195 : : * so uuid->u.raw[6] and uuid->u.raw[8] are time_hi_and_version and clock_seq respectively.
196 : : */
197 : 233 : uuid->u.raw[6] = (uuid->u.raw[6] & 0x0f) | 0x50;
198 : 233 : uuid->u.raw[8] = (uuid->u.raw[8] & 0x3f) | 0x80;
199 : :
200 : 233 : return 0;
201 : :
202 : 0 : err:
203 : 0 : EVP_MD_CTX_free(mdctx);
204 : 0 : return -EINVAL;
205 : :
206 : : #endif /* SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1 */
207 : : }
|