]> git.saurik.com Git - apple/security.git/blob - SecureTransport/digests.c
Security-30.1.tar.gz
[apple/security.git] / SecureTransport / digests.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: digests.c
21
22 Contains: interface between SSL and SHA, MD5 digest libraries
23
24 Written by: Doug Mitchell, based on Netscape RSARef 3.0
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29 /* *********************************************************************
30 File: digests.c
31
32 SSLRef 3.0 Final -- 11/19/96
33
34 Copyright (c)1996 by Netscape Communications Corp.
35
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
39
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
43
44 *********************************************************************
45
46 File: digests.c Hashing support functions and data structures
47
48 Contains interface functions which generalize hashing support for MD5
49 and SHA1 and a dummy null hash implementation (used before MACing is
50 turned on). Also, utility functions for using the hashes.
51
52 ****************************************************************** */
53
54 #ifndef _SSLCTX_H_
55 #include "sslctx.h"
56 #endif
57
58 #ifndef _CRYPTTYPE_H_
59 #include "cryptType.h"
60 #endif
61
62 #ifndef SHA_H
63 #include <stdio.h> /* sha.h has a prototype with a FILE* */
64 #include "st_sha.h"
65 #endif
66
67 #ifndef _SSL_MD5_H_
68 #include "sslmd5.h"
69 #endif
70
71 #ifndef _SSLALLOC_H_
72 #include "sslalloc.h"
73 #endif
74
75 #ifndef _DIGESTS_H_
76 #include "digests.h"
77 #endif
78
79 #ifndef _SSL_DEBUG_H_
80 #include "sslDebug.h"
81 #endif
82
83 #include <string.h>
84
85 typedef struct
86 { SHA_INFO sha;
87 int bufferPos;
88 uint8 dataBuffer[SHA_BLOCKSIZE];
89 } SSL_SHA_INFO;
90
91 uint8 SSLMACPad1[MAX_MAC_PADDING], SSLMACPad2[MAX_MAC_PADDING];
92
93 /*
94 * Public general hash functions
95 */
96 void
97 SSLInitMACPads(void)
98 { int i;
99
100 for (i = 0; i < MAX_MAC_PADDING; i++)
101 { SSLMACPad1[i] = 0x36;
102 SSLMACPad2[i] = 0x5C;
103 }
104 }
105
106 /* FIXME - what's this for, if each alg has its own clone functions? */
107 SSLErr
108 CloneHashState(const HashReference *ref, SSLBuffer state, SSLBuffer *newState, SSLContext *ctx)
109 { SSLErr err;
110 if ((err = SSLAllocBuffer(newState, state.length, &ctx->sysCtx)) != 0)
111 return err;
112 memcpy(newState->data, state.data, state.length);
113 return SSLNoErr;
114 }
115
116 SSLErr
117 ReadyHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
118 { SSLErr err;
119 if ((err = SSLAllocBuffer(state, ref->contextSize, &ctx->sysCtx)) != 0)
120 return err;
121 if ((err = ref->init(*state)) != 0)
122 return err;
123 return SSLNoErr;
124 }
125
126 static SSLErr HashNullInit(SSLBuffer);
127 static SSLErr HashNullUpdate(SSLBuffer,SSLBuffer);
128 static SSLErr HashNullFinal(SSLBuffer,SSLBuffer);
129 static SSLErr HashNullClone(SSLBuffer,SSLBuffer);
130
131 static SSLErr HashMD5Init(SSLBuffer digestCtx);
132 static SSLErr HashMD5Update(SSLBuffer digestCtx, SSLBuffer data);
133 static SSLErr HashMD5Final(SSLBuffer digestCtx, SSLBuffer digest);
134 static SSLErr HashMD5Clone(SSLBuffer src, SSLBuffer dest);
135
136 static SSLErr HashSHA1Init(SSLBuffer digestCtx);
137 static SSLErr HashSHA1Update(SSLBuffer digestCtx, SSLBuffer data);
138 static SSLErr HashSHA1Final(SSLBuffer digestCtx, SSLBuffer digest);
139 static SSLErr HashSHA1Clone(SSLBuffer src, SSLBuffer dest);
140
141 /*
142 * These are the handles by which the bulk of digesting work
143 * is done.
144 */
145 const HashReference SSLHashNull =
146 {
147 0,
148 0,
149 0,
150 HashNullInit,
151 HashNullUpdate,
152 HashNullFinal,
153 HashNullClone
154 };
155
156 const HashReference SSLHashMD5 =
157 {
158 sizeof(MD5_CTX),
159 16,
160 48,
161 HashMD5Init,
162 HashMD5Update,
163 HashMD5Final,
164 HashMD5Clone
165 };
166
167 const HashReference SSLHashSHA1 =
168 {
169 sizeof(SSL_SHA_INFO),
170 20,
171 40,
172 HashSHA1Init,
173 HashSHA1Update,
174 HashSHA1Final,
175 HashSHA1Clone
176 };
177
178 /*** NULL ***/
179 static SSLErr HashNullInit(SSLBuffer digestCtx) {
180 return SSLNoErr;
181 }
182
183 static SSLErr HashNullUpdate(SSLBuffer digestCtx, SSLBuffer data) {
184 return SSLNoErr;
185 }
186
187 static SSLErr HashNullFinal(SSLBuffer digestCtx, SSLBuffer digest) {
188 return SSLNoErr;
189 }
190
191 static SSLErr HashNullClone(SSLBuffer src, SSLBuffer dest) {
192 return SSLNoErr;
193 }
194
195 /*** MD5 ***/
196
197 static SSLErr HashMD5Init(SSLBuffer digestCtx)
198 { CASSERT(digestCtx.length >= sizeof(MD5_CTX));
199 SSLMD5Init((MD5_CTX*)digestCtx.data);
200 return SSLNoErr;
201 }
202
203 static SSLErr HashMD5Update(SSLBuffer digestCtx, SSLBuffer data)
204 { CASSERT(digestCtx.length >= sizeof(MD5_CTX));
205 SSLMD5Update((MD5_CTX*)digestCtx.data, data.data, data.length);
206 return SSLNoErr;
207 }
208
209 static SSLErr HashMD5Final(SSLBuffer digestCtx, SSLBuffer digest)
210 { CASSERT(digestCtx.length >= sizeof(MD5_CTX));
211 CASSERT(digest.length >= 16);
212 SSLMD5Final(digest.data, (MD5_CTX*)digestCtx.data);
213 digest.length = 16;
214 return SSLNoErr;
215 }
216
217 static SSLErr HashMD5Clone(SSLBuffer src, SSLBuffer dest)
218 {
219 if (src.length != dest.length) {
220 errorLog0("HashMD5Clone: length mismatch\n");
221 return SSLProtocolErr;
222 }
223 memcpy(dest.data, src.data, src.length);
224 return SSLNoErr;
225 }
226
227 /*** SHA ***/
228 static SSLErr HashSHA1Init(SSLBuffer digestCtx)
229 { SSL_SHA_INFO *ctx = (SSL_SHA_INFO*)digestCtx.data;
230 CASSERT(digestCtx.length >= sizeof(SSL_SHA_INFO));
231 sha_init(&ctx->sha);
232 ctx->bufferPos = 0;
233 return SSLNoErr;
234 }
235
236 static SSLErr HashSHA1Update(SSLBuffer digestCtx, SSLBuffer data)
237 { SSL_SHA_INFO *ctx = (SSL_SHA_INFO*)digestCtx.data;
238 uint32 dataRemaining, processed;
239 uint8 *dataPos;
240
241 CASSERT(digestCtx.length >= sizeof(SSL_SHA_INFO));
242 dataRemaining = data.length;
243 dataPos = data.data;
244 while (dataRemaining > 0)
245 { processed = SHA_BLOCKSIZE - ctx->bufferPos;
246 if (dataRemaining < processed)
247 processed = dataRemaining;
248 memcpy(ctx->dataBuffer+ctx->bufferPos, dataPos, processed);
249 ctx->bufferPos += processed;
250 if (ctx->bufferPos == SHA_BLOCKSIZE)
251 { sha_update(&ctx->sha, ctx->dataBuffer, ctx->bufferPos);
252 ctx->bufferPos = 0;
253 }
254 dataRemaining -= processed;
255 dataPos += processed;
256 }
257 //DUMP_BUFFER_PTR("SHA1 data", digestCtx.data, data);
258 return SSLNoErr;
259 }
260
261 static SSLErr HashSHA1Final(SSLBuffer digestCtx, SSLBuffer digest)
262 { SSL_SHA_INFO *ctx = (SSL_SHA_INFO*)digestCtx.data;
263 CASSERT(digestCtx.length >= sizeof(SSL_SHA_INFO));
264 CASSERT(digest.length >= SHA_DIGESTSIZE);
265 if (ctx->bufferPos > 0)
266 sha_update(&ctx->sha, ctx->dataBuffer, ctx->bufferPos);
267 sha_final((SHA_INFO*)digestCtx.data);
268 memcpy(digest.data, ((SHA_INFO*)digestCtx.data)->digest, 20);
269 //DUMP_BUFFER_PTR("SHA1 final", digestCtx.data, digest);
270 return SSLNoErr;
271 }
272
273 static SSLErr HashSHA1Clone(SSLBuffer src, SSLBuffer dest)
274 { if (src.length != dest.length) {
275 errorLog0("HashSHA1Clone: length mismatch\n");
276 return SSLProtocolErr;
277 }
278 memcpy(dest.data, src.data, src.length);
279 return SSLNoErr;
280 }