1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2012 Milan Jurik. All rights reserved. 25 * Copyright 2014 Joyent, Inc. All rights reserved. 26 * Copyright 2014 Andrew Stormont. 27 */ 28 29 /* 30 * The copyright in this file is taken from the original Leach & Salz 31 * UUID specification, from which this implementation is derived. 32 */ 33 34 /* 35 * Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. 36 * Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & 37 * Digital Equipment Corporation, Maynard, Mass. Copyright (c) 1998 38 * Microsoft. To anyone who acknowledges that this file is provided 39 * "AS IS" without any express or implied warranty: permission to use, 40 * copy, modify, and distribute this file for any purpose is hereby 41 * granted without fee, provided that the above copyright notices and 42 * this notice appears in all source code copies, and that none of the 43 * names of Open Software Foundation, Inc., Hewlett-Packard Company, 44 * or Digital Equipment Corporation be used in advertising or 45 * publicity pertaining to distribution of the software without 46 * specific, written prior permission. Neither Open Software 47 * Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital 48 * Equipment Corporation makes any representations about the 49 * suitability of this software for any purpose. 50 */ 51 52 /* 53 * This module is the workhorse for generating abstract 54 * UUIDs. It delegates system-specific tasks (such 55 * as obtaining the node identifier or system time) 56 * to the sysdep module. 57 */ 58 59 #include <ctype.h> 60 #include <sys/param.h> 61 #include <sys/stat.h> 62 #include <errno.h> 63 #include <stdio.h> 64 #include <stdlib.h> 65 #include <strings.h> 66 #include <fcntl.h> 67 #include <unistd.h> 68 #include <synch.h> 69 #include <sys/mman.h> 70 #include "uuid_misc.h" 71 72 shared_buffer_t *data; 73 74 static uuid_node_t node_id_cache; 75 static int node_init; 76 static int file_type; 77 static int fd; 78 79 /* 80 * The urandmtx mutex prevents multiple opens of /dev/urandom and protects the 81 * cache. 82 */ 83 #define RCACHE_SIZE 65535 84 static mutex_t urandmtx; 85 static int fd_urand = -1; 86 static char rcache[RCACHE_SIZE]; 87 static char *rcachep = rcache; 88 89 /* 90 * misc routines 91 */ 92 uint16_t get_random(void); 93 void get_current_time(uuid_time_t *); 94 95 void struct_to_string(uuid_t, struct uuid *); 96 void string_to_struct(struct uuid *, uuid_t); 97 int get_ethernet_address(uuid_node_t *); 98 99 /* 100 * local functions 101 */ 102 static int map_state(); 103 static void format_uuid(struct uuid *, uint16_t, uuid_time_t, 104 uuid_node_t); 105 static void fill_random_bytes(uchar_t *, int); 106 static int uuid_create(struct uuid *); 107 static void gen_ethernet_address(uuid_node_t *); 108 static void revalidate_data(uuid_node_t *); 109 110 /* 111 * Generates a uuid based on version 1 format. 112 * Returns 0 on success and -1 on failure. 113 */ 114 static int 115 uuid_create(struct uuid *uuid) 116 { 117 uuid_time_t timestamp; 118 uuid_node_t system_node; 119 int ret, non_unique = 0; 120 121 /* 122 * Get the system MAC address and/or cache it 123 */ 124 if (node_init) { 125 bcopy(&node_id_cache, &system_node, sizeof (uuid_node_t)); 126 } else { 127 gen_ethernet_address(&system_node); 128 bcopy(&system_node, &node_id_cache, sizeof (uuid_node_t)); 129 node_init = 1; 130 } 131 132 /* 133 * Access the state file, mmap it and initialize the shared lock. 134 * file_type tells us whether we had access to the state file or 135 * created a temporary one. 136 */ 137 if (map_state() == -1) 138 return (-1); 139 140 /* 141 * Acquire the lock 142 */ 143 for (;;) { 144 if ((ret = mutex_lock(&data->lock)) == 0) 145 break; 146 else 147 switch (ret) { 148 case EOWNERDEAD: 149 revalidate_data(&system_node); 150 (void) mutex_consistent(&data->lock); 151 (void) mutex_unlock(&data->lock); 152 break; 153 case ENOTRECOVERABLE: 154 return (ret); 155 } 156 } 157 158 /* State file is either new or is temporary, get a random clock seq */ 159 if (data->state.clock == 0) { 160 data->state.clock = get_random(); 161 non_unique++; 162 } 163 164 if (memcmp(&system_node, &data->state.node, sizeof (uuid_node_t)) != 0) 165 data->state.clock++; 166 167 get_current_time(×tamp); 168 169 /* 170 * If timestamp is not set or is not in the past, bump 171 * data->state.clock 172 */ 173 if ((data->state.ts == 0) || (data->state.ts >= timestamp)) { 174 data->state.clock++; 175 data->state.ts = timestamp; 176 } 177 178 if (non_unique) 179 system_node.nodeID[0] |= 0x80; 180 181 /* Stuff fields into the UUID struct */ 182 format_uuid(uuid, data->state.clock, timestamp, system_node); 183 184 (void) mutex_unlock(&data->lock); 185 186 return (0); 187 } 188 189 /* 190 * Fills system_node with Ethernet address if available, 191 * else fills random numbers 192 */ 193 static void 194 gen_ethernet_address(uuid_node_t *system_node) 195 { 196 uchar_t node[6]; 197 198 if (get_ethernet_address(system_node) != 0) { 199 fill_random_bytes(node, 6); 200 (void) memcpy(system_node->nodeID, node, 6); 201 /* 202 * use 8:0:20 with the multicast bit set 203 * to avoid namespace collisions. 204 */ 205 system_node->nodeID[0] = 0x88; 206 system_node->nodeID[1] = 0x00; 207 system_node->nodeID[2] = 0x20; 208 } 209 } 210 211 /* 212 * Formats a UUID, given the clock_seq timestamp, and node address. 213 * Fills in passed-in pointer with the resulting uuid. 214 */ 215 static void 216 format_uuid(struct uuid *uuid, uint16_t clock_seq, 217 uuid_time_t timestamp, uuid_node_t node) 218 { 219 220 /* 221 * First set up the first 60 bits from the timestamp 222 */ 223 uuid->time_low = (uint32_t)(timestamp & 0xFFFFFFFF); 224 uuid->time_mid = (uint16_t)((timestamp >> 32) & 0xFFFF); 225 uuid->time_hi_and_version = (uint16_t)((timestamp >> 48) & 0x0FFF); 226 227 /* 228 * This is version 1, so say so in the UUID version field (4 bits) 229 */ 230 uuid->time_hi_and_version |= (1 << 12); 231 232 /* 233 * Now do the clock sequence 234 */ 235 uuid->clock_seq_low = clock_seq & 0xFF; 236 237 /* 238 * We must save the most-significant 2 bits for the reserved field 239 */ 240 uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; 241 242 /* 243 * The variant for this format is the 2 high bits set to 10, 244 * so here it is 245 */ 246 uuid->clock_seq_hi_and_reserved |= 0x80; 247 248 /* 249 * write result to passed-in pointer 250 */ 251 (void) memcpy(&uuid->node_addr, &node, sizeof (uuid->node_addr)); 252 } 253 254 /* 255 * Opens/creates the state file, falling back to a tmp 256 */ 257 static int 258 map_state() 259 { 260 FILE *tmp; 261 262 /* If file's mapped, return */ 263 if (file_type != 0) 264 return (1); 265 266 if ((fd = open(STATE_LOCATION, O_RDWR)) < 0) { 267 file_type = TEMP_FILE; 268 269 if ((tmp = tmpfile()) == NULL) 270 return (-1); 271 else 272 fd = fileno(tmp); 273 } else { 274 file_type = STATE_FILE; 275 } 276 277 (void) ftruncate(fd, (off_t)sizeof (shared_buffer_t)); 278 279 /* LINTED - alignment */ 280 data = (shared_buffer_t *)mmap(NULL, sizeof (shared_buffer_t), 281 PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 282 283 if (data == MAP_FAILED) 284 return (-1); 285 286 (void) mutex_init(&data->lock, USYNC_PROCESS|LOCK_ROBUST, 0); 287 288 (void) close(fd); 289 290 return (1); 291 } 292 293 static void 294 revalidate_data(uuid_node_t *node) 295 { 296 int i; 297 298 data->state.ts = 0; 299 300 for (i = 0; i < sizeof (data->state.node.nodeID); i++) 301 data->state.node.nodeID[i] = 0; 302 303 data->state.clock = 0; 304 305 gen_ethernet_address(node); 306 bcopy(node, &node_id_cache, sizeof (uuid_node_t)); 307 node_init = 1; 308 } 309 310 /* 311 * Prints a nicely-formatted uuid to stdout. 312 */ 313 void 314 uuid_print(struct uuid u) 315 { 316 int i; 317 318 (void) printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, 319 u.time_hi_and_version, u.clock_seq_hi_and_reserved, 320 u.clock_seq_low); 321 for (i = 0; i < 6; i++) 322 (void) printf("%2.2x", u.node_addr[i]); 323 (void) printf("\n"); 324 } 325 326 /* 327 * Only called with urandmtx held. 328 * Fills/refills the cache of randomness. We know that our allocations of 329 * randomness are always much less than the total size of the cache. 330 * Tries to use /dev/urandom random number generator - if that fails for some 331 * reason, it retries MAX_RETRY times then sets rcachep to NULL so we no 332 * longer use the cache. 333 */ 334 static void 335 load_cache() 336 { 337 int i, retries = 0; 338 int nbytes = RCACHE_SIZE; 339 char *buf = rcache; 340 341 while (nbytes > 0) { 342 i = read(fd_urand, buf, nbytes); 343 if ((i < 0) && (errno == EINTR)) { 344 continue; 345 } 346 if (i <= 0) { 347 if (retries++ == MAX_RETRY) 348 break; 349 continue; 350 } 351 nbytes -= i; 352 buf += i; 353 retries = 0; 354 } 355 if (nbytes == 0) 356 rcachep = rcache; 357 else 358 rcachep = NULL; 359 } 360 361 static void 362 close_pre() 363 { 364 (void) mutex_lock(&urandmtx); 365 } 366 367 static void 368 close_parent() 369 { 370 (void) mutex_unlock(&urandmtx); 371 } 372 373 static void 374 close_child() 375 { 376 if (fd_urand != -1) { 377 (void) close(fd_urand); 378 fd_urand = -1; 379 } 380 (void) mutex_unlock(&urandmtx); 381 } 382 383 #pragma init(cache_init) 384 static void 385 cache_init(void) 386 { 387 (void) pthread_atfork(close_pre, close_parent, close_child); 388 } 389 390 /* 391 * Fills buf with random numbers - nbytes is the number of bytes 392 * to fill-in. Tries to use cached data from the /dev/urandom random number 393 * generator - if that fails for some reason, it uses srand48(3C) 394 */ 395 static void 396 fill_random_bytes(uchar_t *buf, int nbytes) 397 { 398 int i; 399 400 if (fd_urand == -1) { 401 (void) mutex_lock(&urandmtx); 402 /* check again now that we have the mutex */ 403 if (fd_urand == -1) { 404 if ((fd_urand = open(URANDOM_PATH, 405 O_RDONLY | O_CLOEXEC)) >= 0) 406 load_cache(); 407 } 408 (void) mutex_unlock(&urandmtx); 409 } 410 if (fd_urand >= 0 && rcachep != NULL) { 411 int cnt; 412 413 (void) mutex_lock(&urandmtx); 414 if (rcachep != NULL && 415 (rcachep + nbytes) >= (rcache + RCACHE_SIZE)) 416 load_cache(); 417 418 if (rcachep != NULL) { 419 for (cnt = 0; cnt < nbytes; cnt++) 420 *buf++ = *rcachep++; 421 (void) mutex_unlock(&urandmtx); 422 return; 423 } 424 (void) mutex_unlock(&urandmtx); 425 } 426 for (i = 0; i < nbytes; i++) { 427 *buf++ = get_random() & 0xFF; 428 } 429 } 430 431 /* 432 * Unpacks the structure members in "struct uuid" to a char string "uuid_t". 433 */ 434 void 435 struct_to_string(uuid_t ptr, struct uuid *uu) 436 { 437 uint_t tmp; 438 uchar_t *out = ptr; 439 440 tmp = uu->time_low; 441 out[3] = (uchar_t)tmp; 442 tmp >>= 8; 443 out[2] = (uchar_t)tmp; 444 tmp >>= 8; 445 out[1] = (uchar_t)tmp; 446 tmp >>= 8; 447 out[0] = (uchar_t)tmp; 448 449 tmp = uu->time_mid; 450 out[5] = (uchar_t)tmp; 451 tmp >>= 8; 452 out[4] = (uchar_t)tmp; 453 454 tmp = uu->time_hi_and_version; 455 out[7] = (uchar_t)tmp; 456 tmp >>= 8; 457 out[6] = (uchar_t)tmp; 458 459 tmp = uu->clock_seq_hi_and_reserved; 460 out[8] = (uchar_t)tmp; 461 tmp = uu->clock_seq_low; 462 out[9] = (uchar_t)tmp; 463 464 (void) memcpy(out+10, uu->node_addr, 6); 465 466 } 467 468 /* 469 * Packs the values in the "uuid_t" string into "struct uuid". 470 */ 471 void 472 string_to_struct(struct uuid *uuid, uuid_t in) 473 { 474 uchar_t *ptr; 475 uint_t tmp; 476 477 ptr = in; 478 479 tmp = *ptr++; 480 tmp = (tmp << 8) | *ptr++; 481 tmp = (tmp << 8) | *ptr++; 482 tmp = (tmp << 8) | *ptr++; 483 uuid->time_low = tmp; 484 485 tmp = *ptr++; 486 tmp = (tmp << 8) | *ptr++; 487 uuid->time_mid = tmp; 488 489 tmp = *ptr++; 490 tmp = (tmp << 8) | *ptr++; 491 uuid->time_hi_and_version = tmp; 492 493 tmp = *ptr++; 494 uuid->clock_seq_hi_and_reserved = tmp; 495 496 tmp = *ptr++; 497 uuid->clock_seq_low = tmp; 498 499 (void) memcpy(uuid->node_addr, ptr, 6); 500 501 } 502 503 /* 504 * Generates UUID based on DCE Version 4 505 */ 506 void 507 uuid_generate_random(uuid_t uu) 508 { 509 struct uuid uuid; 510 511 if (uu == NULL) 512 return; 513 514 (void) memset(uu, 0, sizeof (uuid_t)); 515 (void) memset(&uuid, 0, sizeof (struct uuid)); 516 517 fill_random_bytes(uu, sizeof (uuid_t)); 518 string_to_struct(&uuid, uu); 519 /* 520 * This is version 4, so say so in the UUID version field (4 bits) 521 */ 522 uuid.time_hi_and_version |= (1 << 14); 523 /* 524 * we don't want the bit 1 to be set also which is for version 1 525 */ 526 uuid.time_hi_and_version &= VER1_MASK; 527 528 /* 529 * The variant for this format is the 2 high bits set to 10, 530 * so here it is 531 */ 532 uuid.clock_seq_hi_and_reserved |= 0x80; 533 534 /* 535 * Set MSB of Ethernet address to 1 to indicate that it was generated 536 * randomly 537 */ 538 uuid.node_addr[0] |= 0x80; 539 struct_to_string(uu, &uuid); 540 } 541 542 /* 543 * Generates UUID based on DCE Version 1. 544 */ 545 void 546 uuid_generate_time(uuid_t uu) 547 { 548 struct uuid uuid; 549 550 if (uu == NULL) 551 return; 552 553 if (uuid_create(&uuid) < 0) { 554 uuid_generate_random(uu); 555 return; 556 } 557 558 struct_to_string(uu, &uuid); 559 } 560 561 /* 562 * Creates a new UUID. The uuid will be generated based on high-quality 563 * randomness from /dev/urandom, if available by calling uuid_generate_random. 564 * If it failed to generate UUID then uuid_generate will call 565 * uuid_generate_time. 566 */ 567 void 568 uuid_generate(uuid_t uu) 569 { 570 if (uu == NULL) { 571 return; 572 } 573 if (fd_urand == -1) { 574 (void) mutex_lock(&urandmtx); 575 /* check again now that we have the mutex */ 576 if (fd_urand == -1) { 577 if ((fd_urand = open(URANDOM_PATH, O_RDONLY)) >= 0) 578 load_cache(); 579 } 580 (void) mutex_unlock(&urandmtx); 581 } 582 if (fd_urand >= 0) { 583 uuid_generate_random(uu); 584 } else { 585 (void) uuid_generate_time(uu); 586 } 587 } 588 589 /* 590 * Copies the UUID variable src to dst. 591 */ 592 void 593 uuid_copy(uuid_t dst, uuid_t src) 594 { 595 (void) memcpy(dst, src, UUID_LEN); 596 } 597 598 /* 599 * Sets the value of the supplied uuid variable uu, to the NULL value. 600 */ 601 void 602 uuid_clear(uuid_t uu) 603 { 604 (void) memset(uu, 0, UUID_LEN); 605 } 606 607 /* 608 * This function converts the supplied UUID uu from the internal 609 * binary format into a 36-byte string (plus trailing null char) 610 * and stores this value in the character string pointed to by out. 611 */ 612 static void 613 uuid_unparse_common(uuid_t uu, char *out, boolean_t upper) 614 { 615 struct uuid uuid; 616 uint16_t clock_seq; 617 char etheraddr[13]; 618 int index = 0, i; 619 620 /* basic sanity checking */ 621 if (uu == NULL) { 622 return; 623 } 624 625 string_to_struct(&uuid, uu); 626 clock_seq = uuid.clock_seq_hi_and_reserved; 627 clock_seq = (clock_seq << 8) | uuid.clock_seq_low; 628 for (i = 0; i < 6; i++) { 629 (void) sprintf(ðeraddr[index++], upper ? "%.2X" : "%.2x", 630 uuid.node_addr[i]); 631 index++; 632 } 633 etheraddr[index] = '\0'; 634 635 (void) snprintf(out, 25, 636 upper ? "%08X-%04X-%04X-%04X-" : "%08x-%04x-%04x-%04x-", 637 uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, clock_seq); 638 (void) strlcat(out, etheraddr, UUID_PRINTABLE_STRING_LENGTH); 639 } 640 641 void 642 uuid_unparse_upper(uuid_t uu, char *out) 643 { 644 uuid_unparse_common(uu, out, B_TRUE); 645 } 646 647 void 648 uuid_unparse_lower(uuid_t uu, char *out) 649 { 650 uuid_unparse_common(uu, out, B_FALSE); 651 } 652 653 void 654 uuid_unparse(uuid_t uu, char *out) 655 { 656 /* 657 * Historically uuid_unparse on Solaris returns lower case, 658 * for compatibility we preserve this behaviour. 659 */ 660 uuid_unparse_common(uu, out, B_FALSE); 661 } 662 663 /* 664 * The uuid_is_null function compares the value of the supplied 665 * UUID variable uu to the NULL value. If the value is equal 666 * to the NULL UUID, 1 is returned, otherwise 0 is returned. 667 */ 668 int 669 uuid_is_null(uuid_t uu) 670 { 671 int i; 672 uuid_t null_uu; 673 674 (void) memset(null_uu, 0, sizeof (uuid_t)); 675 i = memcmp(uu, null_uu, sizeof (uuid_t)); 676 if (i == 0) { 677 /* uu is NULL uuid */ 678 return (1); 679 } else { 680 return (0); 681 } 682 } 683 684 /* 685 * uuid_parse converts the UUID string given by 'in' into the 686 * internal uuid_t format. The input UUID is a string of the form 687 * cefa7a9c-1dd2-11b2-8350-880020adbeef in printf(3C) format. 688 * Upon successfully parsing the input string, UUID is stored 689 * in the location pointed to by uu 690 */ 691 int 692 uuid_parse(char *in, uuid_t uu) 693 { 694 695 char *ptr, buf[3]; 696 int i; 697 struct uuid uuid; 698 uint16_t clock_seq; 699 700 /* do some sanity checking */ 701 if ((strlen(in) != 36) || (uu == NULL) || (in[36] != '\0')) { 702 return (-1); 703 } 704 705 ptr = in; 706 for (i = 0; i < 36; i++, ptr++) { 707 if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { 708 if (*ptr != '-') { 709 return (-1); 710 } 711 } else { 712 if (!isxdigit(*ptr)) { 713 return (-1); 714 } 715 } 716 } 717 718 uuid.time_low = strtoul(in, NULL, 16); 719 uuid.time_mid = strtoul(in+9, NULL, 16); 720 uuid.time_hi_and_version = strtoul(in+14, NULL, 16); 721 clock_seq = strtoul(in+19, NULL, 16); 722 uuid.clock_seq_hi_and_reserved = (clock_seq & 0xFF00) >> 8; 723 uuid.clock_seq_low = (clock_seq & 0xFF); 724 725 ptr = in+24; 726 buf[2] = '\0'; 727 for (i = 0; i < 6; i++) { 728 buf[0] = *ptr++; 729 buf[1] = *ptr++; 730 uuid.node_addr[i] = strtoul(buf, NULL, 16); 731 } 732 struct_to_string(uu, &uuid); 733 return (0); 734 } 735 736 /* 737 * uuid_time extracts the time at which the supplied UUID uu 738 * was created. This function can only extract the creation 739 * time for UUIDs created with the uuid_generate_time function. 740 * The time at which the UUID was created, in seconds and 741 * microseconds since the epoch is stored in the location 742 * pointed to by ret_tv. 743 */ 744 time_t 745 uuid_time(uuid_t uu, struct timeval *ret_tv) 746 { 747 struct uuid uuid; 748 uint_t high; 749 struct timeval tv; 750 u_longlong_t clock_reg; 751 uint_t tmp; 752 uint8_t clk; 753 754 string_to_struct(&uuid, uu); 755 tmp = (uuid.time_hi_and_version & 0xF000) >> 12; 756 clk = uuid.clock_seq_hi_and_reserved; 757 758 /* check if uu is NULL, Version = 1 of DCE and Variant = 0b10x */ 759 if ((uu == NULL) || ((tmp & 0x01) != 0x01) || ((clk & 0x80) != 0x80)) { 760 return (-1); 761 } 762 high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16); 763 clock_reg = uuid.time_low | ((u_longlong_t)high << 32); 764 765 clock_reg -= (((u_longlong_t)0x01B21DD2) << 32) + 0x13814000; 766 tv.tv_sec = clock_reg / 10000000; 767 tv.tv_usec = (clock_reg % 10000000) / 10; 768 769 if (ret_tv) { 770 *ret_tv = tv; 771 } 772 773 return (tv.tv_sec); 774 } 775