Revision: 196 http://trac.macosforge.org/projects/libdispatch/changeset/196 Author: jkh@apple.com Date: 2010-12-23 13:57:41 -0800 (Thu, 23 Dec 2010) Log Message: ----------- Whoops! I knew I was forgetting something on that last commit. Added Paths: ----------- trunk/testing/os_shims.h trunk/testing/shims/ trunk/testing/shims/arc4random.c trunk/testing/shims/arc4random.h trunk/testing/shims/asprintf.c trunk/testing/shims/asprintf.h trunk/testing/shims/fgetln.c trunk/testing/shims/fgetln.h Added: trunk/testing/os_shims.h =================================================================== --- trunk/testing/os_shims.h (rev 0) +++ trunk/testing/os_shims.h 2010-12-23 21:57:41 UTC (rev 196) @@ -0,0 +1,30 @@ +/* + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + + +#ifndef __DISPATCH_TESTS_OS_SHIMS__ +#define __DISPATCH_TESTS_OS_SHIMS__ + +#include "config/config.h" + +#include "shims/asprintf.h" +#include "shims/arc4random.h" +#include "shims/fgetln.h" + +#endif /* __DISPATCH_TESTS_OS_SHIMS__ */ + Added: trunk/testing/shims/arc4random.c =================================================================== --- trunk/testing/shims/arc4random.c (rev 0) +++ trunk/testing/shims/arc4random.c 2010-12-23 21:57:41 UTC (rev 196) @@ -0,0 +1,241 @@ +/* + * arc4random() for libdispatch + * + * Based on http://www.opensource.apple.com/source/Libc/Libc-594.9.1/gen/FreeBSD/arc4ran... + * + * + * Arc4 random number generator for OpenBSD. + * Copyright 1996 David Mazieres <dm@lcs.mit.edu>. + * + * Modification and redistribution in source and binary forms is + * permitted provided that due credit is given to the author and the + * OpenBSD project (for instance by leaving this copyright notice + * intact). + */ + +/* + * This code is derived from section 17.1 of Applied Cryptography, + * second edition, which describes a stream cipher allegedly + * compatible with RSA Labs "RC4" cipher (the actual description of + * which is a trade secret). The same algorithm is used as a stream + * cipher called "arcfour" in Tatu Ylonen's ssh package. + * + * Here the stream cipher has been modified always to include the time + * when initializing the state. That makes it impossible to + * regenerate the same random sequence twice, so this can't be used + * for encryption, but will generate good random numbers. + * + * RC4 is a registered trademark of RSA Laboratories. + */ + +#include "config/config.h" + +#ifndef HAVE_ARC4RANDOM + +#include <sys/types.h> +#include <sys/time.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <pthread.h> + +struct arc4_stream { + uint8_t i; + uint8_t j; + uint8_t s[256]; +}; + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; + +#define __isthreaded 1 +#define RANDOMDEV "/dev/urandom" +#define THREAD_LOCK() \ + do { \ + if (__isthreaded) \ + pthread_mutex_lock(&arc4random_mtx); \ + } while (0) + +#define THREAD_UNLOCK() \ + do { \ + if (__isthreaded) \ + pthread_mutex_unlock(&arc4random_mtx); \ + } while (0) + +static struct arc4_stream rs; +static int rs_initialized; +static int rs_stired; + +static inline uint8_t arc4_getbyte(struct arc4_stream *); +static void arc4_stir(struct arc4_stream *); + +static inline void +arc4_init(as) + struct arc4_stream *as; +{ + int n; + + for (n = 0; n < 256; n++) + as->s[n] = n; + as->i = 0; + as->j = 0; +} + +static inline void +arc4_addrandom(as, dat, datlen) + struct arc4_stream *as; + u_char *dat; + int datlen; +{ + int n; + uint8_t si; + + as->i--; + for (n = 0; n < 256; n++) { + as->i = (as->i + 1); + si = as->s[as->i]; + as->j = (as->j + si + dat[n % datlen]); + as->s[as->i] = as->s[as->j]; + as->s[as->j] = si; + } +} + +static void +arc4_stir(as) + struct arc4_stream *as; +{ + int fd, n; + struct { + struct timeval tv; + pid_t pid; + uint8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)]; + } rdat; + + gettimeofday(&rdat.tv, NULL); + rdat.pid = getpid(); + fd = open(RANDOMDEV, O_RDONLY, 0); + if (fd >= 0) { + (void) read(fd, rdat.rnd, sizeof(rdat.rnd)); + close(fd); + } + /* fd < 0? Ah, what the heck. We'll just take whatever was on the + * stack... */ + + arc4_addrandom(as, (void *) &rdat, sizeof(rdat)); + + /* + * Throw away the first N bytes of output, as suggested in the + * paper "Weaknesses in the Key Scheduling Algorithm of RC4" + * by Fluher, Mantin, and Shamir. N=1024 is based on + * suggestions in the paper "(Not So) Random Shuffles of RC4" + * by Ilya Mironov. + */ + for (n = 0; n < 1024; n++) + arc4_getbyte(as); +} + +static inline uint8_t +arc4_getbyte(as) + struct arc4_stream *as; +{ + uint8_t si, sj; + + as->i = (as->i + 1); + si = as->s[as->i]; + as->j = (as->j + si); + sj = as->s[as->j]; + as->s[as->i] = sj; + as->s[as->j] = si; + + return (as->s[(si + sj) & 0xff]); +} + +static inline uint32_t +arc4_getword(as) + struct arc4_stream *as; +{ + uint32_t val; + + val = arc4_getbyte(as) << 24; + val |= arc4_getbyte(as) << 16; + val |= arc4_getbyte(as) << 8; + val |= arc4_getbyte(as); + + return (val); +} + +static void +arc4_check_init(void) +{ + if (!rs_initialized) { + arc4_init(&rs); + rs_initialized = 1; + } +} + +static void +arc4_check_stir(void) +{ + if (!rs_stired) { + arc4_stir(&rs); + rs_stired = 1; + } +} + +void +arc4random_stir() +{ + THREAD_LOCK(); + arc4_check_init(); + arc4_stir(&rs); + THREAD_UNLOCK(); +} + +void +arc4random_addrandom(dat, datlen) + u_char *dat; + int datlen; +{ + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); + arc4_addrandom(&rs, dat, datlen); + THREAD_UNLOCK(); +} + +uint32_t +arc4random() +{ + uint32_t rnd; + + THREAD_LOCK(); + arc4_check_init(); + arc4_check_stir(); + rnd = arc4_getword(&rs); + THREAD_UNLOCK(); + + return (rnd); +} + +#if 0 +/*-------- Test code for i386 --------*/ +#include <stdio.h> +#include <machine/pctr.h> +int +main(int argc, char **argv) +{ + const int iter = 1000000; + int i; + pctrval v; + + v = rdtsc(); + for (i = 0; i < iter; i++) + arc4random(); + v = rdtsc() - v; + v /= iter; + + printf("%qd cycles\n", v); +} +#endif + +#endif /* HAVE_ARC4RANDOM */ + Added: trunk/testing/shims/arc4random.h =================================================================== --- trunk/testing/shims/arc4random.h (rev 0) +++ trunk/testing/shims/arc4random.h 2010-12-23 21:57:41 UTC (rev 196) @@ -0,0 +1,29 @@ +/* + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + + +#ifndef __DISPATCH_TESTS_SHIMS_ARC4RANDOM__ +#define __DISPATCH_TESTS_SHIMS_ARC4RANDOM__ + +#ifndef HAVE_ARC4RANDOM +unsigned int arc4random(); +#endif + +#endif /* __DISPATCH_TESTS_SHIMS_ARC4RANDOM__ */ + + Added: trunk/testing/shims/asprintf.c =================================================================== --- trunk/testing/shims/asprintf.c (rev 0) +++ trunk/testing/shims/asprintf.c 2010-12-23 21:57:41 UTC (rev 196) @@ -0,0 +1,95 @@ +/* + * libdispatch asprintf portability shim, based on + * http://www.opensource.apple.com/source/OpenSSH/OpenSSH-142/openssh/openbsd-c... + * + * + * Copyright (c) 2004 Darren Tucker. + * + * Based originally on asprintf.c from OpenBSD: + * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config/config.h" + +#ifndef HAVE_VASPRINTF + +#include <stdio.h> +#include <errno.h> +#include <stdarg.h> +#include <stdlib.h> +#include <sys/types.h> + +#define INIT_SZ 128 + +int +vasprintf(char **str, const char *fmt, va_list ap) +{ + int ret = -1; + va_list ap2; + char *string, *newstr; + size_t len; + + va_copy(ap2, ap); + if ((string = malloc(INIT_SZ)) == NULL) + goto fail; + + ret = vsnprintf(string, INIT_SZ, fmt, ap2); + if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ + *str = string; + } else if (ret < 0) { /* Bad length */ + free(string); + goto fail; + } else { /* bigger than initial, realloc allowing for nul */ + len = (size_t)ret + 1; + if ((newstr = realloc(string, len)) == NULL) { + free(string); + goto fail; + } else { + va_end(ap2); + va_copy(ap2, ap); + ret = vsnprintf(newstr, len, fmt, ap2); + if (ret >= 0 && (size_t)ret < len) { + *str = newstr; + } else { /* failed with realloc'ed string, give up */ + free(newstr); + goto fail; + } + } + } + va_end(ap2); + return (ret); + +fail: + *str = NULL; + errno = ENOMEM; + va_end(ap2); + return (-1); +} +#endif + +#ifndef HAVE_ASPRINTF +int asprintf(char **str, const char *fmt, ...) +{ + va_list ap; + int ret; + + *str = NULL; + va_start(ap, fmt); + ret = vasprintf(str, fmt, ap); + va_end(ap); + + return ret; +} +#endif Added: trunk/testing/shims/asprintf.h =================================================================== --- trunk/testing/shims/asprintf.h (rev 0) +++ trunk/testing/shims/asprintf.h 2010-12-23 21:57:41 UTC (rev 196) @@ -0,0 +1,27 @@ +/* + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + + +#ifndef __DISPATCH_TESTS_SHIMS_ASPRINTF__ +#define __DISPATCH_TESTS_SHIMS_ASPRINTF__ + +#ifndef HAVE_ASPRINTF +int asprintf(char **str, const char *fmt, ...); +#endif + +#endif /* __DISPATCH_TESTS_SHIMS_ASPRINTF__ */ Added: trunk/testing/shims/fgetln.c =================================================================== --- trunk/testing/shims/fgetln.c (rev 0) +++ trunk/testing/shims/fgetln.c 2010-12-23 21:57:41 UTC (rev 196) @@ -0,0 +1,93 @@ +/* $NetBSD: fgetln.c,v 1.3 2006/09/25 07:18:17 lukem Exp $ */ + +/*- + * libdispatch fgetln shim + * Based on http://www.opensource.apple.com/source/lukemftpd/lukemftpd-32/tnftpd/libnetb... + * + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config/config.h" + +#ifndef HAVE_FGETLN + +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <errno.h> + +char * +fgetln(fp, len) + FILE *fp; + size_t *len; +{ + static char *buf = NULL; + static size_t bufsiz = 0; + char *ptr; + + + if (buf == NULL) { + bufsiz = BUFSIZ; + if ((buf = malloc(bufsiz)) == NULL) + return NULL; + } + + if (fgets(buf, bufsiz, fp) == NULL) + return NULL; + + *len = 0; + while ((ptr = strchr(&buf[*len], '\n')) == NULL) { + size_t nbufsiz = bufsiz + BUFSIZ; + char *nbuf = realloc(buf, nbufsiz); + + if (nbuf == NULL) { + int oerrno = errno; + free(buf); + errno = oerrno; + buf = NULL; + return NULL; + } else + buf = nbuf; + + *len = bufsiz; + if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) + return buf; + + bufsiz = nbufsiz; + } + + *len = (ptr - buf) + 1; + return buf; +} + +#endif /* #ifndef HAVE_FGETLN */ + + Added: trunk/testing/shims/fgetln.h =================================================================== --- trunk/testing/shims/fgetln.h (rev 0) +++ trunk/testing/shims/fgetln.h 2010-12-23 21:57:41 UTC (rev 196) @@ -0,0 +1,29 @@ +/* + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + + +#ifndef __DISPATCH_TESTS_SHIMS_FGETLN__ +#define __DISPATCH_TESTS_SHIMS_FGETLN__ + +#ifndef HAVE_FGETLN +#include <stdio.h> + +char *fgetln(FILE *stream, size_t *len); +#endif + +#endif /* __DISPATCH_TESTS_SHIMS_FGETLN__ */
participants (1)
-
source_changes@macosforge.org