]> git.saurik.com Git - apple/security.git/blob - SecureTransport/tls_hmac.cpp
Security-54.1.9.tar.gz
[apple/security.git] / SecureTransport / tls_hmac.cpp
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 "sslMemory.h"
30 #include "cryptType.h"
31 #include "sslDigests.h"
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 */
46 static OSStatus HMAC_Alloc(
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;
55 OSStatus serr;
56 CSSM_ALGORITHMS calg;
57 HMACContextRef href = (HMACContextRef)sslMalloc(sizeof(struct HMACContext));
58
59 if(href == NULL) {
60 return memFullErr;
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);
79 return errSSLInternal;
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) {
98 return errSSLCrypto;
99 }
100
101 /* success */
102 *hmacCtx = href;
103 return noErr;
104 }
105
106 /* free a session */
107 static OSStatus HMAC_Free(
108 HMACContextRef hmacCtx)
109 {
110 if(hmacCtx != NULL) {
111 if(hmacCtx->ccHand != 0) {
112 CSSM_DeleteContext(hmacCtx->ccHand);
113 hmacCtx->ccHand = 0;
114 }
115 sslFree(hmacCtx);
116 }
117 return noErr;
118 }
119
120 /* Reusable init */
121 static OSStatus HMAC_Init(
122 HMACContextRef hmacCtx)
123 {
124 CSSM_RETURN crtn;
125
126 if(hmacCtx == NULL) {
127 return errSSLInternal;
128 }
129 assert(hmacCtx->ctx != NULL);
130 assert(hmacCtx->hmac != NULL);
131 assert(hmacCtx->ccHand != 0);
132
133 crtn = CSSM_GenerateMacInit(hmacCtx->ccHand);
134 if(crtn) {
135 return errSSLCrypto;
136 }
137 return noErr;
138 }
139
140 /* normal crypt ops */
141 static OSStatus HMAC_Update(
142 HMACContextRef hmacCtx,
143 const void *data,
144 unsigned dataLen)
145 {
146 CSSM_RETURN crtn;
147 CSSM_DATA cdata;
148
149 if(hmacCtx == NULL) {
150 return errSSLInternal;
151 }
152 assert(hmacCtx->ctx != NULL);
153 assert(hmacCtx->hmac != NULL);
154 assert(hmacCtx->ccHand != 0);
155 cdata.Data = (uint8 *)data;
156 cdata.Length = dataLen;
157 crtn = CSSM_GenerateMacUpdate(hmacCtx->ccHand, &cdata, 1);
158 if(crtn) {
159 return errSSLCrypto;
160 }
161 return noErr;
162 }
163
164 static OSStatus HMAC_Final(
165 HMACContextRef hmacCtx,
166 void *hmac, // mallocd by caller
167 unsigned *hmacLen) // IN/OUT
168 {
169 CSSM_RETURN crtn;
170 CSSM_DATA cdata;
171
172 if(hmacCtx == NULL) {
173 return errSSLInternal;
174 }
175 if((hmac == NULL) || (hmacLen == 0)) {
176 return errSSLInternal;
177 }
178 assert(hmacCtx->ctx != NULL);
179 assert(hmacCtx->hmac != NULL);
180 assert(hmacCtx->ccHand != 0);
181 cdata.Data = (uint8 *)hmac;
182 cdata.Length = *hmacLen;
183 crtn = CSSM_GenerateMacFinal(hmacCtx->ccHand, &cdata);
184 if(crtn) {
185 return errSSLCrypto;
186 }
187 *hmacLen = cdata.Length;
188 return noErr;
189 }
190
191 /* one-shot */
192 static OSStatus HMAC_Hmac (
193 HMACContextRef hmacCtx,
194 const void *data,
195 unsigned dataLen,
196 void *hmac, // mallocd by caller
197 unsigned *hmacLen) // IN/OUT
198 {
199 OSStatus serr;
200 const HMACReference *hmacRef;
201
202 if(hmacCtx == NULL) {
203 return errSSLInternal;
204 }
205 hmacRef = hmacCtx->hmac;
206 assert(hmacRef != NULL);
207 serr = hmacRef->init(hmacCtx);
208 if(serr) {
209 return serr;
210 }
211 serr = hmacRef->update(hmacCtx, data, dataLen);
212 if(serr) {
213 return serr;
214 }
215 return hmacRef->final(hmacCtx, hmac, hmacLen);
216 }
217
218 #pragma mark *** Null HMAC ***
219
220 static OSStatus HMAC_AllocNull(
221 const struct HMACReference *hmac,
222 SSLContext *ctx,
223 const void *keyPtr,
224 unsigned keyLen,
225 HMACContextRef *hmacCtx) // RETURNED
226 {
227 *hmacCtx = NULL;
228 return noErr;
229 }
230
231 static OSStatus HMAC_FreeNull(
232 HMACContextRef hmacCtx)
233 {
234 return noErr;
235 }
236
237 static OSStatus HMAC_InitNull(
238 HMACContextRef hmacCtx)
239 {
240 return noErr;
241 }
242
243 static OSStatus HMAC_UpdateNull(
244 HMACContextRef hmacCtx,
245 const void *data,
246 unsigned dataLen)
247 {
248 return noErr;
249 }
250
251 static OSStatus HMAC_FinalNull(
252 HMACContextRef hmacCtx,
253 void *hmac, // mallocd by caller
254 unsigned *hmacLen) // IN/OUT
255 {
256 return noErr;
257 }
258
259 static OSStatus HMAC_HmacNull (
260 HMACContextRef hmacCtx,
261 const void *data,
262 unsigned dataLen,
263 void *hmac, // mallocd by caller
264 unsigned *hmacLen)
265 {
266 return noErr;
267 }
268
269 const HMACReference TlsHmacNull = {
270 0,
271 HA_Null,
272 HMAC_AllocNull,
273 HMAC_FreeNull,
274 HMAC_InitNull,
275 HMAC_UpdateNull,
276 HMAC_FinalNull,
277 HMAC_HmacNull
278 };
279
280 const HMACReference TlsHmacSHA1 = {
281 20,
282 HA_SHA1,
283 HMAC_Alloc,
284 HMAC_Free,
285 HMAC_Init,
286 HMAC_Update,
287 HMAC_Final,
288 HMAC_Hmac
289 };
290
291 const HMACReference TlsHmacMD5 = {
292 16,
293 HA_MD5,
294 HMAC_Alloc,
295 HMAC_Free,
296 HMAC_Init,
297 HMAC_Update,
298 HMAC_Final,
299 HMAC_Hmac
300 };
301
302 const HashHmacReference HashHmacNull = {
303 &SSLHashNull,
304 &TlsHmacNull
305 };
306
307 const HashHmacReference HashHmacMD5 = {
308 &SSLHashMD5,
309 &TlsHmacMD5
310 };
311
312 const HashHmacReference HashHmacSHA1 = {
313 &SSLHashSHA1,
314 &TlsHmacSHA1
315 };