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