]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/lib/castContext.cpp
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / lib / castContext.cpp
1 /*
2 * Copyright (c) 2000-2001,2011-2012,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 * castContext.cpp - glue between BlockCrytpor and CommonCrypto CAST128 (CAST5)
21 * implementation
22 *
23 */
24
25 #include "castContext.h"
26
27 CastContext::CastContext(AppleCSPSession &session) :
28 BlockCryptor(session),
29 mCastKey(NULL),
30 mInitFlag(false),
31 mRawKeySize(0)
32 {
33 }
34
35
36
37 CastContext::~CastContext()
38 {
39 deleteKey();
40 }
41
42 void CastContext::deleteKey()
43 {
44 if (mCastKey != NULL) {
45 CCCryptorRelease(mCastKey);
46 }
47 mCastKey = NULL;
48 mInitFlag = false;
49 }
50
51 /*
52 * Standard CSPContext init, called from CSPFullPluginSession::init().
53 * Reusable, e.g., query followed by en/decrypt.
54 */
55 void CastContext::init(
56 const Context &context,
57 bool encrypting)
58 {
59 if(mInitFlag && !opStarted()) {
60 return;
61 }
62
63 CSSM_SIZE keyLen;
64 uint8 *keyData = NULL;
65 bool sameKeySize = false;
66
67 /* obtain key from context */
68 symmetricKeyBits(context, session(), CSSM_ALGID_CAST,
69 encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
70 keyData, keyLen);
71 if((keyLen < kCCKeySizeMinCAST) || (keyLen > kCCKeySizeMaxCAST)) {
72 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
73 }
74
75 /*
76 * Delete existing key if key size changed
77 */
78 if(mRawKeySize == keyLen) {
79 sameKeySize = true;
80 }
81 else {
82 deleteKey();
83 }
84
85 /* init key only if key size or key bits have changed */
86 if(!sameKeySize || memcmp(mRawKey, keyData, mRawKeySize)) {
87 (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithmCAST, ccDefaultPadding, NULL, keyData, keyLen, NULL, 0, 0, 0, &mCastKey);
88
89 /* save this raw key data */
90 memmove(mRawKey, keyData, keyLen);
91 mRawKeySize = (uint32)keyLen;
92 }
93
94 /* Finally, have BlockCryptor do its setup */
95 setup(kCCBlockSizeCAST, context);
96 mInitFlag = true;
97 }
98
99 /*
100 * Functions called by BlockCryptor
101 */
102 void CastContext::encryptBlock(
103 const void *plainText, // length implied (one block)
104 size_t plainTextLen,
105 void *cipherText,
106 size_t &cipherTextLen, // in/out, throws on overflow
107 bool final) // ignored
108 {
109 if(plainTextLen != kCCBlockSizeCAST) {
110 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
111 }
112 if(cipherTextLen < kCCBlockSizeCAST) {
113 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
114 }
115 (void) CCCryptorEncryptDataBlock(mCastKey, NULL, plainText, kCCBlockSizeCAST, cipherText);
116
117 cipherTextLen = kCCBlockSizeCAST;
118 }
119
120 void CastContext::decryptBlock(
121 const void *cipherText, // length implied (one block)
122 size_t cipherTextLen,
123 void *plainText,
124 size_t &plainTextLen, // in/out, throws on overflow
125 bool final) // ignored
126 {
127 if(plainTextLen < kCCBlockSizeCAST) {
128 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
129 }
130 (void) CCCryptorDecryptDataBlock(mCastKey, NULL, cipherText, kCCBlockSizeCAST, plainText);
131
132 plainTextLen = kCCBlockSizeCAST;
133 }