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.
20 * desContext.cpp - glue between BlockCrytpor and DES implementation
21 * Written by Doug Mitchell 3/28/2001
24 #include "desContext.h"
25 #include <Security/debugging.h>
26 #include <Security/globalizer.h>
27 #include <Security/threading.h>
29 ModuleNexus
<Mutex
> desInitMutex
;
31 #define DESDebug(args...) debug("desContext", ## args)
34 * DES encrypt/decrypt.
36 DESContext::~DESContext()
39 memset(&DesInst
, 0, sizeof(struct _desInst
));
43 * Standard CSPContext init, called from CSPFullPluginSession::init().
44 * Reusable, e.g., query followed by en/decrypt.
46 void DESContext::init(
47 const Context
&context
,
51 UInt8
*keyData
= NULL
;
53 /* obtain key from context */
54 symmetricKeyBits(context
, CSSM_ALGID_DES
,
55 encrypting
? CSSM_KEYUSE_ENCRYPT
: CSSM_KEYUSE_DECRYPT
,
57 if(keyLen
!= (DES_KEY_SIZE_BITS_EXTERNAL
/ 8)) {
58 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY
);
61 /* init the low-level state */
63 StLock
<Mutex
> _(desInitMutex());
64 if(int irtn
= desinit(&DesInst
, DES_MODE_STD
)) {
65 DESDebug("desinit returned %d\n", irtn
);
66 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
69 dessetkey(&DesInst
, (char *)keyData
);
71 /* Finally, have BlockCryptor do its setup */
72 setup(DES_BLOCK_SIZE_BYTES
, context
);
76 * Functions called by BlockCryptor
77 * DES does encrypt/decrypt in place
79 void DESContext::encryptBlock(
80 const void *plainText
, // length implied (one block)
83 size_t &cipherTextLen
, // in/out, throws on overflow
84 bool final
) // ignored
86 if(plainTextLen
!= DES_BLOCK_SIZE_BYTES
) {
87 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR
);
89 if(cipherTextLen
< DES_BLOCK_SIZE_BYTES
) {
90 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
92 if(plainText
!= cipherText
) {
93 /* little optimization for callers who want to encrypt in place */
94 memmove(cipherText
, plainText
, DES_BLOCK_SIZE_BYTES
);
96 endes(&DesInst
, (char *)cipherText
);
97 cipherTextLen
= DES_BLOCK_SIZE_BYTES
;
100 void DESContext::decryptBlock(
101 const void *cipherText
, // length implied (one block)
103 size_t &plainTextLen
, // in/out, throws on overflow
104 bool final
) // ignored
106 if(plainTextLen
< DES_BLOCK_SIZE_BYTES
) {
107 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
109 if(plainText
!= cipherText
) {
110 /* little optimization for callers who want to decrypt in place */
111 memmove(plainText
, cipherText
, DES_BLOCK_SIZE_BYTES
);
113 dedes(&DesInst
, (char *)plainText
);
114 plainTextLen
= DES_BLOCK_SIZE_BYTES
;
118 *** Triple-DES - EDE, 24-bit key only
121 DES3Context::~DES3Context()
123 for(int i
=0; i
<3; i
++) {
124 desdone(&DesInst
[i
]);
125 memset(&DesInst
[i
], 0, sizeof(struct _desInst
));
130 * Standard CSPContext init, called from CSPFullPluginSession::init().
131 * Reusable, e.g., query followed by en/decrypt.
133 void DES3Context::init(
134 const Context
&context
,
138 UInt8
*keyData
= NULL
;
140 /* obtain key from context */
141 symmetricKeyBits(context
, CSSM_ALGID_3DES_3KEY_EDE
,
142 encrypting
? CSSM_KEYUSE_ENCRYPT
: CSSM_KEYUSE_DECRYPT
,
144 if(keyLen
!= DES3_KEY_SIZE_BYTES
) {
145 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY
);
148 /* init the low-level state */
152 StLock
<Mutex
> _(desInitMutex());
154 if((irtn
= desinit(&DesInst
[i
], DES_MODE_STD
))) {
155 DESDebug("desinit returned %d\n", irtn
);
156 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
158 dessetkey(&DesInst
[i
], (char *)keyData
+ (8 * i
));
162 /* Finally, have BlockCryptor do its setup */
163 setup(DES3_BLOCK_SIZE_BYTES
, context
);
167 * Functions called by BlockCryptor
168 * DES does encrypt/decrypt in place
170 void DES3Context::encryptBlock(
171 const void *plainText
, // length implied (one block)
174 size_t &cipherTextLen
, // in/out, throws on overflow
175 bool final
) // ignored
177 if(plainTextLen
!= DES3_BLOCK_SIZE_BYTES
) {
178 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR
);
180 if(cipherTextLen
< DES3_BLOCK_SIZE_BYTES
) {
181 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
183 if(plainText
!= cipherText
) {
184 /* little optimization for callers who want to encrypt in place */
185 memmove(cipherText
, plainText
, DES3_BLOCK_SIZE_BYTES
);
188 /* encrypt --> decrypt --> encrypt */
189 endes(&DesInst
[0], (char *)cipherText
);
190 dedes(&DesInst
[1], (char *)cipherText
);
191 endes(&DesInst
[2], (char *)cipherText
);
192 cipherTextLen
= DES3_BLOCK_SIZE_BYTES
;
195 void DES3Context::decryptBlock(
196 const void *cipherText
, // length implied (one block)
198 size_t &plainTextLen
, // in/out, throws on overflow
199 bool final
) // ignored
201 if(plainTextLen
< DES3_BLOCK_SIZE_BYTES
) {
202 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
204 if(plainText
!= cipherText
) {
205 /* little optimization for callers who want to decrypt in place */
206 memmove(plainText
, cipherText
, DES3_BLOCK_SIZE_BYTES
);
209 /* decrypt --> encrypt -->decrypt */
210 dedes(&DesInst
[2], (char *)plainText
);
211 endes(&DesInst
[1], (char *)plainText
);
212 dedes(&DesInst
[0], (char *)plainText
);
213 plainTextLen
= DES3_BLOCK_SIZE_BYTES
;