#include "MacContext.h"
#include <PBKDF2/HMACSHA1.h>
#include <Security/cssmerr.h>
#include <Security/utilities.h>
#ifdef CRYPTKIT_CSP_ENABLE
#include <CryptKit/HmacSha1Legacy.h>
#endif
MacContext::~MacContext()
{
if(mHmac) {
hmacFree(mHmac);
mHmac = NULL;
}
}
void MacContext::init(const Context &context, bool isSigning)
{
if(mHmac == NULL) {
mHmac = hmacAlloc();
if(mHmac == NULL) {
CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
}
}
UInt32 keyLen;
UInt8 *keyData = NULL;
symmetricKeyBits(context, CSSM_ALGID_SHA1HMAC,
isSigning ? CSSM_KEYUSE_SIGN : CSSM_KEYUSE_VERIFY,
keyData, keyLen);
if((keyLen < HMAC_MIN_KEY_SIZE) || (keyLen > HMAC_MAX_KEY_SIZE)) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
}
CSSM_RETURN crtn = hmacInit(mHmac, keyData, keyLen);
if(crtn) {
CssmError::throwMe(crtn);
}
}
void MacContext::update(const CssmData &data)
{
CSSM_RETURN crtn = hmacUpdate(mHmac,
data.data(),
data.length());
if(crtn) {
CssmError::throwMe(crtn);
}
}
void MacContext::final(CssmData &out)
{
if(out.length() < kHMACSHA1DigestSize) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
hmacFinal(mHmac, out.data());
}
void MacContext::final(const CssmData &in)
{
unsigned char mac[kHMACSHA1DigestSize];
hmacFinal(mHmac, mac);
if(memcmp(mac, in.data(), kHMACSHA1DigestSize)) {
CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
}
}
size_t MacContext::outputSize(bool final, size_t inSize)
{
return kHMACSHA1DigestSize;
}
#ifdef CRYPTKIT_CSP_ENABLE
MacLegacyContext::~MacLegacyContext()
{
if(mHmac) {
hmacLegacyFree(mHmac);
mHmac = NULL;
}
}
void MacLegacyContext::init(const Context &context, bool isSigning)
{
if(mHmac == NULL) {
mHmac = hmacLegacyAlloc();
if(mHmac == NULL) {
CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
}
}
UInt32 keyLen;
UInt8 *keyData = NULL;
symmetricKeyBits(context, CSSM_ALGID_SHA1HMAC,
isSigning ? CSSM_KEYUSE_SIGN : CSSM_KEYUSE_VERIFY,
keyData, keyLen);
if((keyLen < HMAC_MIN_KEY_SIZE) || (keyLen > HMAC_MAX_KEY_SIZE)) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
}
OSStatus ortn = hmacLegacyInit(mHmac, keyData, keyLen);
if(ortn) {
MacOSError::throwMe(ortn);
}
}
void MacLegacyContext::update(const CssmData &data)
{
OSStatus ortn = hmacLegacyUpdate(mHmac,
data.data(),
data.length());
if(ortn) {
MacOSError::throwMe(ortn);
}
}
void MacLegacyContext::final(CssmData &out)
{
if(out.length() < kHMACSHA1DigestSize) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
hmacLegacyFinal(mHmac, out.data());
}
void MacLegacyContext::final(const CssmData &in)
{
unsigned char mac[kHMACSHA1DigestSize];
hmacLegacyFinal(mHmac, mac);
if(memcmp(mac, in.data(), kHMACSHA1DigestSize)) {
CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
}
}
size_t MacLegacyContext::outputSize(bool final, size_t inSize)
{
return kHMACSHA1DigestSize;
}
#endif