]>
git.saurik.com Git - apple/security.git/blob - SecureTransport/symCipher.c
a70b1d90e44f63bdaf1d31076031d3ff0ac3daa2
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, based on Netscape SSLRef 3.0
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
29 /* *********************************************************************
32 SSLRef 3.0 Final -- 11/19/96
34 Copyright (c)1996 by Netscape Communications Corp.
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
44 *********************************************************************
46 File: ciphers.c Data structures for handling supported ciphers
48 Contains a table mapping cipherSuite values to the ciphers, MAC
49 algorithms, key exchange procedures and so on that are used for that
50 algorithm, in order of preference.
52 ****************************************************************** */
55 #include "cryptType.h"
58 #include "appleCdsa.h"
59 #include "symCipher.h"
61 #include <Security/cssm.h>
65 /* dispose of dynamically allocated resources in a CipherContext */
66 static void disposeCipherCtx(
67 CipherContext
*cipherCtx
)
69 CASSERT(cipherCtx
!= NULL
);
70 if(cipherCtx
->symKey
!= NULL
) {
71 CASSERT(cipherCtx
->cspHand
!= 0);
72 CSSM_FreeKey(cipherCtx
->cspHand
, NULL
, cipherCtx
->symKey
, CSSM_FALSE
);
73 sslFree(cipherCtx
->symKey
);
74 cipherCtx
->symKey
= NULL
;
76 cipherCtx
->cspHand
= 0;
77 if(cipherCtx
->ccHand
!= 0) {
78 CSSM_DeleteContext(cipherCtx
->ccHand
);
79 cipherCtx
->ccHand
= 0;
86 CipherContext
*cipherCtx
,
90 * Cook up a symmetric key and a CCSM_CC_HANDLE. Assumes:
91 * cipherCtx->symCipher.keyAlg
95 * Resulting CSSM_KEY_PTR --> cipherCtx->symKey
96 * Resulting CSSM_CC_HANDLE --> cipherCtx->ccHand
97 * (Currently) a copy of ctx->cspHand --> cipherCtx->cspHand
99 * FIXME - for now we assume that ctx->cspHand is capable of
100 * using the specified algorithm, keysize, and mode. This
101 * may need revisiting.
104 SSLErr serr
= SSLInternalError
;
106 const SSLSymmetricCipher
*symCipher
;
108 CSSM_DATA_PTR ivDataPtr
= NULL
;
109 CSSM_KEY_PTR symKey
= NULL
;
110 CSSM_CC_HANDLE ccHand
= 0;
113 CASSERT(cipherCtx
!= NULL
);
114 CASSERT(cipherCtx
->symCipher
!= NULL
);
115 CASSERT(ctx
!= NULL
);
116 if(ctx
->cspHand
== 0) {
117 errorLog0("CDSASymmInit: NULL cspHand!\n");
118 return SSLInternalError
;
121 /* clean up cipherCtx */
122 disposeCipherCtx(cipherCtx
);
124 /* cook up a raw key */
125 symKey
= sslMalloc(sizeof(CSSM_KEY
));
129 serr
= sslSetUpSymmKey(symKey
, cipherCtx
->symCipher
->keyAlg
,
130 CSSM_KEYUSE_ENCRYPT
| CSSM_KEYUSE_DECRYPT
, CSSM_TRUE
,
131 key
, cipherCtx
->symCipher
->keySize
);
137 cipherCtx
->symKey
= symKey
;
139 /* now the crypt handle */
140 symCipher
= cipherCtx
->symCipher
;
141 if(symCipher
->ivSize
!= 0) {
143 ivData
.Length
= symCipher
->ivSize
;
146 crtn
= CSSM_CSP_CreateSymmetricContext(ctx
->cspHand
,
156 stPrintCdsaError("CSSM_CSP_CreateSymmetricContext", crtn
);
157 serr
= SSLCryptoError
;
160 cipherCtx
->ccHand
= ccHand
;
162 /* after this, each en/decrypt is merely an update */
163 if(cipherCtx
->encrypting
) {
164 crtn
= CSSM_EncryptDataInit(ccHand
);
165 op
= "CSSM_EncryptDataInit";
168 crtn
= CSSM_DecryptDataInit(ccHand
);
169 op
= "CSSM_DecryptDataInit";
172 stPrintCdsaError("CSSM_CSP_EncryptDataInit", crtn
);
173 serr
= SSLCryptoError
;
178 cipherCtx
->cspHand
= ctx
->cspHand
;
183 /* dispose of the stuff we created */
184 disposeCipherCtx(cipherCtx
);
189 #define REDECRYPT_DATA 0
191 #define LOG_SYMM_DATA 0
193 static void logSymmData(
200 printf("%s: ", field
);
201 for(i
=0; i
<data
->length
; i
++) {
205 printf("%02X", data
->data
[i
]);
212 #else /* LOG_SYMM_DATA */
213 #define logSymmData(f, d, l)
214 #endif /* LOG_SYMM_DATA */
216 #define IS_ALIGNED(count, blockSize) ((count % blockSize) == 0)
218 SSLErr
CDSASymmEncrypt(
221 CipherContext
*cipherCtx
,
227 uint32 bytesEncrypted
;
228 SSLErr serr
= SSLInternalError
;
229 uint32 origLen
= dest
.length
;
236 CASSERT(ctx
!= NULL
);
237 CASSERT(cipherCtx
!= NULL
);
238 logSymmData("Symm encrypt ptext", &src
, 48);
240 /* this requirement allows us to avoid a malloc and copy */
241 CASSERT(dest
.length
>= src
.length
);
245 unsigned blockSize
= cipherCtx
->symCipher
->blockSize
;
247 if(!IS_ALIGNED(src
.length
, blockSize
)) {
248 errorLog2("CDSASymmEncrypt: unaligned ptext (len %ld bs %d)\n",
249 src
.length
, blockSize
);
250 return SSLInternalError
;
252 if(!IS_ALIGNED(dest
.length
, blockSize
)) {
253 errorLog2("CDSASymmEncrypt: unaligned ctext (len %ld bs %d)\n",
254 dest
.length
, blockSize
);
255 return SSLInternalError
;
261 if((cipherCtx
->ccHand
== 0) || (cipherCtx
->cspHand
== 0)) {
262 errorLog0("CDSASymmEncrypt: null args\n");
263 return SSLInternalError
;
265 SSLBUF_TO_CSSM(&src
, &ptextData
);
266 SSLBUF_TO_CSSM(&dest
, &ctextData
);
267 crtn
= CSSM_EncryptDataUpdate(cipherCtx
->ccHand
,
274 stPrintCdsaError("CSSM_EncryptDataUpdate", crtn
);
275 serr
= SSLCryptoError
;
279 if(bytesEncrypted
> origLen
) {
280 /* should never happen, callers always give us block-aligned
281 * plaintext and CSP padding is disabled. */
282 errorLog2("Symmetric encrypt overflow: bytesEncrypted %ld destLen %ld\n",
283 bytesEncrypted
, dest
.length
);
284 serr
= SSLDataOverflow
;
287 dest
.length
= bytesEncrypted
;
288 logSymmData("Symm encrypt ctext", &dest
, 48);
295 SSLErr
CDSASymmDecrypt(
298 CipherContext
*cipherCtx
,
302 CSSM_DATA ptextData
= {0, NULL
};
304 uint32 bytesDecrypted
;
305 SSLErr serr
= SSLInternalError
;
306 uint32 origLen
= dest
.length
;
313 CASSERT(ctx
!= NULL
);
314 CASSERT(cipherCtx
!= NULL
);
315 if((cipherCtx
->ccHand
== 0) || (cipherCtx
->cspHand
== 0)) {
316 errorLog0("CDSASymmDecrypt: null args\n");
317 return SSLInternalError
;
319 /* this requirement allows us to avoid a malloc and copy */
320 CASSERT(dest
.length
>= src
.length
);
324 unsigned blockSize
= cipherCtx
->symCipher
->blockSize
;
326 if(!IS_ALIGNED(src
.length
, blockSize
)) {
327 errorLog2("CDSASymmDecrypt: unaligned ctext (len %ld bs %d)\n",
328 src
.length
, blockSize
);
329 return SSLInternalError
;
331 if(!IS_ALIGNED(dest
.length
, blockSize
)) {
332 errorLog2("CDSASymmDecrypt: unaligned ptext (len %ld bs %d)\n",
333 dest
.length
, blockSize
);
334 return SSLInternalError
;
340 SSLBUF_TO_CSSM(&src
, &ctextData
);
341 SSLBUF_TO_CSSM(&dest
, &ptextData
);
342 crtn
= CSSM_DecryptDataUpdate(cipherCtx
->ccHand
,
349 stPrintCdsaError("CSSM_DecryptDataUpdate", crtn
);
350 serr
= SSLCryptoError
;
354 if(bytesDecrypted
> origLen
) {
355 /* FIXME - can this happen? Should we remalloc? */
356 errorLog2("Symmetric decrypt overflow: bytesDecrypted %ld destLen %ld\n",
357 bytesDecrypted
, dest
.length
);
358 serr
= SSLDataOverflow
;
361 dest
.length
= bytesDecrypted
;
363 logSymmData("Symm decrypt ptext(1)", &dest
, 48);
368 SSLErr
CDSASymmFinish(
369 CipherContext
*cipherCtx
,
372 /* dispose of cipherCtx->{symKey,cspHand,ccHand} */
373 disposeCipherCtx(cipherCtx
);