--- uuid.c 2004/01/10 11:54:05 1.13
+++ uuid.c 2004/01/10 12:16:03 1.14
@@ -41,6 +41,7 @@
#include "config.h"
#include "uuid.h"
#include "uuid_md5.h"
+#include "uuid_prng.h"
#include "uuid_ui64.h"
/* determine types of 8-bit size */
@@ -118,7 +119,9 @@
/* abstract data type (ADT) of API */
struct uuid_st {
- uuid_obj_t obj;
+ uuid_obj_t obj; /* inlined UUID object */
+ prng_t *prng; /* RPNG sub-object */
+ md5_t *md5; /* MD5 sub-object */
};
/* create UUID object */
@@ -128,13 +131,19 @@
if (uuid == NULL)
return UUID_RC_ARG;
- /* allocate UUID binary representation buffer */
+ /* allocate UUID object */
if ((*uuid = (uuid_t *)malloc(sizeof(uuid_t))) == NULL)
return UUID_RC_MEM;
- /* set initially to "nil UUID" */
+ /* set UUID object initially to "nil UUID" */
uuid_nil(*uuid);
+ /* create PRNG and MD5 sub-objects */
+ if (prng_create(&(*uuid)->prng) != PRNG_RC_OK)
+ return UUID_RC_INT;
+ if (md5_create(&(*uuid)->md5) != MD5_RC_OK)
+ return UUID_RC_INT;
+
return UUID_RC_OK;
}
@@ -145,7 +154,11 @@
if (uuid == NULL)
return UUID_RC_ARG;
- /* free UUID binary representation buffer */
+ /* destroy PRNG and MD5 sub-objects */
+ prng_destroy(uuid->prng);
+ md5_destroy(uuid->md5);
+
+ /* free UUID object */
free(uuid);
return UUID_RC_OK;
@@ -432,68 +445,6 @@
return UUID_RC_OK;
}
-/* INTERNAL: pseudo-random number generator (PRNG) */
-static void uuid_prng_getdata(uuid_uint8_t *data_ptr, size_t data_len)
-{
- static int initialized = FALSE;
- static int fd = -1;
- struct timeval tv;
- pid_t pid;
- size_t n;
- size_t i;
- uuid_uint8_t *p;
- int cnt;
-
- if (!initialized) {
- /* try to open the system PRNG device */
- if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
- fd = open("/dev/random", O_RDONLY|O_NONBLOCK);
- if (fd != -1)
- fcntl(fd, F_SETFD, FD_CLOEXEC);
-
- /* seed the PRNG once */
- gettimeofday(&tv, NULL);
- pid = getpid();
- srand((unsigned int)(
- ((uuid_uint32_t)pid << 16)
- ^ (uuid_uint32_t)pid
- ^ (uuid_uint32_t)tv.tv_sec
- ^ (uuid_uint32_t)tv.tv_usec));
-
- /* crank the PRNG a few times */
- gettimeofday(&tv, NULL);
- for (i = (unsigned int)(tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
- (void)rand();
-
- initialized = TRUE;
- }
-
- /* try to gather data from the system PRNG device */
- if (fd != -1) {
- p = data_ptr;
- n = data_len;
- cnt = 0;
- while (n > 0) {
- i = read(fd, (void *)p, n);
- if (i <= 0) {
- if (cnt++ > 16)
- break;
- continue;
- }
- n -= i;
- p += i;
- cnt = 0;
- }
- }
-
- /* always also apply the weaker PRNG. In case the stronger PRNG device
- based source failed, this is the only remaining randomness, of course */
- for (p = data_ptr, n = 0; n < data_len; n++)
- *p++ ^= (uuid_uint8_t)(((uuid_uint32_t)rand() >> 7) & 0xFF);
-
- return;
-}
-
/* INTERNAL: brand UUID with version and variant */
static void uuid_brand(uuid_t *uuid, int version)
{
@@ -542,7 +493,6 @@
void *uuid_octets;
uuid_t *uuid_object;
uuid_rc_t rc;
- md5_t *md5;
int i;
/* determine namespace UUID name and argument name string */
@@ -551,8 +501,8 @@
if ((str = (char *)va_arg(ap, char *)) == NULL)
return UUID_RC_ARG;
- /* create MD5 context */
- if (md5_create(&md5) != MD5_RC_OK)
+ /* initialize MD5 context */
+ if (md5_init(uuid->md5) != MD5_RC_OK)
return UUID_RC_MEM;
/* load the namespace UUID into MD5 context */
@@ -564,7 +514,7 @@
return rc;
uuid_octets = (void *)&(uuid_object->obj);
uuid_pack(uuid_object, &uuid_octets);
- md5_update(md5, uuid_octets, UUID_LEN_BIN);
+ md5_update(uuid->md5, uuid_octets, UUID_LEN_BIN);
uuid_destroy(uuid_object);
}
else {
@@ -578,20 +528,17 @@
}
if (uuid_octets == NULL)
return UUID_RC_ARG;
- md5_update(md5, uuid_octets, UUID_LEN_BIN);
+ md5_update(uuid->md5, uuid_octets, UUID_LEN_BIN);
}
/* load the argument name string into MD5 context */
- md5_update(md5, str, strlen(str));
+ md5_update(uuid->md5, str, strlen(str));
/* store MD5 result into UUID
(requires MD5_LEN_BIN space, UUID_LEN_BIN space is available,
and both are equal in size, so we are safe!) */
uuid_octets = (void *)&(uuid->obj);
- md5_store(md5, &uuid_octets, NULL);
-
- /* destroy MD5 context */
- md5_destroy(md5);
+ md5_store(uuid->md5, &uuid_octets, NULL);
/* fulfill requirement of standard and convert UUID data into
local/host byte order (this uses fact that uuid_unpack() is
@@ -608,7 +555,7 @@
static uuid_rc_t uuid_generate_v4(uuid_t *uuid, unsigned int mode, va_list ap)
{
/* fill UUID with random data */
- uuid_prng_getdata((void *)&(uuid->obj), sizeof(uuid->obj));
+ prng_data(uuid->prng, (void *)&(uuid->obj), sizeof(uuid->obj));
/* brand UUID with version and variant */
uuid_brand(uuid, 4);
|