1/* 2 * Copyright (c) 2000-2001 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 * 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 30MacContext::~MacContext() 31{ 32 memset(&hmacCtx, 0, sizeof(hmacCtx)); 33} 34 35/* called out from CSPFullPluginSession.... 36 * both generate and verify */ 37void 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 70void MacContext::update(const CssmData &data) 71{ 72 CCHmacUpdate(&hmacCtx, data.data(), data.length()); 73} 74 75/* generate only */ 76void 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 88void 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 98size_t MacContext::outputSize(bool final, size_t inSize) 99{ 100 return mDigestSize; 101} 102 103#ifdef CRYPTKIT_CSP_ENABLE 104 105MacLegacyContext::~MacLegacyContext() 106{ 107 if(mHmac) { 108 hmacLegacyFree(mHmac); 109 mHmac = NULL; 110 } 111} 112 113/* called out from CSPFullPluginSession.... 114 * both generate and verify: */ 115void 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 142void 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 */ 153void 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 */ 162void 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 171size_t MacLegacyContext::outputSize(bool final, size_t inSize) 172{ 173 return kHMACSHA1DigestSize; 174} 175 176#endif /* CRYPTKIT_CSP_ENABLE */ 177