1/* 2 * Copyright (c) 2012 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// #define COMMON_GCM_FUNCTIONS 25#include "ccMemory.h" 26#include "ccdebug.h" 27#include "CommonCryptor.h" 28#include "CommonCryptorSPI.h" 29#include "CommonCryptorPriv.h" 30#include <corecrypto/ccmode_factory.h> 31 32 33CCCryptorStatus 34CCCryptorGCMAddIV(CCCryptorRef cryptorRef, 35 const void *iv, 36 size_t ivLen) 37{ 38 CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); 39 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 40 if(!cryptor) return kCCParamError; 41 ccmode_gcm_set_iv(cryptor->ctx[cryptor->op].gcm, ivLen, iv); 42 return kCCSuccess; 43} 44 45 46CCCryptorStatus 47CCCryptorGCMAddAAD(CCCryptorRef cryptorRef, 48 const void *aData, 49 size_t aDataLen) 50{ 51 CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); 52 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 53 if(!cryptor) return kCCParamError; 54 ccmode_gcm_gmac(cryptor->ctx[cryptor->op].gcm, aDataLen, aData); 55 return kCCSuccess; 56} 57 58// This is for old iOS5 clients 59CCCryptorStatus 60CCCryptorGCMAddADD(CCCryptorRef cryptorRef, 61 const void *aData, 62 size_t aDataLen) 63{ 64 return CCCryptorGCMAddAAD(cryptorRef, aData, aDataLen); 65} 66 67// This was a temp mistake in MacOSX8 68CCCryptorStatus 69CCCryptorGCMaddAAD(CCCryptorRef cryptorRef, 70 const void *aData, 71 size_t aDataLen) 72{ 73 return CCCryptorGCMAddAAD(cryptorRef, aData, aDataLen); 74} 75 76 77 78CCCryptorStatus CCCryptorGCMEncrypt( 79 CCCryptorRef cryptorRef, 80 const void *dataIn, 81 size_t dataInLength, 82 void *dataOut) 83{ 84 CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); 85 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 86 if(!cryptor) return kCCParamError; 87 if(dataIn == NULL || dataOut == NULL) return kCCParamError; 88 ccmode_gcm_encrypt(cryptor->ctx[cryptor->op].gcm, dataInLength, dataIn, dataOut); 89 return kCCSuccess; 90} 91 92 93 94CCCryptorStatus CCCryptorGCMDecrypt( 95 CCCryptorRef cryptorRef, 96 const void *dataIn, 97 size_t dataInLength, 98 void *dataOut) 99{ 100 CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); 101 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 102 if(!cryptor) return kCCParamError; 103 if(dataIn == NULL || dataOut == NULL) return kCCParamError; 104 ccmode_gcm_decrypt(cryptor->ctx[cryptor->op].gcm, dataInLength, dataIn, dataOut); 105 return kCCSuccess; 106} 107 108 109 110CCCryptorStatus CCCryptorGCMFinal( 111 CCCryptorRef cryptorRef, 112 const void *tag, 113 size_t *tagLength) 114{ 115 CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); 116 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 117 if(!cryptor) return kCCParamError; 118 if(tag == NULL || tagLength == NULL) return kCCParamError; 119 ccmode_gcm_finalize(cryptor->ctx[cryptor->op].gcm, *tagLength, (void *)tag); 120 return kCCSuccess; 121} 122 123 124 125CCCryptorStatus CCCryptorGCMReset( 126 CCCryptorRef cryptorRef) 127{ 128 CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); 129 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 130 if(!cryptor) return kCCParamError; 131 ccmode_gcm_reset(cryptor->ctx[cryptor->op].gcm); 132 return kCCSuccess; 133} 134 135 136 137CCCryptorStatus CCCryptorGCM( 138 CCOperation op, /* kCCEncrypt, kCCDecrypt */ 139 CCAlgorithm alg, 140 const void *key, /* raw key material */ 141 size_t keyLength, 142 const void *iv, 143 size_t ivLen, 144 const void *aData, 145 size_t aDataLen, 146 const void *dataIn, 147 size_t dataInLength, 148 void *dataOut, 149 const void *tag, 150 size_t *tagLength) 151{ 152 CCCryptorRef cryptorRef; 153 CCCryptorStatus retval; 154 155 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering Op: %d Cipher: %d\n", op, alg); 156 157 retval = CCCryptorCreateWithMode(op, kCCModeGCM, alg, 0, NULL, key, keyLength, 158 NULL, 0, 0, 0, &cryptorRef); 159 if(retval) return retval; 160 161 // IV is optional 162 if(ivLen) { 163 retval = CCCryptorGCMAddIV(cryptorRef, iv, ivLen); 164 if(retval) return retval; 165 } 166 167 // This must always be called - even with no aData. 168 retval = CCCryptorGCMaddAAD(cryptorRef, aData, aDataLen); 169 if(retval) return retval; 170 171 if(op == kCCEncrypt) 172 retval = CCCryptorGCMEncrypt(cryptorRef, dataIn, dataInLength, dataOut); 173 else if(op == kCCDecrypt) 174 retval = CCCryptorGCMDecrypt(cryptorRef, dataIn, dataInLength, dataOut); 175 else return kCCParamError; 176 if(retval) return retval; 177 178 retval = CCCryptorGCMFinal(cryptorRef, tag, tagLength); 179 CCCryptorRelease(cryptorRef); 180 181 return retval; 182} 183 184 185