/ OSX / libsecurity_cdsa_client / lib / cryptoclient.cpp
cryptoclient.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  // cryptoclient - client interface to CSSM CSP encryption/decryption operations
 21  //
 22  #include <security_cdsa_client/cryptoclient.h>
 23  
 24  using namespace CssmClient;
 25  
 26  
 27  Crypt::Crypt(const CSP &csp, CSSM_ALGORITHMS alg)
 28  	: Context(csp, alg), mMode(CSSM_ALGMODE_NONE), mInitVector(NULL),
 29  	  mPadding(CSSM_PADDING_NONE)
 30  {
 31  }
 32  
 33  void Crypt::key(const Key &key)
 34  {
 35  	mKey = key;
 36  	set(CSSM_ATTRIBUTE_KEY, static_cast<const CssmKey &>(key));
 37  }
 38  
 39  
 40  void
 41  Crypt::activate()
 42  {
 43      StLock<Mutex> _(mActivateMutex);
 44  	if (!mActive)
 45  	{
 46          // Key is required unless we have a NULL algorithm (cleartext wrap/unwrap),
 47          // in which case we'll make a symmetric context (it shouldn't matter then).
 48  		if (!mKey && mAlgorithm != CSSM_ALGID_NONE)
 49  			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_KEY);
 50  		if (!mKey || mKey->keyClass() == CSSM_KEYCLASS_SESSION_KEY)
 51  		{	// symmetric key
 52  			check(CSSM_CSP_CreateSymmetricContext(attachment()->handle(), mAlgorithm,
 53  				mMode, neededCred(), mKey, mInitVector, mPadding, NULL,
 54  				&mHandle));
 55  		}
 56  		else
 57  		{
 58  			check(CSSM_CSP_CreateAsymmetricContext(attachment()->handle(), mAlgorithm,
 59  				neededCred(), mKey, mPadding, &mHandle));
 60  			//@@@ stick mode and initVector explicitly into the context?
 61  		}		
 62  		mActive = true;
 63  	}
 64  }
 65  
 66  
 67  //
 68  // Manage encryption contexts
 69  //
 70  CSSM_SIZE
 71  Encrypt::encrypt(const CssmData *in, uint32 inCount,
 72  						CssmData *out, uint32 outCount, CssmData &remData)
 73  {
 74  	unstaged();
 75  	CSSM_SIZE total;
 76  	check(CSSM_EncryptData(handle(), in, inCount, out, outCount, &total, &remData));
 77  	return total;
 78  }
 79  
 80  void
 81  Encrypt::init()
 82  {
 83  	check(CSSM_EncryptDataInit(handle()));
 84  	mStaged = true;
 85  }
 86  
 87  CSSM_SIZE
 88  Encrypt::encrypt(const CssmData *in, uint32 inCount,
 89  	CssmData *out, uint32 outCount)
 90  {
 91  	staged();
 92  	CSSM_SIZE total;
 93  	check(CSSM_EncryptDataUpdate(handle(), in, inCount, out, outCount, &total));
 94  	return total;
 95  }
 96  
 97  void
 98  Encrypt::final(CssmData &remData)
 99  {
100  	staged();
101  	check(CSSM_EncryptDataFinal(handle(), &remData));
102  	mStaged = false;
103  }
104  
105  
106  //
107  // Manage Decryption contexts
108  //
109  
110  CSSM_SIZE
111  Decrypt::decrypt(const CssmData *in, uint32 inCount,
112  	CssmData *out, uint32 outCount, CssmData &remData)
113  {
114  	unstaged();
115  	CSSM_SIZE total;
116  	check(CSSM_DecryptData(handle(), in, inCount, out, outCount, &total, &remData));
117  	return total;
118  }
119  
120  void
121  Decrypt::init()
122  {
123  	check(CSSM_DecryptDataInit(handle()));
124  	mStaged = true;
125  }
126  
127  CSSM_SIZE
128  Decrypt::decrypt(const CssmData *in, uint32 inCount,
129  	CssmData *out, uint32 outCount)
130  {
131  	staged();
132  	CSSM_SIZE total;
133  	check(CSSM_DecryptDataUpdate(handle(), in, inCount, out, outCount, &total));
134  	return total;
135  }
136  
137  void
138  Decrypt::final(CssmData &remData)
139  {
140  	staged();
141  	check(CSSM_DecryptDataFinal(handle(), &remData));
142  	mStaged = false;
143  }