]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/lib/desContext.cpp
Security-57337.40.85.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / lib / desContext.cpp
1 /*
2 * Copyright (c) 2000-2001,2011,2014 Apple 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 * desContext.cpp - glue between BlockCrytpor and DES implementation
21 */
22
23 #include "desContext.h"
24 #include <security_utilities/debugging.h>
25 #include <security_utilities/globalizer.h>
26 #include <security_utilities/threading.h>
27
28 #define DESDebug(args...) secdebug("desContext", ## args)
29
30 /*
31 * DES encrypt/decrypt.
32 */
33 DESContext::DESContext(AppleCSPSession &session) : BlockCryptor(session), DesInst(NULL)
34 {
35 }
36
37 DESContext::~DESContext()
38 {
39 if (DesInst != NULL) {
40 CCCryptorRelease(DesInst);
41 }
42
43 DesInst = NULL;
44 }
45
46 /*
47 * Standard CSPContext init, called from CSPFullPluginSession::init().
48 * Reusable, e.g., query followed by en/decrypt.
49 */
50 void DESContext::init(
51 const Context &context,
52 bool encrypting)
53 {
54 CSSM_SIZE keyLen;
55 uint8 *keyData = NULL;
56
57 /* obtain key from context */
58 symmetricKeyBits(context, session(), CSSM_ALGID_DES,
59 encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
60 keyData, keyLen);
61 if(keyLen != (DES_KEY_SIZE_BITS_EXTERNAL / 8)) {
62 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
63 }
64
65 if (DesInst != NULL)
66 {
67 CCCryptorRelease(DesInst);
68 }
69
70 (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithmDES, ccDefaultPadding, NULL, keyData, kCCKeySizeDES, NULL, 0, 0, 0, &DesInst);
71
72 /* Finally, have BlockCryptor do its setup */
73 setup(DES_BLOCK_SIZE_BYTES, context);
74 }
75
76 /*
77 * Functions called by BlockCryptor
78 * DES does encrypt/decrypt in place
79 */
80 void DESContext::encryptBlock(
81 const void *plainText, // length implied (one block)
82 size_t plainTextLen,
83 void *cipherText,
84 size_t &cipherTextLen, // in/out, throws on overflow
85 bool final) // ignored
86 {
87 if(plainTextLen != DES_BLOCK_SIZE_BYTES) {
88 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
89 }
90 if(cipherTextLen < DES_BLOCK_SIZE_BYTES) {
91 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
92 }
93 (void) CCCryptorEncryptDataBlock(DesInst, NULL, plainText, DES_BLOCK_SIZE_BYTES, cipherText);
94 cipherTextLen = DES_BLOCK_SIZE_BYTES;
95 }
96
97 void DESContext::decryptBlock(
98 const void *cipherText, // length implied (one block)
99 size_t cipherTextLen,
100 void *plainText,
101 size_t &plainTextLen, // in/out, throws on overflow
102 bool final) // ignored
103 {
104 if(plainTextLen < DES_BLOCK_SIZE_BYTES) {
105 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
106 }
107 if(plainText != cipherText) {
108 /* little optimization for callers who want to decrypt in place */
109 memmove(plainText, cipherText, DES_BLOCK_SIZE_BYTES);
110 }
111 (void) CCCryptorDecryptDataBlock(DesInst, NULL, cipherText, DES_BLOCK_SIZE_BYTES, plainText);
112 plainTextLen = DES_BLOCK_SIZE_BYTES;
113 }
114
115 /***
116 *** Triple-DES - EDE, 24-bit key only
117 ***/
118
119 DES3Context::DES3Context(AppleCSPSession &session) : BlockCryptor(session), DesInst(NULL)
120 {
121 }
122
123
124
125 DES3Context::~DES3Context()
126 {
127 if (DesInst != NULL) {
128 CCCryptorRelease(DesInst);
129 }
130
131 DesInst = NULL;
132 }
133
134 /*
135 * Standard CSPContext init, called from CSPFullPluginSession::init().
136 * Reusable, e.g., query followed by en/decrypt.
137 */
138 void DES3Context::init(
139 const Context &context,
140 bool encrypting)
141 {
142 CSSM_SIZE keyLen;
143 uint8 *keyData = NULL;
144
145 /* obtain key from context */
146 symmetricKeyBits(context, session(), CSSM_ALGID_3DES_3KEY_EDE,
147 encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
148 keyData, keyLen);
149 if(keyLen != DES3_KEY_SIZE_BYTES) {
150 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
151 }
152
153 if (DesInst != NULL) {
154 CCCryptorRelease(DesInst);
155 }
156
157 (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithm3DES, ccDefaultPadding, NULL, keyData, kCCKeySize3DES, NULL, 0, 0, 0, &DesInst);
158
159 /* Finally, have BlockCryptor do its setup */
160 setup(DES3_BLOCK_SIZE_BYTES, context);
161 }
162
163 /*
164 * Functions called by BlockCryptor
165 * DES does encrypt/decrypt in place
166 */
167 void DES3Context::encryptBlock(
168 const void *plainText, // length implied (one block)
169 size_t plainTextLen,
170 void *cipherText,
171 size_t &cipherTextLen, // in/out, throws on overflow
172 bool final) // ignored
173 {
174 if(plainTextLen != DES3_BLOCK_SIZE_BYTES) {
175 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
176 }
177 if(cipherTextLen < DES3_BLOCK_SIZE_BYTES) {
178 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
179 }
180 (void) CCCryptorEncryptDataBlock(DesInst, NULL, plainText, DES3_BLOCK_SIZE_BYTES, cipherText);
181 cipherTextLen = DES3_BLOCK_SIZE_BYTES;
182 }
183
184 void DES3Context::decryptBlock(
185 const void *cipherText, // length implied (one block)
186 size_t cipherTextLen,
187 void *plainText,
188 size_t &plainTextLen, // in/out, throws on overflow
189 bool final) // ignored
190 {
191 if(plainTextLen < DES3_BLOCK_SIZE_BYTES) {
192 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
193 }
194 (void) CCCryptorDecryptDataBlock(DesInst, NULL, cipherText, DES3_BLOCK_SIZE_BYTES, plainText);
195 plainTextLen = DES3_BLOCK_SIZE_BYTES;
196 }