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: interface between SSL and SHA, MD5 digest libraries
24 Written by: Doug Mitchell, based on Netscape SSLRef 3.0
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
29 /* *********************************************************************
32 SSLRef 3.0 Final -- 11/19/96
34 Copyright (c)1996 by Netscape Communications Corp.
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.
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/>.
44 *********************************************************************
46 File: digests.c Hashing support functions and data structures
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.
52 ****************************************************************** */
55 #include "cryptType.h"
59 #include "appleCdsa.h"
60 #include <Security/cssm.h>
63 #define DIGEST_PRINT 0
65 #define dgprintf(s) printf s
71 * Common digest context. The SSLBuffer.data pointer in a "digest state" argument
72 * casts to one of these.
75 CSSM_CC_HANDLE hashHand
;
78 uint8 SSLMACPad1
[MAX_MAC_PADDING
], SSLMACPad2
[MAX_MAC_PADDING
];
81 * Public general hash functions
87 for (i
= 0; i
< MAX_MAC_PADDING
; i
++)
88 { SSLMACPad1
[i
] = 0x36;
94 * A convenience wrapper for HashReference.clone, which has the added benefit of
95 * allocating the state buffer for the caller.
98 CloneHashState(const HashReference
*ref
, SSLBuffer state
, SSLBuffer
*newState
, SSLContext
*ctx
)
101 if ((err
= SSLAllocBuffer(newState
, ref
->contextSize
, &ctx
->sysCtx
)) != 0)
103 return ref
->clone(state
, *newState
);
107 * Wrapper for HashReference.init.
110 ReadyHash(const HashReference
*ref
, SSLBuffer
*state
, SSLContext
*ctx
)
113 if ((err
= SSLAllocBuffer(state
, ref
->contextSize
, &ctx
->sysCtx
)) != 0)
115 return ref
->init(*state
, ctx
);
119 * Wrapper for HashReference.clone. Tolerates NULL digestCtx and frees it if it's
122 SSLErr
CloseHash(const HashReference
*ref
, SSLBuffer
*state
, SSLContext
*ctx
)
126 if((state
== NULL
) || (state
->data
== NULL
)) {
129 serr
= ref
->close(*state
, ctx
);
133 return SSLFreeBuffer(state
, &ctx
->sysCtx
);
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
);
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
);
152 * These are the handles by which the bulk of digesting work
155 const HashReference SSLHashNull
=
167 const HashReference SSLHashMD5
=
169 sizeof(cdsaHashContext
),
179 const HashReference SSLHashSHA1
=
181 sizeof(cdsaHashContext
),
192 static SSLErr
HashNullInit(SSLBuffer digestCtx
, SSLContext
*sslCtx
) {
196 static SSLErr
HashNullUpdate(SSLBuffer digestCtx
, SSLBuffer data
) {
200 static SSLErr
HashNullFinal(SSLBuffer digestCtx
, SSLBuffer digest
) {
203 static SSLErr
HashNullClose(SSLBuffer digestCtx
, SSLContext
*sslCtx
) {
206 static SSLErr
HashNullClone(SSLBuffer src
, SSLBuffer dest
) {
210 static SSLErr
HashMD5Init(SSLBuffer digestCtx
, SSLContext
*sslCtx
)
212 CASSERT(digestCtx
.length
>= sizeof(cdsaHashContext
));
213 return cdsaHashInit(digestCtx
, sslCtx
, CSSM_ALGID_MD5
);
216 static SSLErr
HashSHA1Init(SSLBuffer digestCtx
, SSLContext
*sslCtx
)
218 CASSERT(digestCtx
.length
>= sizeof(cdsaHashContext
));
219 return cdsaHashInit(digestCtx
, sslCtx
, CSSM_ALGID_SHA1
);
222 /* common digest functions via CDSA */
223 static SSLErr
cdsaHashInit(SSLBuffer digestCtx
,
225 CSSM_ALGORITHMS digestAlg
)
228 cdsaHashContext
*cdsaCtx
;
229 CSSM_CC_HANDLE hashHand
= 0;
232 CASSERT(digestCtx
.length
>= sizeof(cdsaHashContext
));
233 serr
= attachToCsp(sslCtx
); // should be a nop
237 cdsaCtx
= (cdsaHashContext
*)digestCtx
.data
;
238 cdsaCtx
->hashHand
= 0;
239 dgprintf(("###cdsaHashInit cdsaCtx %p\n", cdsaCtx
));
241 /* cook up a digest context, initialize it */
242 crtn
= CSSM_CSP_CreateDigestContext(sslCtx
->cspHand
,
246 errorLog0("CSSM_CSP_CreateDigestContext failure\n");
247 return SSLCryptoError
;
249 crtn
= CSSM_DigestDataInit(hashHand
);
251 CSSM_DeleteContext(hashHand
);
252 errorLog0("CSSM_DigestDataInit failure\n");
253 return SSLCryptoError
;
255 cdsaCtx
->hashHand
= hashHand
;
259 static SSLErr
cdsaHashUpdate(SSLBuffer digestCtx
, SSLBuffer data
)
261 cdsaHashContext
*cdsaCtx
;
265 CASSERT(digestCtx
.length
>= sizeof(cdsaHashContext
));
266 cdsaCtx
= (cdsaHashContext
*)digestCtx
.data
;
267 //dgprintf(("###cdsaHashUpdate cdsaCtx %p\n", cdsaCtx));
269 SSLBUF_TO_CSSM(&data
, &cdata
);
270 crtn
= CSSM_DigestDataUpdate(cdsaCtx
->hashHand
, &cdata
, 1);
272 errorLog0("CSSM_DigestDataUpdate failure\n");
273 return SSLCryptoError
;
280 static SSLErr
cdsaHashFinal(SSLBuffer digestCtx
, SSLBuffer digest
)
282 cdsaHashContext
*cdsaCtx
;
285 SSLErr srtn
= SSLNoErr
;
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
);
293 errorLog0("CSSM_DigestDataFinal failure\n");
294 srtn
= SSLCryptoError
;
297 digest
.length
= cdata
.Length
;
299 CSSM_DeleteContext(cdsaCtx
->hashHand
);
300 cdsaCtx
->hashHand
= 0;
304 static SSLErr
cdsaHashClose(SSLBuffer digestCtx
, SSLContext
*sslCtx
)
306 cdsaHashContext
*cdsaCtx
;
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;
318 static SSLErr
cdsaHashClone(SSLBuffer src
, SSLBuffer dst
)
320 cdsaHashContext
*srcCtx
;
321 cdsaHashContext
*dstCtx
;
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
));
330 crtn
= CSSM_DigestDataClone(srcCtx
->hashHand
, &dstCtx
->hashHand
);
332 errorLog0("CSSM_DigestDataClone failure\n");
333 return SSLCryptoError
;