]> git.saurik.com Git - apple/security.git/blob - SecureTransport/digests.c
Security-54.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 SSLRef 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 #include "sslctx.h"
55 #include "cryptType.h"
56 #include "sslalloc.h"
57 #include "digests.h"
58 #include "sslDebug.h"
59 #include "appleCdsa.h"
60 #include <Security/cssm.h>
61 #include <string.h>
62
63 #define DIGEST_PRINT 0
64 #if DIGEST_PRINT
65 #define dgprintf(s) printf s
66 #else
67 #define dgprintf(s)
68 #endif
69
70 /*
71 * Common digest context. The SSLBuffer.data pointer in a "digest state" argument
72 * casts to one of these.
73 */
74 typedef struct {
75 CSSM_CC_HANDLE hashHand;
76 } cdsaHashContext;
77
78 uint8 SSLMACPad1[MAX_MAC_PADDING], SSLMACPad2[MAX_MAC_PADDING];
79
80 /*
81 * Public general hash functions
82 */
83 void
84 SSLInitMACPads(void)
85 { int i;
86
87 for (i = 0; i < MAX_MAC_PADDING; i++)
88 { SSLMACPad1[i] = 0x36;
89 SSLMACPad2[i] = 0x5C;
90 }
91 }
92
93 /*
94 * A convenience wrapper for HashReference.clone, which has the added benefit of
95 * allocating the state buffer for the caller.
96 */
97 SSLErr
98 CloneHashState(const HashReference *ref, SSLBuffer state, SSLBuffer *newState, SSLContext *ctx)
99 {
100 SSLErr err;
101 if ((err = SSLAllocBuffer(newState, ref->contextSize, &ctx->sysCtx)) != 0)
102 return err;
103 return ref->clone(state, *newState);
104 }
105
106 /*
107 * Wrapper for HashReference.init.
108 */
109 SSLErr
110 ReadyHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
111 {
112 SSLErr err;
113 if ((err = SSLAllocBuffer(state, ref->contextSize, &ctx->sysCtx)) != 0)
114 return err;
115 return ref->init(*state, ctx);
116 }
117
118 /*
119 * Wrapper for HashReference.clone. Tolerates NULL digestCtx and frees it if it's
120 * there.
121 */
122 SSLErr CloseHash(const HashReference *ref, SSLBuffer *state, SSLContext *ctx)
123 {
124 SSLErr serr;
125
126 if((state == NULL) || (state->data == NULL)) {
127 return SSLNoErr;
128 }
129 serr = ref->close(*state, ctx);
130 if(serr) {
131 return serr;
132 }
133 return SSLFreeBuffer(state, &ctx->sysCtx);
134 }
135
136 static SSLErr HashNullInit(SSLBuffer digestCtx, SSLContext *sslCtx);
137 static SSLErr HashNullUpdate(SSLBuffer,SSLBuffer);
138 static SSLErr HashNullFinal(SSLBuffer,SSLBuffer);
139 static SSLErr HashNullClose(SSLBuffer digestCtx, SSLContext *sslCtx);
140 static SSLErr HashNullClone(SSLBuffer,SSLBuffer);
141
142 static SSLErr HashMD5Init(SSLBuffer digestCtx, SSLContext *sslCtx);
143 static SSLErr HashSHA1Init(SSLBuffer digestCtx, SSLContext *sslCtx);
144 static SSLErr cdsaHashInit(SSLBuffer digestCtx, SSLContext *sslCtx,
145 CSSM_ALGORITHMS digestAlg);
146 static SSLErr cdsaHashUpdate(SSLBuffer digestCtx, SSLBuffer data);
147 static SSLErr cdsaHashFinal(SSLBuffer digestCtx, SSLBuffer digest);
148 static SSLErr cdsaHashClose(SSLBuffer digestCtx, SSLContext *sslCtx);
149 static SSLErr cdsaHashClone(SSLBuffer src, SSLBuffer dest);
150
151 /*
152 * These are the handles by which the bulk of digesting work
153 * is done.
154 */
155 const HashReference SSLHashNull =
156 {
157 0,
158 0,
159 0,
160 HashNullInit,
161 HashNullUpdate,
162 HashNullFinal,
163 HashNullClose,
164 HashNullClone
165 };
166
167 const HashReference SSLHashMD5 =
168 {
169 sizeof(cdsaHashContext),
170 16,
171 48,
172 HashMD5Init,
173 cdsaHashUpdate,
174 cdsaHashFinal,
175 cdsaHashClose,
176 cdsaHashClone
177 };
178
179 const HashReference SSLHashSHA1 =
180 {
181 sizeof(cdsaHashContext),
182 20,
183 40,
184 HashSHA1Init,
185 cdsaHashUpdate,
186 cdsaHashFinal,
187 cdsaHashClose,
188 cdsaHashClone
189 };
190
191 /*** NULL ***/
192 static SSLErr HashNullInit(SSLBuffer digestCtx, SSLContext *sslCtx) {
193 return SSLNoErr;
194 }
195
196 static SSLErr HashNullUpdate(SSLBuffer digestCtx, SSLBuffer data) {
197 return SSLNoErr;
198 }
199
200 static SSLErr HashNullFinal(SSLBuffer digestCtx, SSLBuffer digest) {
201 return SSLNoErr;
202 }
203 static SSLErr HashNullClose(SSLBuffer digestCtx, SSLContext *sslCtx) {
204 return SSLNoErr;
205 }
206 static SSLErr HashNullClone(SSLBuffer src, SSLBuffer dest) {
207 return SSLNoErr;
208 }
209
210 static SSLErr HashMD5Init(SSLBuffer digestCtx, SSLContext *sslCtx)
211 {
212 CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
213 return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_MD5);
214 }
215
216 static SSLErr HashSHA1Init(SSLBuffer digestCtx, SSLContext *sslCtx)
217 {
218 CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
219 return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_SHA1);
220 }
221
222 /* common digest functions via CDSA */
223 static SSLErr cdsaHashInit(SSLBuffer digestCtx,
224 SSLContext *sslCtx,
225 CSSM_ALGORITHMS digestAlg)
226 {
227 SSLErr serr;
228 cdsaHashContext *cdsaCtx;
229 CSSM_CC_HANDLE hashHand = 0;
230 CSSM_RETURN crtn;
231
232 CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
233 serr = attachToCsp(sslCtx); // should be a nop
234 if(serr) {
235 return serr;
236 }
237 cdsaCtx = (cdsaHashContext *)digestCtx.data;
238 cdsaCtx->hashHand = 0;
239 dgprintf(("###cdsaHashInit cdsaCtx %p\n", cdsaCtx));
240
241 /* cook up a digest context, initialize it */
242 crtn = CSSM_CSP_CreateDigestContext(sslCtx->cspHand,
243 digestAlg,
244 &hashHand);
245 if(crtn) {
246 errorLog0("CSSM_CSP_CreateDigestContext failure\n");
247 return SSLCryptoError;
248 }
249 crtn = CSSM_DigestDataInit(hashHand);
250 if(crtn) {
251 CSSM_DeleteContext(hashHand);
252 errorLog0("CSSM_DigestDataInit failure\n");
253 return SSLCryptoError;
254 }
255 cdsaCtx->hashHand = hashHand;
256 return SSLNoErr;
257 }
258
259 static SSLErr cdsaHashUpdate(SSLBuffer digestCtx, SSLBuffer data)
260 {
261 cdsaHashContext *cdsaCtx;
262 CSSM_RETURN crtn;
263 CSSM_DATA cdata;
264
265 CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
266 cdsaCtx = (cdsaHashContext *)digestCtx.data;
267 //dgprintf(("###cdsaHashUpdate cdsaCtx %p\n", cdsaCtx));
268
269 SSLBUF_TO_CSSM(&data, &cdata);
270 crtn = CSSM_DigestDataUpdate(cdsaCtx->hashHand, &cdata, 1);
271 if(crtn) {
272 errorLog0("CSSM_DigestDataUpdate failure\n");
273 return SSLCryptoError;
274 }
275 else {
276 return SSLNoErr;
277 }
278 }
279
280 static SSLErr cdsaHashFinal(SSLBuffer digestCtx, SSLBuffer digest)
281 {
282 cdsaHashContext *cdsaCtx;
283 CSSM_RETURN crtn;
284 CSSM_DATA cdata;
285 SSLErr srtn = SSLNoErr;
286
287 CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
288 cdsaCtx = (cdsaHashContext *)digestCtx.data;
289 dgprintf(("###cdsaHashFinal cdsaCtx %p\n", cdsaCtx));
290 SSLBUF_TO_CSSM(&digest, &cdata);
291 crtn = CSSM_DigestDataFinal(cdsaCtx->hashHand, &cdata);
292 if(crtn) {
293 errorLog0("CSSM_DigestDataFinal failure\n");
294 srtn = SSLCryptoError;
295 }
296 else {
297 digest.length = cdata.Length;
298 }
299 CSSM_DeleteContext(cdsaCtx->hashHand);
300 cdsaCtx->hashHand = 0;
301 return srtn;
302 }
303
304 static SSLErr cdsaHashClose(SSLBuffer digestCtx, SSLContext *sslCtx)
305 {
306 cdsaHashContext *cdsaCtx;
307
308 CASSERT(digestCtx.length >= sizeof(cdsaHashContext));
309 cdsaCtx = (cdsaHashContext *)digestCtx.data;
310 dgprintf(("###cdsaHashClose cdsaCtx %p\n", cdsaCtx));
311 if(cdsaCtx->hashHand != 0) {
312 CSSM_DeleteContext(cdsaCtx->hashHand);
313 cdsaCtx->hashHand = 0;
314 }
315 return SSLNoErr;
316 }
317
318 static SSLErr cdsaHashClone(SSLBuffer src, SSLBuffer dst)
319 {
320 cdsaHashContext *srcCtx;
321 cdsaHashContext *dstCtx;
322 CSSM_RETURN crtn;
323
324 CASSERT(src.length >= sizeof(cdsaHashContext));
325 CASSERT(dst.length >= sizeof(cdsaHashContext));
326 srcCtx = (cdsaHashContext *)src.data;
327 dstCtx = (cdsaHashContext *)dst.data;
328 dgprintf(("###cdsaHashClone srcCtx %p dstCtx %p\n", srcCtx, dstCtx));
329
330 crtn = CSSM_DigestDataClone(srcCtx->hashHand, &dstCtx->hashHand);
331 if(crtn) {
332 errorLog0("CSSM_DigestDataClone failure\n");
333 return SSLCryptoError;
334 }
335 else {
336 return SSLNoErr;
337 }
338 }
339