]>
git.saurik.com Git - apple/security.git/blob - SecurityServer/MacYarrow/YarrowServer/systemEntropy.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
22 Contains: System entropy collector, using
23 sysctl(CTL_KERN:KERN_KDEBUG) trace info
25 Copyright: (C) 2000 by Apple Computer, Inc., all rights reserved
27 Written by: Doug Mitchell <dmitch@apple.com>
30 #include "systemEntropy.h"
33 /* support for sysctl */
35 #include <sys/types.h>
36 #include <sys/param.h>
39 #include <sys/kdebug.h>
40 #include <sys/sysctl.h>
41 #include <sys/errno.h>
44 /* this should eventually come from private system headers */
45 #include "kdebug_private.h"
47 /* time to gather trace info */
48 #define MS_TO_SLEEP 100
50 static int set_remove();
51 static int set_init();
52 static int set_enable(int val
);
53 static int set_numbufs(int nbufs
);
55 /* start collecting system entropy */
56 int systemEntropyBegin(UInt32 bufSize
)
60 /* start from clean slate */
64 * This will result in a ENOENT error if we're not root.
65 * That's OK, the kernel will use its default of an 8K
66 * buffer in that case.
69 if(rtn
= set_init()) {
72 if(rtn
= set_enable(1)) {
79 int systemEntropyCollect(
82 UInt32
*numBytes
, // RETURNED - number of bytes obtained
83 UInt32
*bitsOfEntropy
) // RETURNED - est. amount of entropy
98 * We use one byte from each entry, which is a kd_buf.
99 * Thus, malloc bufSize kd_bufs.
100 * FIXME : this should use a secure nonswapping malloc.
102 mallocdSize
= bufSize
* sizeof(kd_buf
);
103 kd
= (kd_buf
*)malloc(mallocdSize
);
110 mib
[1] = KERN_KDEBUG
;
111 mib
[2] = KERN_KDREADTR
;
114 mib
[5] = 0; /* no flags */
117 * Snag the trace buffer, up to caller's limit.
118 * On call to sysctl, numEntries is byte count, on return,
121 numEntries
= mallocdSize
;
122 if (sysctl(mib
, 3, kd
, &numEntries
, NULL
, 0) < 0) {
123 /* ENOMEM means we didn't have room for everything in
124 * the kernel trace buffer, which is fine */
127 errorLog1("sysctl-KERN_KDREADTR: %d\n", err
);
132 if(numEntries
== 0) {
138 * First entropy byte is the low byte of the first entry's
139 * timestamp. Subsequent bytes are the deltas between successive
140 * entries' timestamps.
142 *cp
++ = (UInt8
)kd
[0].timestamp
.tv_nsec
;
143 for (i
=1; i
<numEntries
; i
++) {
144 *cp
++ = kd
[i
].timestamp
.tv_nsec
- kd
[i
-1].timestamp
.tv_nsec
;
147 *numBytes
= numEntries
;
148 *bitsOfEntropy
= numEntries
* 4; // half random?
150 /* and finally, turn off tracing */
153 set_remove(); // ignore errors
158 * The remainder of this file is based on code provided by Joe Sokol.
159 * All functions return a UNIX errno, zero on success.
162 static int set_remove()
168 mib
[1] = KERN_KDEBUG
;
169 mib
[2] = KERN_KDREMOVE
; /* protocol */
172 mib
[5] = 0; /* no flags */
174 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0) {
176 errorLog1("sysctl-KERN_KDREMOVE: %d\n", err
);
182 static int set_init()
188 kr
.type
= KDBG_RANGETYPE
;
191 needed
= sizeof(kd_regtype
);
193 mib
[1] = KERN_KDEBUG
;
194 mib
[2] = KERN_KDSETREG
;
197 mib
[5] = 0; /* no flags */
199 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
201 errorLog1("sysctl-KERN_KDSETREG: %d\n", err
);
206 mib
[1] = KERN_KDEBUG
;
207 mib
[2] = KERN_KDSETUP
;
210 mib
[5] = 0; /* no flags */
212 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0) {
214 errorLog1("sysctl-KERN_KDSETUP: %d\n", err
);
220 static int set_enable(int val
)
226 mib
[1] = KERN_KDEBUG
;
227 mib
[2] = KERN_KDENABLE
; /* protocol */
230 mib
[5] = 0; /* no flags */
231 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0) {
233 errorLog1("sysctl-KERN_KDENABLE: %d\n", err
);
239 static int set_numbufs(int nbufs
)
245 mib
[1] = KERN_KDEBUG
;
246 mib
[2] = KERN_KDSETBUF
;
249 mib
[5] = 0; /* no flags */
250 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0) {
252 errorLog2("ERROR: sysctl-KERN_KDSETBUF(%d): %s\n",
253 nbufs
, strerror(err
));
258 mib
[1] = KERN_KDEBUG
;
259 mib
[2] = KERN_KDSETUP
;
262 mib
[5] = 0; /* no flags */
263 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0) {
265 errorLog1("ERROR: sysctl-KERN_KDSETUP: %s\n",