1  /*
2   * Universally Unique IDentifier (UUID)
3   * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
4   *
5   * This software may be distributed under the terms of the BSD license.
6   * See README for more details.
7   */
8  
9  #include "includes.h"
10  
11  #include "common.h"
12  #include "crypto/sha256.h"
13  #include "uuid.h"
14  
uuid_str2bin(const char * str,u8 * bin)15  int uuid_str2bin(const char *str, u8 *bin)
16  {
17  	const char *pos;
18  	u8 *opos;
19  
20  	pos = str;
21  	opos = bin;
22  
23  	if (hexstr2bin(pos, opos, 4))
24  		return -1;
25  	pos += 8;
26  	opos += 4;
27  
28  	if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
29  		return -1;
30  	pos += 4;
31  	opos += 2;
32  
33  	if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
34  		return -1;
35  	pos += 4;
36  	opos += 2;
37  
38  	if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
39  		return -1;
40  	pos += 4;
41  	opos += 2;
42  
43  	if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
44  		return -1;
45  
46  	return 0;
47  }
48  
49  
uuid_bin2str(const u8 * bin,char * str,size_t max_len)50  int uuid_bin2str(const u8 *bin, char *str, size_t max_len)
51  {
52  	int len;
53  	len = os_snprintf(str, max_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
54  			  "%02x%02x-%02x%02x%02x%02x%02x%02x",
55  			  bin[0], bin[1], bin[2], bin[3],
56  			  bin[4], bin[5], bin[6], bin[7],
57  			  bin[8], bin[9], bin[10], bin[11],
58  			  bin[12], bin[13], bin[14], bin[15]);
59  	if (os_snprintf_error(max_len, len))
60  		return -1;
61  	return 0;
62  }
63  
64  
is_nil_uuid(const u8 * uuid)65  int is_nil_uuid(const u8 *uuid)
66  {
67  	int i;
68  	for (i = 0; i < UUID_LEN; i++)
69  		if (uuid[i])
70  			return 0;
71  	return 1;
72  }
73  
74  
uuid_random(u8 * uuid)75  int uuid_random(u8 *uuid)
76  {
77  	struct os_time t;
78  	u8 hash[SHA256_MAC_LEN];
79  
80  	/* Use HMAC-SHA256 and timestamp as context to avoid exposing direct
81  	 * os_get_random() output in the UUID field. */
82  	os_get_time(&t);
83  	if (os_get_random(uuid, UUID_LEN) < 0 ||
84  	    hmac_sha256(uuid, UUID_LEN, (const u8 *) &t, sizeof(t), hash) < 0)
85  		return -1;
86  
87  	os_memcpy(uuid, hash, UUID_LEN);
88  
89  	/* Version: 4 = random */
90  	uuid[6] = (4 << 4) | (uuid[6] & 0x0f);
91  
92  	/* Variant specified in RFC 4122 */
93  	uuid[8] = 0x80 | (uuid[8] & 0x3f);
94  
95  	return 0;
96  }
97