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 RSARef 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 ****************************************************************** */
59 #include "cryptType.h"
63 #include <stdio.h> /* sha.h has a prototype with a FILE* */
88 uint8 dataBuffer
[SHA_BLOCKSIZE
];
91 uint8 SSLMACPad1
[MAX_MAC_PADDING
], SSLMACPad2
[MAX_MAC_PADDING
];
94 * Public general hash functions
100 for (i
= 0; i
< MAX_MAC_PADDING
; i
++)
101 { SSLMACPad1
[i
] = 0x36;
102 SSLMACPad2
[i
] = 0x5C;
106 /* FIXME - what's this for, if each alg has its own clone functions? */
108 CloneHashState(const HashReference
*ref
, SSLBuffer state
, SSLBuffer
*newState
, SSLContext
*ctx
)
110 if ((err
= SSLAllocBuffer(newState
, state
.length
, &ctx
->sysCtx
)) != 0)
112 memcpy(newState
->data
, state
.data
, state
.length
);
117 ReadyHash(const HashReference
*ref
, SSLBuffer
*state
, SSLContext
*ctx
)
119 if ((err
= SSLAllocBuffer(state
, ref
->contextSize
, &ctx
->sysCtx
)) != 0)
121 if ((err
= ref
->init(*state
)) != 0)
126 static SSLErr
HashNullInit(SSLBuffer
);
127 static SSLErr
HashNullUpdate(SSLBuffer
,SSLBuffer
);
128 static SSLErr
HashNullFinal(SSLBuffer
,SSLBuffer
);
129 static SSLErr
HashNullClone(SSLBuffer
,SSLBuffer
);
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
);
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
);
142 * These are the handles by which the bulk of digesting work
145 const HashReference SSLHashNull
=
156 const HashReference SSLHashMD5
=
167 const HashReference SSLHashSHA1
=
169 sizeof(SSL_SHA_INFO
),
179 static SSLErr
HashNullInit(SSLBuffer digestCtx
) {
183 static SSLErr
HashNullUpdate(SSLBuffer digestCtx
, SSLBuffer data
) {
187 static SSLErr
HashNullFinal(SSLBuffer digestCtx
, SSLBuffer digest
) {
191 static SSLErr
HashNullClone(SSLBuffer src
, SSLBuffer dest
) {
197 static SSLErr
HashMD5Init(SSLBuffer digestCtx
)
198 { CASSERT(digestCtx
.length
>= sizeof(MD5_CTX
));
199 SSLMD5Init((MD5_CTX
*)digestCtx
.data
);
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
);
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
);
217 static SSLErr
HashMD5Clone(SSLBuffer src
, SSLBuffer dest
)
219 if (src
.length
!= dest
.length
) {
220 errorLog0("HashMD5Clone: length mismatch\n");
221 return SSLProtocolErr
;
223 memcpy(dest
.data
, src
.data
, src
.length
);
228 static SSLErr
HashSHA1Init(SSLBuffer digestCtx
)
229 { SSL_SHA_INFO
*ctx
= (SSL_SHA_INFO
*)digestCtx
.data
;
230 CASSERT(digestCtx
.length
>= sizeof(SSL_SHA_INFO
));
236 static SSLErr
HashSHA1Update(SSLBuffer digestCtx
, SSLBuffer data
)
237 { SSL_SHA_INFO
*ctx
= (SSL_SHA_INFO
*)digestCtx
.data
;
238 uint32 dataRemaining
, processed
;
241 CASSERT(digestCtx
.length
>= sizeof(SSL_SHA_INFO
));
242 dataRemaining
= data
.length
;
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
);
254 dataRemaining
-= processed
;
255 dataPos
+= processed
;
257 //DUMP_BUFFER_PTR("SHA1 data", digestCtx.data, data);
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);
273 static SSLErr
HashSHA1Clone(SSLBuffer src
, SSLBuffer dest
)
274 { if (src
.length
!= dest
.length
) {
275 errorLog0("HashSHA1Clone: length mismatch\n");
276 return SSLProtocolErr
;
278 memcpy(dest
.data
, src
.data
, src
.length
);