]>
git.saurik.com Git - apple/security.git/blob - SecureTransport/symCipher.cpp
2 * Copyright (c) 2000-2001 Apple Computer, 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.
22 Contains: CDSA-based symmetric cipher module
24 Written by: Doug Mitchell
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
30 #include "sslContext.h"
31 #include "cryptType.h"
33 #include "sslMemory.h"
34 #include "appleCdsa.h"
35 #include "symCipher.h"
37 #include <Security/cssm.h>
41 /* dispose of dynamically allocated resources in a CipherContext */
42 static void disposeCipherCtx(
43 CipherContext
*cipherCtx
)
45 assert(cipherCtx
!= NULL
);
46 if(cipherCtx
->symKey
!= NULL
) {
47 assert(cipherCtx
->cspHand
!= 0);
48 CSSM_FreeKey(cipherCtx
->cspHand
, NULL
, cipherCtx
->symKey
, CSSM_FALSE
);
49 sslFree(cipherCtx
->symKey
);
50 cipherCtx
->symKey
= NULL
;
52 cipherCtx
->cspHand
= 0;
53 if(cipherCtx
->ccHand
!= 0) {
54 CSSM_DeleteContext(cipherCtx
->ccHand
);
55 cipherCtx
->ccHand
= 0;
59 OSStatus
CDSASymmInit(
62 CipherContext
*cipherCtx
,
66 * Cook up a symmetric key and a CCSM_CC_HANDLE. Assumes:
67 * cipherCtx->symCipher.keyAlg
71 * Resulting CSSM_KEY_PTR --> cipherCtx->symKey
72 * Resulting CSSM_CC_HANDLE --> cipherCtx->ccHand
73 * (Currently) a copy of ctx->cspHand --> cipherCtx->cspHand
75 * FIXME - for now we assume that ctx->cspHand is capable of
76 * using the specified algorithm, keysize, and mode. This
77 * may need revisiting.
80 OSStatus serr
= errSSLInternal
;
82 const SSLSymmetricCipher
*symCipher
;
84 CSSM_DATA_PTR ivDataPtr
= NULL
;
85 CSSM_KEY_PTR symKey
= NULL
;
86 CSSM_CC_HANDLE ccHand
= 0;
89 assert(cipherCtx
!= NULL
);
90 assert(cipherCtx
->symCipher
!= NULL
);
92 if(ctx
->cspHand
== 0) {
93 sslErrorLog("CDSASymmInit: NULL cspHand!\n");
94 return errSSLInternal
;
97 /* clean up cipherCtx */
98 disposeCipherCtx(cipherCtx
);
100 /* cook up a raw key */
101 symKey
= (CSSM_KEY_PTR
)sslMalloc(sizeof(CSSM_KEY
));
105 serr
= sslSetUpSymmKey(symKey
, cipherCtx
->symCipher
->keyAlg
,
106 CSSM_KEYUSE_ENCRYPT
| CSSM_KEYUSE_DECRYPT
, CSSM_TRUE
,
107 key
, cipherCtx
->symCipher
->keySize
);
113 cipherCtx
->symKey
= symKey
;
115 /* now the crypt handle */
116 symCipher
= cipherCtx
->symCipher
;
117 if(symCipher
->ivSize
!= 0) {
119 ivData
.Length
= symCipher
->ivSize
;
122 crtn
= CSSM_CSP_CreateSymmetricContext(ctx
->cspHand
,
132 stPrintCdsaError("CSSM_CSP_CreateSymmetricContext", crtn
);
136 cipherCtx
->ccHand
= ccHand
;
138 /* after this, each en/decrypt is merely an update */
139 if(cipherCtx
->encrypting
) {
140 crtn
= CSSM_EncryptDataInit(ccHand
);
141 op
= "CSSM_EncryptDataInit";
144 crtn
= CSSM_DecryptDataInit(ccHand
);
145 op
= "CSSM_DecryptDataInit";
148 stPrintCdsaError("CSSM_CSP_EncryptDataInit", crtn
);
154 cipherCtx
->cspHand
= ctx
->cspHand
;
159 /* dispose of the stuff we created */
160 disposeCipherCtx(cipherCtx
);
165 #define REDECRYPT_DATA 0
167 #define LOG_SYMM_DATA 0
169 static void logSymmData(
176 printf("%s: ", field
);
177 for(i
=0; i
<data
->length
; i
++) {
181 printf("%02X", data
->data
[i
]);
188 #else /* LOG_SYMM_DATA */
189 #define logSymmData(f, d, l)
190 #endif /* LOG_SYMM_DATA */
192 #define IS_ALIGNED(count, blockSize) ((count % blockSize) == 0)
194 OSStatus
CDSASymmEncrypt(
197 CipherContext
*cipherCtx
,
203 uint32 bytesEncrypted
;
204 OSStatus serr
= errSSLInternal
;
205 uint32 origLen
= dest
.length
;
213 assert(cipherCtx
!= NULL
);
214 logSymmData("Symm encrypt ptext", &src
, 48);
216 /* this requirement allows us to avoid a malloc and copy */
217 assert(dest
.length
>= src
.length
);
221 unsigned blockSize
= cipherCtx
->symCipher
->blockSize
;
223 if(!IS_ALIGNED(src
.length
, blockSize
)) {
224 sslErrorLog("CDSASymmEncrypt: unaligned ptext (len %ld bs %d)\n",
225 src
.length
, blockSize
);
226 return errSSLInternal
;
228 if(!IS_ALIGNED(dest
.length
, blockSize
)) {
229 sslErrorLog("CDSASymmEncrypt: unaligned ctext (len %ld bs %d)\n",
230 dest
.length
, blockSize
);
231 return errSSLInternal
;
237 if((cipherCtx
->ccHand
== 0) || (cipherCtx
->cspHand
== 0)) {
238 sslErrorLog("CDSASymmEncrypt: null args\n");
239 return errSSLInternal
;
241 SSLBUF_TO_CSSM(&src
, &ptextData
);
242 SSLBUF_TO_CSSM(&dest
, &ctextData
);
243 crtn
= CSSM_EncryptDataUpdate(cipherCtx
->ccHand
,
250 stPrintCdsaError("CSSM_EncryptDataUpdate", crtn
);
255 if(bytesEncrypted
> origLen
) {
256 /* should never happen, callers always give us block-aligned
257 * plaintext and CSP padding is disabled. */
258 sslErrorLog("Symmetric encrypt overflow: bytesEncrypted %ld destLen %ld\n",
259 bytesEncrypted
, dest
.length
);
263 dest
.length
= bytesEncrypted
;
264 logSymmData("Symm encrypt ctext", &dest
, 48);
271 OSStatus
CDSASymmDecrypt(
274 CipherContext
*cipherCtx
,
278 CSSM_DATA ptextData
= {0, NULL
};
280 uint32 bytesDecrypted
;
281 OSStatus serr
= errSSLInternal
;
282 uint32 origLen
= dest
.length
;
290 assert(cipherCtx
!= NULL
);
291 if((cipherCtx
->ccHand
== 0) || (cipherCtx
->cspHand
== 0)) {
292 sslErrorLog("CDSASymmDecrypt: null args\n");
293 return errSSLInternal
;
295 /* this requirement allows us to avoid a malloc and copy */
296 assert(dest
.length
>= src
.length
);
300 unsigned blockSize
= cipherCtx
->symCipher
->blockSize
;
302 if(!IS_ALIGNED(src
.length
, blockSize
)) {
303 sslErrorLog("CDSASymmDecrypt: unaligned ctext (len %ld bs %d)\n",
304 src
.length
, blockSize
);
305 return errSSLInternal
;
307 if(!IS_ALIGNED(dest
.length
, blockSize
)) {
308 sslErrorLog("CDSASymmDecrypt: unaligned ptext (len %ld bs %d)\n",
309 dest
.length
, blockSize
);
310 return errSSLInternal
;
316 SSLBUF_TO_CSSM(&src
, &ctextData
);
317 SSLBUF_TO_CSSM(&dest
, &ptextData
);
318 crtn
= CSSM_DecryptDataUpdate(cipherCtx
->ccHand
,
325 stPrintCdsaError("CSSM_DecryptDataUpdate", crtn
);
330 if(bytesDecrypted
> origLen
) {
331 /* FIXME - can this happen? Should we remalloc? */
332 sslErrorLog("Symmetric decrypt overflow: bytesDecrypted %ld destLen %ld\n",
333 bytesDecrypted
, dest
.length
);
337 dest
.length
= bytesDecrypted
;
339 logSymmData("Symm decrypt ptext(1)", &dest
, 48);
344 OSStatus
CDSASymmFinish(
345 CipherContext
*cipherCtx
,
348 /* dispose of cipherCtx->{symKey,cspHand,ccHand} */
349 disposeCipherCtx(cipherCtx
);