]> git.saurik.com Git - apple/security.git/blame - SecureTransport/tls_hmac.cpp
Security-163.tar.gz
[apple/security.git] / SecureTransport / tls_hmac.cpp
CommitLineData
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 */
37struct 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 46static 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 108static 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 122static 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 143static 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 167static 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 196static 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 224static 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 235static OSStatus HMAC_FreeNull(
29654253
A
236 HMACContextRef hmacCtx)
237{
5a719ac8 238 return noErr;
29654253
A
239}
240
5a719ac8 241static OSStatus HMAC_InitNull(
29654253
A
242 HMACContextRef hmacCtx)
243 {
5a719ac8 244 return noErr;
29654253
A
245}
246
5a719ac8 247static 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 255static 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 263static 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
273const 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
284const 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
295const 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
306const HashHmacReference HashHmacNull = {
307 &SSLHashNull,
308 &TlsHmacNull
309};
310
311const HashHmacReference HashHmacMD5 = {
312 &SSLHashMD5,
313 &TlsHmacMD5
314};
315
316const HashHmacReference HashHmacSHA1 = {
317 &SSLHashSHA1,
318 &TlsHmacSHA1
319};