]>
Commit | Line | Data |
---|---|---|
29654253 A |
1 | /* |
2 | * Copyright (c) 2002 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: tls_hmac.c | |
21 | ||
22 | Contains: HMAC routines used by TLS | |
23 | ||
24 | Written by: Doug Mitchell | |
25 | */ | |
26 | ||
27 | #include "tls_hmac.h" | |
28 | #include "appleCdsa.h" | |
5a719ac8 | 29 | #include "sslMemory.h" |
29654253 | 30 | #include "cryptType.h" |
5a719ac8 | 31 | #include "sslDigests.h" |
29654253 A |
32 | #include <strings.h> |
33 | #include <assert.h> | |
34 | #include <Security/cssm.h> | |
35 | ||
36 | /* Per-session state, opaque to callers; all fields set at alloc time */ | |
37 | struct HMACContext { | |
38 | SSLContext *ctx; | |
39 | CSSM_CC_HANDLE ccHand; | |
40 | const struct HMACReference *hmac; | |
41 | }; | |
42 | ||
43 | #pragma mark *** Common CDSA_based HMAC routines *** | |
44 | ||
45 | /* Create an HMAC session */ | |
5a719ac8 | 46 | static OSStatus HMAC_Alloc( |
29654253 A |
47 | const struct HMACReference *hmac, |
48 | SSLContext *ctx, | |
49 | const void *keyPtr, | |
50 | unsigned keyLen, | |
51 | HMACContextRef *hmacCtx) // RETURNED | |
52 | { | |
53 | CSSM_RETURN crtn; | |
54 | CSSM_KEY cssmKey; | |
5a719ac8 | 55 | OSStatus serr; |
29654253 | 56 | CSSM_ALGORITHMS calg; |
5a719ac8 | 57 | HMACContextRef href = (HMACContextRef)sslMalloc(sizeof(struct HMACContext)); |
29654253 A |
58 | |
59 | if(href == NULL) { | |
5a719ac8 | 60 | return memFullErr; |
29654253 A |
61 | } |
62 | href->ctx = ctx; | |
63 | href->ccHand = 0; | |
64 | href->hmac = hmac; | |
65 | ||
66 | /* | |
67 | * Since the key is present in the CDSA context, we cook up the context now. | |
68 | * Currently we can't reuse an HMAC context if the key changes. | |
69 | */ | |
70 | switch(hmac->alg) { | |
71 | case HA_SHA1: | |
72 | calg = CSSM_ALGID_SHA1HMAC; | |
73 | break; | |
74 | case HA_MD5: | |
75 | calg = CSSM_ALGID_MD5HMAC; | |
76 | break; | |
77 | default: | |
78 | assert(0); | |
5a719ac8 | 79 | return errSSLInternal; |
29654253 A |
80 | } |
81 | serr = sslSetUpSymmKey(&cssmKey, | |
82 | calg, | |
83 | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY, | |
84 | CSSM_FALSE, /* don't malloc/copy key */ | |
85 | (uint8 *)keyPtr, | |
86 | keyLen); | |
87 | if(serr) { | |
88 | return serr; | |
89 | } | |
90 | if(attachToCsp(ctx)) { | |
91 | return serr; | |
92 | } | |
93 | crtn = CSSM_CSP_CreateMacContext(ctx->cspHand, | |
94 | calg, | |
95 | &cssmKey, | |
96 | &href->ccHand); | |
97 | if(crtn) { | |
df0e469f | 98 | stPrintCdsaError("CSSM_CSP_CreateMacContext", crtn); |
5a719ac8 | 99 | return errSSLCrypto; |
29654253 A |
100 | } |
101 | ||
102 | /* success */ | |
103 | *hmacCtx = href; | |
5a719ac8 | 104 | return noErr; |
29654253 A |
105 | } |
106 | ||
107 | /* free a session */ | |
5a719ac8 | 108 | static OSStatus HMAC_Free( |
29654253 A |
109 | HMACContextRef hmacCtx) |
110 | { | |
111 | if(hmacCtx != NULL) { | |
112 | if(hmacCtx->ccHand != 0) { | |
113 | CSSM_DeleteContext(hmacCtx->ccHand); | |
114 | hmacCtx->ccHand = 0; | |
115 | } | |
116 | sslFree(hmacCtx); | |
117 | } | |
5a719ac8 | 118 | return noErr; |
29654253 A |
119 | } |
120 | ||
121 | /* Reusable init */ | |
5a719ac8 | 122 | static OSStatus HMAC_Init( |
29654253 A |
123 | HMACContextRef hmacCtx) |
124 | { | |
125 | CSSM_RETURN crtn; | |
126 | ||
127 | if(hmacCtx == NULL) { | |
5a719ac8 | 128 | return errSSLInternal; |
29654253 A |
129 | } |
130 | assert(hmacCtx->ctx != NULL); | |
131 | assert(hmacCtx->hmac != NULL); | |
132 | assert(hmacCtx->ccHand != 0); | |
133 | ||
134 | crtn = CSSM_GenerateMacInit(hmacCtx->ccHand); | |
135 | if(crtn) { | |
df0e469f | 136 | stPrintCdsaError("CSSM_GenerateMacInit", crtn); |
5a719ac8 | 137 | return errSSLCrypto; |
29654253 | 138 | } |
5a719ac8 | 139 | return noErr; |
29654253 A |
140 | } |
141 | ||
142 | /* normal crypt ops */ | |
5a719ac8 | 143 | static OSStatus HMAC_Update( |
29654253 A |
144 | HMACContextRef hmacCtx, |
145 | const void *data, | |
146 | unsigned dataLen) | |
147 | { | |
148 | CSSM_RETURN crtn; | |
149 | CSSM_DATA cdata; | |
150 | ||
151 | if(hmacCtx == NULL) { | |
5a719ac8 | 152 | return errSSLInternal; |
29654253 A |
153 | } |
154 | assert(hmacCtx->ctx != NULL); | |
155 | assert(hmacCtx->hmac != NULL); | |
156 | assert(hmacCtx->ccHand != 0); | |
157 | cdata.Data = (uint8 *)data; | |
158 | cdata.Length = dataLen; | |
159 | crtn = CSSM_GenerateMacUpdate(hmacCtx->ccHand, &cdata, 1); | |
160 | if(crtn) { | |
df0e469f | 161 | stPrintCdsaError("CSSM_GenerateMacUpdate", crtn); |
5a719ac8 | 162 | return errSSLCrypto; |
29654253 | 163 | } |
5a719ac8 | 164 | return noErr; |
29654253 A |
165 | } |
166 | ||
5a719ac8 | 167 | static OSStatus HMAC_Final( |
29654253 A |
168 | HMACContextRef hmacCtx, |
169 | void *hmac, // mallocd by caller | |
170 | unsigned *hmacLen) // IN/OUT | |
171 | { | |
172 | CSSM_RETURN crtn; | |
173 | CSSM_DATA cdata; | |
174 | ||
175 | if(hmacCtx == NULL) { | |
5a719ac8 | 176 | return errSSLInternal; |
29654253 A |
177 | } |
178 | if((hmac == NULL) || (hmacLen == 0)) { | |
5a719ac8 | 179 | return errSSLInternal; |
29654253 A |
180 | } |
181 | assert(hmacCtx->ctx != NULL); | |
182 | assert(hmacCtx->hmac != NULL); | |
183 | assert(hmacCtx->ccHand != 0); | |
184 | cdata.Data = (uint8 *)hmac; | |
185 | cdata.Length = *hmacLen; | |
186 | crtn = CSSM_GenerateMacFinal(hmacCtx->ccHand, &cdata); | |
187 | if(crtn) { | |
df0e469f | 188 | stPrintCdsaError("CSSM_GenerateMacFinal", crtn); |
5a719ac8 | 189 | return errSSLCrypto; |
29654253 A |
190 | } |
191 | *hmacLen = cdata.Length; | |
5a719ac8 | 192 | return noErr; |
29654253 A |
193 | } |
194 | ||
195 | /* one-shot */ | |
5a719ac8 | 196 | static OSStatus HMAC_Hmac ( |
29654253 A |
197 | HMACContextRef hmacCtx, |
198 | const void *data, | |
199 | unsigned dataLen, | |
200 | void *hmac, // mallocd by caller | |
201 | unsigned *hmacLen) // IN/OUT | |
202 | { | |
5a719ac8 | 203 | OSStatus serr; |
29654253 A |
204 | const HMACReference *hmacRef; |
205 | ||
206 | if(hmacCtx == NULL) { | |
5a719ac8 | 207 | return errSSLInternal; |
29654253 A |
208 | } |
209 | hmacRef = hmacCtx->hmac; | |
210 | assert(hmacRef != NULL); | |
211 | serr = hmacRef->init(hmacCtx); | |
212 | if(serr) { | |
213 | return serr; | |
214 | } | |
215 | serr = hmacRef->update(hmacCtx, data, dataLen); | |
216 | if(serr) { | |
217 | return serr; | |
218 | } | |
219 | return hmacRef->final(hmacCtx, hmac, hmacLen); | |
220 | } | |
221 | ||
222 | #pragma mark *** Null HMAC *** | |
223 | ||
5a719ac8 | 224 | static OSStatus HMAC_AllocNull( |
29654253 A |
225 | const struct HMACReference *hmac, |
226 | SSLContext *ctx, | |
227 | const void *keyPtr, | |
228 | unsigned keyLen, | |
229 | HMACContextRef *hmacCtx) // RETURNED | |
230 | { | |
231 | *hmacCtx = NULL; | |
5a719ac8 | 232 | return noErr; |
29654253 A |
233 | } |
234 | ||
5a719ac8 | 235 | static OSStatus HMAC_FreeNull( |
29654253 A |
236 | HMACContextRef hmacCtx) |
237 | { | |
5a719ac8 | 238 | return noErr; |
29654253 A |
239 | } |
240 | ||
5a719ac8 | 241 | static OSStatus HMAC_InitNull( |
29654253 A |
242 | HMACContextRef hmacCtx) |
243 | { | |
5a719ac8 | 244 | return noErr; |
29654253 A |
245 | } |
246 | ||
5a719ac8 | 247 | static OSStatus HMAC_UpdateNull( |
29654253 A |
248 | HMACContextRef hmacCtx, |
249 | const void *data, | |
250 | unsigned dataLen) | |
251 | { | |
5a719ac8 | 252 | return noErr; |
29654253 A |
253 | } |
254 | ||
5a719ac8 | 255 | static OSStatus HMAC_FinalNull( |
29654253 A |
256 | HMACContextRef hmacCtx, |
257 | void *hmac, // mallocd by caller | |
258 | unsigned *hmacLen) // IN/OUT | |
259 | { | |
5a719ac8 | 260 | return noErr; |
29654253 A |
261 | } |
262 | ||
5a719ac8 | 263 | static OSStatus HMAC_HmacNull ( |
29654253 A |
264 | HMACContextRef hmacCtx, |
265 | const void *data, | |
266 | unsigned dataLen, | |
267 | void *hmac, // mallocd by caller | |
268 | unsigned *hmacLen) | |
269 | { | |
5a719ac8 | 270 | return noErr; |
29654253 A |
271 | } |
272 | ||
273 | const HMACReference TlsHmacNull = { | |
274 | 0, | |
275 | HA_Null, | |
276 | HMAC_AllocNull, | |
277 | HMAC_FreeNull, | |
278 | HMAC_InitNull, | |
279 | HMAC_UpdateNull, | |
280 | HMAC_FinalNull, | |
281 | HMAC_HmacNull | |
282 | }; | |
283 | ||
284 | const HMACReference TlsHmacSHA1 = { | |
285 | 20, | |
286 | HA_SHA1, | |
287 | HMAC_Alloc, | |
288 | HMAC_Free, | |
289 | HMAC_Init, | |
290 | HMAC_Update, | |
291 | HMAC_Final, | |
292 | HMAC_Hmac | |
293 | }; | |
294 | ||
295 | const HMACReference TlsHmacMD5 = { | |
296 | 16, | |
297 | HA_MD5, | |
298 | HMAC_Alloc, | |
299 | HMAC_Free, | |
300 | HMAC_Init, | |
301 | HMAC_Update, | |
302 | HMAC_Final, | |
303 | HMAC_Hmac | |
304 | }; | |
305 | ||
306 | const HashHmacReference HashHmacNull = { | |
307 | &SSLHashNull, | |
308 | &TlsHmacNull | |
309 | }; | |
310 | ||
311 | const HashHmacReference HashHmacMD5 = { | |
312 | &SSLHashMD5, | |
313 | &TlsHmacMD5 | |
314 | }; | |
315 | ||
316 | const HashHmacReference HashHmacSHA1 = { | |
317 | &SSLHashSHA1, | |
318 | &TlsHmacSHA1 | |
319 | }; |