/ OSX / libsecurity_apple_csp / lib / desContext.cpp
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...)	secinfo("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          DesInst = NULL;
 69      }
 70      
 71      (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithmDES, ccDefaultPadding, NULL, keyData, kCCKeySizeDES, NULL, 0, 0, 0, &DesInst);
 72  
 73  	/* Finally, have BlockCryptor do its setup */
 74  	setup(DES_BLOCK_SIZE_BYTES, context);
 75  }	
 76  
 77  /*
 78   * Functions called by BlockCryptor
 79   * DES does encrypt/decrypt in place
 80   */
 81  void DESContext::encryptBlock(
 82  	const void		*plainText,			// length implied (one block)
 83  	size_t			plainTextLen,
 84  	void			*cipherText,	
 85  	size_t			&cipherTextLen,		// in/out, throws on overflow
 86  	bool			final)				// ignored
 87  {
 88  	if(plainTextLen != DES_BLOCK_SIZE_BYTES) {
 89  		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
 90  	}
 91  	if(cipherTextLen < DES_BLOCK_SIZE_BYTES) {
 92  		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
 93  	}
 94      (void) CCCryptorEncryptDataBlock(DesInst, NULL, plainText, DES_BLOCK_SIZE_BYTES, cipherText);
 95  	cipherTextLen = DES_BLOCK_SIZE_BYTES;
 96  }
 97  
 98  void DESContext::decryptBlock(
 99  	const void		*cipherText,		// length implied (one block)
100  	size_t			cipherTextLen,
101  	void			*plainText,	
102  	size_t			&plainTextLen,		// in/out, throws on overflow
103  	bool			final)				// ignored
104  {
105  	if(plainTextLen < DES_BLOCK_SIZE_BYTES) {
106  		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
107  	}
108  	if(plainText != cipherText) {
109  		/* little optimization for callers who want to decrypt in place */
110  		memmove(plainText, cipherText, DES_BLOCK_SIZE_BYTES);
111  	}
112      (void) CCCryptorDecryptDataBlock(DesInst, NULL, cipherText, DES_BLOCK_SIZE_BYTES, plainText);
113  	plainTextLen = DES_BLOCK_SIZE_BYTES;
114  }
115  
116  /***
117   *** Triple-DES - EDE, 24-bit key only
118   ***/
119   
120  DES3Context::DES3Context(AppleCSPSession &session) : BlockCryptor(session), DesInst(NULL)
121  {
122  }
123  
124  
125  
126  DES3Context::~DES3Context()
127  {
128      if (DesInst != NULL) {
129          CCCryptorRelease(DesInst);
130      }
131      
132      DesInst = NULL;
133  }
134  
135  /* 
136   * Standard CSPContext init, called from CSPFullPluginSession::init().
137   * Reusable, e.g., query followed by en/decrypt.
138   */
139  void DES3Context::init( 
140  	const Context &context, 
141  	bool encrypting)
142  {
143  	CSSM_SIZE	keyLen;
144  	uint8 		*keyData 	= NULL;
145  	
146  	/* obtain key from context */
147  	symmetricKeyBits(context, session(), CSSM_ALGID_3DES_3KEY_EDE, 
148  		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
149  		keyData, keyLen);
150  	if(keyLen != DES3_KEY_SIZE_BYTES) {
151  		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
152  	}
153  
154      if (DesInst != NULL) {
155          CCCryptorRelease(DesInst);
156          DesInst = NULL;
157      }
158      
159      (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithm3DES, ccDefaultPadding, NULL, keyData, kCCKeySize3DES, NULL, 0, 0, 0, &DesInst);
160  
161  	/* Finally, have BlockCryptor do its setup */
162  	setup(DES3_BLOCK_SIZE_BYTES, context);
163  }	
164  
165  /*
166   * Functions called by BlockCryptor
167   * DES does encrypt/decrypt in place
168   */
169  void DES3Context::encryptBlock(
170  	const void		*plainText,			// length implied (one block)
171  	size_t			plainTextLen,
172  	void			*cipherText,	
173  	size_t			&cipherTextLen,		// in/out, throws on overflow
174  	bool			final)				// ignored
175  {
176  	if(plainTextLen != DES3_BLOCK_SIZE_BYTES) {
177  		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
178  	}
179  	if(cipherTextLen < DES3_BLOCK_SIZE_BYTES) {
180  		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
181  	}
182      (void) CCCryptorEncryptDataBlock(DesInst, NULL, plainText, DES3_BLOCK_SIZE_BYTES, cipherText);
183  	cipherTextLen = DES3_BLOCK_SIZE_BYTES;
184  }
185  
186  void DES3Context::decryptBlock(
187  	const void		*cipherText,		// length implied (one block)
188  	size_t			cipherTextLen,
189  	void			*plainText,	
190  	size_t			&plainTextLen,		// in/out, throws on overflow
191  	bool			final)				// ignored
192  {
193  	if(plainTextLen < DES3_BLOCK_SIZE_BYTES) {
194  		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
195  	}
196      (void) CCCryptorDecryptDataBlock(DesInst, NULL, cipherText, DES3_BLOCK_SIZE_BYTES, plainText);
197  	plainTextLen = DES3_BLOCK_SIZE_BYTES;
198  }