CommonCryptorGCM.c [plain text]
#include "ccMemory.h"
#include "ccdebug.h"
#include "CommonCryptor.h"
#include "CommonCryptorSPI.h"
#include "CommonCryptorPriv.h"
#include <corecrypto/ccn.h>
#define CCCryptorGCMprologue() CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); \
CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); \
if(!cryptor) return kCCParamError;
static inline CCCryptorStatus translate_err_code(int err)
{
if (err==0) {
return kCCSuccess;
} else {
return kCCUnspecifiedError;
}
}
CCCryptorStatus
CCCryptorGCMAddIV(CCCryptorRef cryptorRef,
const void *iv,
size_t ivLen)
{
CCCryptorGCMprologue();
if(ivLen!=0 && iv==NULL) return kCCParamError;
int rc = ccgcm_set_iv_legacy(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, ivLen, iv);
return translate_err_code(rc);
}
CCCryptorStatus
CCCryptorGCMAddAAD(CCCryptorRef cryptorRef,
const void *aData,
size_t aDataLen)
{
CCCryptorGCMprologue();
if(aDataLen!=0 && aData==NULL) return kCCParamError;
int rc = ccgcm_gmac(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, aDataLen, aData);
return translate_err_code(rc);
}
CCCryptorStatus
CCCryptorGCMAddADD(CCCryptorRef cryptorRef,
const void *aData,
size_t aDataLen)
{
return CCCryptorGCMAddAAD(cryptorRef, aData, aDataLen);
}
CCCryptorStatus
CCCryptorGCMaddAAD(CCCryptorRef cryptorRef,
const void *aData,
size_t aDataLen)
{
return CCCryptorGCMAddAAD(cryptorRef, aData, aDataLen);
}
static CCCryptorStatus gcm_update(CCCryptorRef cryptorRef,
const void *dataIn,
size_t dataInLength,
void *dataOut)
{
CCCryptorGCMprologue();
if(dataInLength!=0 && dataIn==NULL) return kCCParamError;
if(dataOut == NULL) return kCCParamError;
int rc = ccgcm_update(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, dataInLength, dataIn, dataOut);
return translate_err_code(rc);
}
CCCryptorStatus CCCryptorGCMEncrypt(CCCryptorRef cryptorRef,
const void *dataIn,
size_t dataInLength,
void *dataOut)
{
return gcm_update(cryptorRef, dataIn, dataInLength, dataOut);
}
CCCryptorStatus CCCryptorGCMDecrypt(CCCryptorRef cryptorRef,
const void *dataIn,
size_t dataInLength,
void *dataOut)
{
return gcm_update(cryptorRef, dataIn, dataInLength, dataOut);
}
CCCryptorStatus CCCryptorGCMFinal(CCCryptorRef cryptorRef,
void *tagOut,
size_t *tagLength)
{
CCCryptorGCMprologue();
if(tagOut == NULL || tagLength == NULL) return kCCParamError;
int rc = ccgcm_finalize(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, *tagLength, (void *) tagOut);
if(rc == -1)
return kCCUnspecifiedError;
else
return kCCSuccess;
}
CCCryptorStatus CCCryptorGCMReset(CCCryptorRef cryptorRef)
{
CCCryptorGCMprologue();
int rc = ccgcm_reset(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm);
return translate_err_code(rc);
}
CCCryptorStatus CCCryptorGCM(CCOperation op,
CCAlgorithm alg,
const void *key, size_t keyLength,
const void *iv, size_t ivLen,
const void *aData, size_t aDataLen,
const void *dataIn, size_t dataInLength,
void *dataOut,
void *tagOut, size_t *tagLength)
{
CCCryptorRef cryptorRef;
CCCryptorStatus retval;
CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering Op: %d Cipher: %d\n", op, alg);
retval = CCCryptorCreateWithMode(op, kCCModeGCM, alg, 0, NULL, key, keyLength,
NULL, 0, 0, 0, &cryptorRef);
if(retval) return retval;
retval = CCCryptorGCMAddIV(cryptorRef, iv, ivLen);
if(retval) return retval;
retval = CCCryptorGCMaddAAD(cryptorRef, aData, aDataLen);
if(retval) return retval;
retval = gcm_update(cryptorRef, dataIn, dataInLength, dataOut);
if(retval) return retval;
retval = CCCryptorGCMFinal(cryptorRef, tagOut, tagLength);
CCCryptorRelease(cryptorRef);
return retval;
}