]> git.saurik.com Git - apple/security.git/blob - libsecurity_apple_csp/lib/gladmanContext.cpp
Security-55471.tar.gz
[apple/security.git] / libsecurity_apple_csp / lib / gladmanContext.cpp
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 /*
20 * gladmanContext.cpp - glue between BlockCryptor and Gladman AES implementation
21 * Written by Doug Mitchell 12/12/2001
22 */
23
24 #include "gladmanContext.h"
25 #include "cspdebugging.h"
26 #include <CommonCrypto/CommonCryptor.h>
27
28 /*
29 * AES encrypt/decrypt.
30 */
31 GAESContext::GAESContext(AppleCSPSession &session) :
32 BlockCryptor(session),
33 mAesKey(NULL),
34 mInitFlag(false),
35 mRawKeySize(0),
36 mWasEncrypting(false)
37 {
38 cbcCapable(false);
39 multiBlockCapable(false);
40 }
41
42 GAESContext::~GAESContext()
43 {
44 if(mAesKey) {
45 CCCryptorFinal(mAesKey,NULL,0,NULL);
46 CCCryptorRelease(mAesKey);
47 mAesKey = NULL;
48 }
49
50 deleteKey();
51 memset(mRawKey, 0, MAX_AES_KEY_BITS / 8);
52 mInitFlag = false;
53 }
54
55 void GAESContext::deleteKey()
56 {
57 mRawKeySize = 0;
58 }
59
60 /*
61 * Standard CSPContext init, called from CSPFullPluginSession::init().
62 * Reusable, e.g., query followed by en/decrypt. Even reusable after context
63 * changed (i.e., new IV in Encrypted File System).
64 */
65 void GAESContext::init(
66 const Context &context,
67 bool encrypting)
68 {
69 if(mInitFlag && !opStarted()) {
70 return;
71 }
72
73 CSSM_SIZE keyLen;
74 uint8 *keyData = NULL;
75 bool sameKeySize = false;
76
77 /* obtain key from context */
78 symmetricKeyBits(context, session(), CSSM_ALGID_AES,
79 encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
80 keyData, keyLen);
81
82 switch(keyLen) {
83 case kCCKeySizeAES128:
84 case kCCKeySizeAES192:
85 case kCCKeySizeAES256:
86 break;
87 default:
88 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
89 }
90
91 /*
92 * Delete existing key if key size changed
93 */
94 if(mRawKeySize == keyLen) {
95 sameKeySize = true;
96 }
97 else {
98 deleteKey();
99 }
100
101 /*
102 * Init key only if key size or key bits have changed, or
103 * we're doing a different operation than the previous key
104 * was scheduled for.
105 */
106 if(!sameKeySize || (mWasEncrypting != encrypting) ||
107 memcmp(mRawKey, keyData, mRawKeySize)) {
108 (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithmAES128, ccDefaultPadding, NULL, keyData, keyLen, NULL, 0, 0, 0, &mAesKey);
109
110 /* save this raw key data */
111 memmove(mRawKey, keyData, keyLen);
112 mRawKeySize = (uint32)keyLen;
113 mWasEncrypting = encrypting;
114 }
115
116 /* we handle CBC, and hence the IV, ourselves */
117 CSSM_ENCRYPT_MODE cssmMode = context.getInt(CSSM_ATTRIBUTE_MODE);
118 switch (cssmMode) {
119 /* no mode attr --> 0 == CSSM_ALGMODE_NONE, not currently supported */
120 case CSSM_ALGMODE_CBCPadIV8:
121 case CSSM_ALGMODE_CBC_IV8:
122 {
123 CssmData *iv = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR);
124 if(iv == NULL) {
125 CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR);
126 }
127 if(iv->Length != kCCBlockSizeAES128) {
128 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR);
129 }
130 }
131 break;
132 default:
133 break;
134 }
135
136 /* Finally, have BlockCryptor do its setup */
137 setup(GLADMAN_BLOCK_SIZE_BYTES, context);
138 mInitFlag = true;
139 }
140
141 /*
142 * Functions called by BlockCryptor
143 * FIXME make this multi-block capabl3e
144 */
145 void GAESContext::encryptBlock(
146 const void *plainText, // length implied (one block)
147 size_t plainTextLen,
148 void *cipherText,
149 size_t &cipherTextLen, // in/out, throws on overflow
150 bool final) // ignored
151 {
152 if(cipherTextLen < plainTextLen) {
153 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
154 }
155 (void) CCCryptorEncryptDataBlock(mAesKey, NULL, plainText, plainTextLen, cipherText);
156
157 cipherTextLen = plainTextLen;
158 }
159
160 void GAESContext::decryptBlock(
161 const void *cipherText, // length implied (one cipher block)
162 size_t cipherTextLen,
163 void *plainText,
164 size_t &plainTextLen, // in/out, throws on overflow
165 bool final) // ignored
166 {
167 if(plainTextLen < cipherTextLen) {
168 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
169 }
170 (void) CCCryptorDecryptDataBlock(mAesKey, NULL, cipherText, cipherTextLen, plainText);
171 plainTextLen = cipherTextLen;
172 }
173