]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/lib/MacContext.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / lib / MacContext.cpp
1 /*
2 * Copyright (c) 2000-2001,2011-2012,2014 Apple 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 * MacContext.cpp - AppleCSPContext for HMACSHA1
20 */
21
22 #include "MacContext.h"
23 #include <HMACSHA1.h>
24 #include <Security/cssmerr.h>
25 #include <CommonCrypto/CommonDigest.h> /* for digest sizes */
26 #ifdef CRYPTKIT_CSP_ENABLE
27 #include <security_cryptkit/HmacSha1Legacy.h>
28 #endif /* CRYPTKIT_CSP_ENABLE */
29
30 MacContext::~MacContext()
31 {
32 memset(&hmacCtx, 0, sizeof(hmacCtx));
33 }
34
35 /* called out from CSPFullPluginSession....
36 * both generate and verify */
37 void MacContext::init(const Context &context, bool isSigning)
38 {
39 CCHmacAlgorithm ccAlg;
40
41 /* obtain key from context */
42 CSSM_SIZE keyLen;
43 uint8 *keyData = NULL;
44
45 symmetricKeyBits(context, session(), mAlg,
46 isSigning ? CSSM_KEYUSE_SIGN : CSSM_KEYUSE_VERIFY,
47 keyData, keyLen);
48 uint32 minKey = 0;
49 switch(mAlg) {
50 case CSSM_ALGID_SHA1HMAC:
51 minKey = HMAC_SHA_MIN_KEY_SIZE;
52 mDigestSize = CC_SHA1_DIGEST_LENGTH;
53 ccAlg = kCCHmacAlgSHA1;
54 break;
55 case CSSM_ALGID_MD5HMAC:
56 minKey = HMAC_MD5_MIN_KEY_SIZE;
57 mDigestSize = CC_MD5_DIGEST_LENGTH;
58 ccAlg = kCCHmacAlgMD5;
59 break;
60 default:
61 assert(0); // factory should not have called us
62 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
63 }
64 if((keyLen < minKey) || (keyLen > HMAC_MAX_KEY_SIZE)) {
65 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
66 }
67 CCHmacInit(&hmacCtx, ccAlg, keyData, keyLen);
68 }
69
70 void MacContext::update(const CssmData &data)
71 {
72 CCHmacUpdate(&hmacCtx, data.data(), data.length());
73 }
74
75 /* generate only */
76 void MacContext::final(CssmData &out)
77 {
78 if(out.length() < mDigestSize) {
79 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
80 }
81 CCHmacFinal(&hmacCtx, out.data());
82 out.Length = mDigestSize;
83 }
84
85 /* verify only */
86 #define MAX_DIGEST_SIZE CC_SHA1_DIGEST_LENGTH
87
88 void MacContext::final(const CssmData &in)
89 {
90 unsigned char mac[MAX_DIGEST_SIZE];
91
92 CCHmacFinal(&hmacCtx, mac);
93 if(memcmp(mac, in.data(), mDigestSize)) {
94 CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
95 }
96 }
97
98 size_t MacContext::outputSize(bool final, size_t inSize)
99 {
100 return mDigestSize;
101 }
102
103 #ifdef CRYPTKIT_CSP_ENABLE
104
105 MacLegacyContext::~MacLegacyContext()
106 {
107 if(mHmac) {
108 hmacLegacyFree(mHmac);
109 mHmac = NULL;
110 }
111 }
112
113 /* called out from CSPFullPluginSession....
114 * both generate and verify: */
115 void MacLegacyContext::init(const Context &context, bool isSigning)
116 {
117 if(mHmac == NULL) {
118 mHmac = hmacLegacyAlloc();
119 if(mHmac == NULL) {
120 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
121 }
122 }
123
124 /* obtain key from context */
125 CSSM_SIZE keyLen;
126 uint8 *keyData = NULL;
127
128 /* FIXME - this may require a different key alg */
129 symmetricKeyBits(context, session(), CSSM_ALGID_SHA1HMAC,
130 isSigning ? CSSM_KEYUSE_SIGN : CSSM_KEYUSE_VERIFY,
131 keyData, keyLen);
132 if((keyLen < HMAC_SHA_MIN_KEY_SIZE) || (keyLen > HMAC_MAX_KEY_SIZE)) {
133 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
134 }
135
136 OSStatus ortn = hmacLegacyInit(mHmac, keyData, (UInt32)keyLen);
137 if(ortn) {
138 MacOSError::throwMe(ortn);
139 }
140 }
141
142 void MacLegacyContext::update(const CssmData &data)
143 {
144 OSStatus ortn = hmacLegacyUpdate(mHmac,
145 data.data(),
146 (UInt32)data.length());
147 if(ortn) {
148 MacOSError::throwMe(ortn);
149 }
150 }
151
152 /* generate only */
153 void MacLegacyContext::final(CssmData &out)
154 {
155 if(out.length() < kHMACSHA1DigestSize) {
156 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
157 }
158 hmacLegacyFinal(mHmac, out.data());
159 }
160
161 /* verify only */
162 void MacLegacyContext::final(const CssmData &in)
163 {
164 unsigned char mac[kHMACSHA1DigestSize];
165 hmacLegacyFinal(mHmac, mac);
166 if(memcmp(mac, in.data(), kHMACSHA1DigestSize)) {
167 CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
168 }
169 }
170
171 size_t MacLegacyContext::outputSize(bool final, size_t inSize)
172 {
173 return kHMACSHA1DigestSize;
174 }
175
176 #endif /* CRYPTKIT_CSP_ENABLE */