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 implementations
24 Written by: Doug Mitchell
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
30 #include "sslContext.h"
31 #include "cryptType.h"
32 #include "sslMemory.h"
33 #include "sslDigests.h"
35 #include "appleCdsa.h"
36 #include <Security/cssm.h>
39 #define DIGEST_PRINT 0
41 #define dgprintf(s) printf s
47 * Common digest context. The SSLBuffer.data pointer in a "digest state" argument
48 * casts to one of these.
51 CSSM_CC_HANDLE hashHand
;
54 const UInt8 SSLMACPad1
[MAX_MAC_PADDING
] =
56 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
57 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
58 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
59 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
60 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
61 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36
64 const UInt8 SSLMACPad2
[MAX_MAC_PADDING
] =
66 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
67 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
68 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
69 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
70 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
71 0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C
75 * Public general hash functions
79 * A convenience wrapper for HashReference.clone, which has the added benefit of
80 * allocating the state buffer for the caller.
84 const HashReference
&ref
,
85 const SSLBuffer
&state
,
90 if ((err
= SSLAllocBuffer(newState
, ref
.contextSize
, ctx
)) != 0)
92 return ref
.clone(state
, newState
);
96 * Wrapper for HashReference.init.
99 ReadyHash(const HashReference
&ref
, SSLBuffer
&state
, SSLContext
*ctx
)
102 if ((err
= SSLAllocBuffer(state
, ref
.contextSize
, ctx
)) != 0)
104 return ref
.init(state
, ctx
);
108 * Wrapper for HashReference.clone. Tolerates NULL digestCtx and frees it if it's
111 OSStatus
CloseHash(const HashReference
&ref
, SSLBuffer
&state
, SSLContext
*ctx
)
115 if(state
.data
== NULL
) {
118 serr
= ref
.close(state
, ctx
);
122 return SSLFreeBuffer(state
, ctx
);
125 static OSStatus
HashNullInit(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
);
126 static OSStatus
HashNullUpdate(SSLBuffer
&digestCtx
, const SSLBuffer
&data
);
127 static OSStatus
HashNullFinal(SSLBuffer
&digestCtx
, SSLBuffer
&digest
);
128 static OSStatus
HashNullClose(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
);
129 static OSStatus
HashNullClone(const SSLBuffer
&src
, SSLBuffer
&dst
);
131 static OSStatus
HashMD5Init(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
);
132 static OSStatus
HashSHA1Init(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
);
133 static OSStatus
cdsaHashInit(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
,
134 CSSM_ALGORITHMS digestAlg
);
135 static OSStatus
cdsaHashUpdate(SSLBuffer
&digestCtx
, const SSLBuffer
&data
);
136 static OSStatus
cdsaHashFinal(SSLBuffer
&digestCtx
, SSLBuffer
&digest
);
137 static OSStatus
cdsaHashClose(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
);
138 static OSStatus
cdsaHashClone(const SSLBuffer
&src
, SSLBuffer
&dest
);
141 * These are the handles by which the bulk of digesting work
144 const HashReference SSLHashNull
=
156 const HashReference SSLHashMD5
=
158 sizeof(cdsaHashContext
),
168 const HashReference SSLHashSHA1
=
170 sizeof(cdsaHashContext
),
181 static OSStatus
HashNullInit(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
) {
185 static OSStatus
HashNullUpdate(SSLBuffer
&digestCtx
, const SSLBuffer
&data
) {
189 static OSStatus
HashNullFinal(SSLBuffer
&digestCtx
, SSLBuffer
&digest
) {
192 static OSStatus
HashNullClose(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
) {
195 static OSStatus
HashNullClone(const SSLBuffer
&src
, SSLBuffer
&dest
) {
199 static OSStatus
HashMD5Init(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
)
201 assert(digestCtx
.length
>= sizeof(cdsaHashContext
));
202 return cdsaHashInit(digestCtx
, sslCtx
, CSSM_ALGID_MD5
);
205 static OSStatus
HashSHA1Init(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
)
207 assert(digestCtx
.length
>= sizeof(cdsaHashContext
));
208 return cdsaHashInit(digestCtx
, sslCtx
, CSSM_ALGID_SHA1
);
211 /* common digest functions via CDSA */
212 static OSStatus
cdsaHashInit(SSLBuffer
&digestCtx
,
214 CSSM_ALGORITHMS digestAlg
)
217 cdsaHashContext
*cdsaCtx
;
218 CSSM_CC_HANDLE hashHand
= 0;
221 assert(digestCtx
.length
>= sizeof(cdsaHashContext
));
222 serr
= attachToCsp(sslCtx
); // should be a nop
226 cdsaCtx
= (cdsaHashContext
*)digestCtx
.data
;
227 cdsaCtx
->hashHand
= 0;
228 dgprintf(("###cdsaHashInit cdsaCtx %p\n", cdsaCtx
));
230 /* cook up a digest context, initialize it */
231 crtn
= CSSM_CSP_CreateDigestContext(sslCtx
->cspHand
,
235 sslErrorLog("CSSM_CSP_CreateDigestContext failure\n");
238 crtn
= CSSM_DigestDataInit(hashHand
);
240 CSSM_DeleteContext(hashHand
);
241 sslErrorLog("CSSM_DigestDataInit failure\n");
244 cdsaCtx
->hashHand
= hashHand
;
248 static OSStatus
cdsaHashUpdate(SSLBuffer
&digestCtx
, const SSLBuffer
&data
)
250 cdsaHashContext
*cdsaCtx
;
254 assert(digestCtx
.length
>= sizeof(cdsaHashContext
));
255 cdsaCtx
= (cdsaHashContext
*)digestCtx
.data
;
256 //dgprintf(("###cdsaHashUpdate cdsaCtx %p\n", cdsaCtx));
258 SSLBUF_TO_CSSM(&data
, &cdata
);
259 crtn
= CSSM_DigestDataUpdate(cdsaCtx
->hashHand
, &cdata
, 1);
261 sslErrorLog("CSSM_DigestDataUpdate failure\n");
269 static OSStatus
cdsaHashFinal(SSLBuffer
&digestCtx
, SSLBuffer
&digest
)
271 cdsaHashContext
*cdsaCtx
;
274 OSStatus srtn
= noErr
;
276 assert(digestCtx
.length
>= sizeof(cdsaHashContext
));
277 cdsaCtx
= (cdsaHashContext
*)digestCtx
.data
;
278 dgprintf(("###cdsaHashFinal cdsaCtx %p\n", cdsaCtx
));
279 SSLBUF_TO_CSSM(&digest
, &cdata
);
280 crtn
= CSSM_DigestDataFinal(cdsaCtx
->hashHand
, &cdata
);
282 sslErrorLog("CSSM_DigestDataFinal failure\n");
286 digest
.length
= cdata
.Length
;
288 CSSM_DeleteContext(cdsaCtx
->hashHand
);
289 cdsaCtx
->hashHand
= 0;
293 static OSStatus
cdsaHashClose(SSLBuffer
&digestCtx
, SSLContext
*sslCtx
)
295 cdsaHashContext
*cdsaCtx
;
297 assert(digestCtx
.length
>= sizeof(cdsaHashContext
));
298 cdsaCtx
= (cdsaHashContext
*)digestCtx
.data
;
299 dgprintf(("###cdsaHashClose cdsaCtx %p\n", cdsaCtx
));
300 if(cdsaCtx
->hashHand
!= 0) {
301 CSSM_DeleteContext(cdsaCtx
->hashHand
);
302 cdsaCtx
->hashHand
= 0;
307 static OSStatus
cdsaHashClone(const SSLBuffer
&src
, SSLBuffer
&dst
)
309 cdsaHashContext
*srcCtx
;
310 cdsaHashContext
*dstCtx
;
313 assert(src
.length
>= sizeof(cdsaHashContext
));
314 assert(dst
.length
>= sizeof(cdsaHashContext
));
315 srcCtx
= (cdsaHashContext
*)src
.data
;
316 dstCtx
= (cdsaHashContext
*)dst
.data
;
317 dgprintf(("###cdsaHashClone srcCtx %p dstCtx %p\n", srcCtx
, dstCtx
));
319 crtn
= CSSM_DigestDataClone(srcCtx
->hashHand
, &dstCtx
->hashHand
);
321 sslErrorLog("CSSM_DigestDataClone failure\n");