]> git.saurik.com Git - apple/security.git/blob - SecurityServer/MacYarrow/YarrowServer/entropyFileUnix.c
Security-28.tar.gz
[apple/security.git] / SecurityServer / MacYarrow / YarrowServer / entropyFileUnix.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 /*
20 File: entropyFileUnix.c
21
22 Contains: Module to maintain MacYarrow's entropy file, UNIX version.
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved.
27
28 Change History (most recent first):
29
30 05/22/00 dpm Created.
31
32 */
33
34 #include "entropyFile.h"
35 #include "debug.h"
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <sys/types.h>
42 #include <string.h>
43 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
44
45 /*
46 * For now we use the same file location for all builds. Generally for
47 * debugging - when this code is not running as root - you need to do
48 * the following once per system before using this code:
49 *
50 * > su to root
51 * # touch /var/db/SystemEntropyCache
52 * # chmod 666 /var/db/SystemEntropyCache
53 */
54 #define DEFAULT_ENTROPY_FILE_PATH "/var/db/SystemEntropyCache"
55
56 /* NULL ==> use default, else use caller-specified path */
57 static char *entropyFilePath = NULL;
58
59 static OSErr errNoToOSErr(int err)
60 {
61 switch(err) {
62 case ENOENT:
63 return fnfErr;
64 case EPERM:
65 return permErr;
66 /* anything else interesting? */
67 default:
68 return ioErr;
69 }
70 }
71
72 static char *getEntropyFilePath()
73 {
74 if(entropyFilePath) {
75 return entropyFilePath;
76 }
77 else {
78 return DEFAULT_ENTROPY_FILE_PATH;
79 }
80 }
81
82 /*
83 * Specify optional entropy file path. If this is never called,
84 * this module will use its own default path.
85 */
86 OSErr setEntropyFilePath(
87 const char *path)
88 {
89 unsigned len;
90
91 if(entropyFilePath) {
92 free(entropyFilePath);
93 entropyFilePath = NULL;
94 }
95 if(path == NULL) {
96 return noErr;
97 }
98 len = strlen(path);
99 if(len > 255) {
100 /* no can do */
101 return bdNamErr;
102 }
103 entropyFilePath = malloc(len + 1);
104 if(entropyFilePath == NULL) {
105 return memFullErr;
106 }
107 memmove(entropyFilePath, path, len + 1);
108 return noErr;
109 }
110
111 /*
112 * Write specified data to entropy file. A new file will be created
113 * if none exists. Existing file's data is replaced with caller's data.
114 */
115 OSErr writeEntropyFile(
116 UInt8 *bytes,
117 UInt32 numBytes)
118 {
119 int rtn;
120 int fd;
121 OSErr ortn;
122
123 fd = open(getEntropyFilePath(), O_RDWR | O_CREAT | O_TRUNC, 0600);
124 if(fd <= 0) {
125 rtn = errno;
126 errorLog1("writeEntropyFile: open returned %d\n", rtn);
127 return errNoToOSErr(rtn);
128 }
129 rtn = lseek(fd, 0, SEEK_SET);
130 if(rtn < 0) {
131 rtn = errno;
132 errorLog1("writeEntropyFile: lseek returned %d\n", rtn);
133 return errNoToOSErr(rtn);
134 }
135 rtn = write(fd, bytes, (size_t)numBytes);
136 if(rtn != (int)numBytes) {
137 if(rtn < 0) {
138 errorLog1("writeEntropyFile: write() returned %d\n", rtn);
139 ortn = errNoToOSErr(errno);
140 }
141 else {
142 errorLog0("writeEntropyFile(): short write\n");
143 ortn = ioErr;
144 }
145 }
146 else {
147 ortn = noErr;
148 }
149 close(fd);
150 return ortn;
151 }
152
153 /*
154 * Read data from entropy file.
155 */
156 OSErr readEntropyFile(
157 UInt8 *bytes,
158 UInt32 numBytes, // max # of bytes to read
159 UInt32 *actualBytes) // RETURNED - number of bytes actually read
160 {
161 int rtn;
162 int fd;
163 OSErr ortn;
164
165 *actualBytes = 0;
166 fd = open(getEntropyFilePath(), O_RDONLY, 0);
167 if(fd <= 0) {
168 rtn = errno;
169 errorLog1("readEntropyFile: open returned %d\n", rtn);
170 return errNoToOSErr(rtn);
171 }
172 rtn = lseek(fd, 0, SEEK_SET);
173 if(rtn < 0) {
174 rtn = errno;
175 errorLog1("readEntropyFile: lseek returned %d\n", rtn);
176 return errNoToOSErr(rtn);
177 }
178 rtn = read(fd, bytes, (size_t)numBytes);
179 if(rtn < 0) {
180 errorLog1("readEntropyFile: read() returned %d\n", rtn);
181 ortn = errNoToOSErr(errno);
182 }
183 else {
184 *actualBytes = (UInt32)rtn;
185 ortn = noErr;
186 }
187 close(fd);
188 return ortn;
189 }