2 * Copyright (c) 2000-2001,2011-2012,2014 Apple Inc. All Rights Reserved.
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
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.
20 * gladmanContext.cpp - glue between BlockCryptor and Gladman AES implementation
23 #include "gladmanContext.h"
24 #include "cspdebugging.h"
25 #include <CommonCrypto/CommonCryptor.h>
28 * AES encrypt/decrypt.
30 GAESContext::GAESContext(AppleCSPSession
&session
) :
31 BlockCryptor(session
),
38 multiBlockCapable(false);
41 GAESContext::~GAESContext()
44 CCCryptorFinal(mAesKey
,NULL
,0,NULL
);
45 CCCryptorRelease(mAesKey
);
50 memset(mRawKey
, 0, MAX_AES_KEY_BITS
/ 8);
54 void GAESContext::deleteKey()
60 * Standard CSPContext init, called from CSPFullPluginSession::init().
61 * Reusable, e.g., query followed by en/decrypt. Even reusable after context
62 * changed (i.e., new IV in Encrypted File System).
64 void GAESContext::init(
65 const Context
&context
,
68 if(mInitFlag
&& !opStarted()) {
73 uint8
*keyData
= NULL
;
74 bool sameKeySize
= false;
76 /* obtain key from context */
77 symmetricKeyBits(context
, session(), CSSM_ALGID_AES
,
78 encrypting
? CSSM_KEYUSE_ENCRYPT
: CSSM_KEYUSE_DECRYPT
,
82 case kCCKeySizeAES128
:
83 case kCCKeySizeAES192
:
84 case kCCKeySizeAES256
:
87 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY
);
91 * Delete existing key if key size changed
93 if(mRawKeySize
== keyLen
) {
101 * Init key only if key size or key bits have changed, or
102 * we're doing a different operation than the previous key
105 if(!sameKeySize
|| (mWasEncrypting
!= encrypting
) ||
106 memcmp(mRawKey
, keyData
, mRawKeySize
)) {
107 (void) CCCryptorCreateWithMode(0, kCCModeECB
, kCCAlgorithmAES128
, ccDefaultPadding
, NULL
, keyData
, keyLen
, NULL
, 0, 0, 0, &mAesKey
);
109 /* save this raw key data */
110 memmove(mRawKey
, keyData
, keyLen
);
111 mRawKeySize
= (uint32
)keyLen
;
112 mWasEncrypting
= encrypting
;
115 /* we handle CBC, and hence the IV, ourselves */
116 CSSM_ENCRYPT_MODE cssmMode
= context
.getInt(CSSM_ATTRIBUTE_MODE
);
118 /* no mode attr --> 0 == CSSM_ALGMODE_NONE, not currently supported */
119 case CSSM_ALGMODE_CBCPadIV8
:
120 case CSSM_ALGMODE_CBC_IV8
:
122 CssmData
*iv
= context
.get
<CssmData
>(CSSM_ATTRIBUTE_INIT_VECTOR
);
124 CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR
);
126 if(iv
->Length
!= kCCBlockSizeAES128
) {
127 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR
);
135 /* Finally, have BlockCryptor do its setup */
136 setup(GLADMAN_BLOCK_SIZE_BYTES
, context
);
141 * Functions called by BlockCryptor
142 * FIXME make this multi-block capabl3e
144 void GAESContext::encryptBlock(
145 const void *plainText
, // length implied (one block)
148 size_t &cipherTextLen
, // in/out, throws on overflow
149 bool final
) // ignored
151 if(cipherTextLen
< plainTextLen
) {
152 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
154 (void) CCCryptorEncryptDataBlock(mAesKey
, NULL
, plainText
, plainTextLen
, cipherText
);
156 cipherTextLen
= plainTextLen
;
159 void GAESContext::decryptBlock(
160 const void *cipherText
, // length implied (one cipher block)
161 size_t cipherTextLen
,
163 size_t &plainTextLen
, // in/out, throws on overflow
164 bool final
) // ignored
166 if(plainTextLen
< cipherTextLen
) {
167 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
169 (void) CCCryptorDecryptDataBlock(mAesKey
, NULL
, cipherText
, cipherTextLen
, plainText
);
170 plainTextLen
= cipherTextLen
;