/ OSX / libsecurity_apple_csp / lib / rc2Context.cpp
rc2Context.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   * rc2Context.cpp - glue between BlockCrytpor and ssleay RC2 implementation
 21   */
 22   
 23  #include <openssl/rc2_legacy.h>
 24  #include <misc/rc2_locl.h>
 25  #include "rc2Context.h"
 26  
 27  RC2Context::~RC2Context()
 28  {
 29  	memset(&rc2Key, 0, sizeof(RC2_KEY));
 30  }
 31  	
 32  /* 
 33   * Standard CSPContext init, called from CSPFullPluginSession::init().
 34   * Reusable, e.g., query followed by en/decrypt.
 35   */
 36  void RC2Context::init( 
 37  	const Context &context, 
 38  	bool encrypting)
 39  {
 40  	CSSM_SIZE	keyLen;
 41  	uint8 		*keyData 	= NULL;
 42  	uint32		effectiveBits;
 43  	
 44  	/* obtain key from context */
 45  	symmetricKeyBits(context, session(), CSSM_ALGID_RC2, 
 46  		encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
 47  		keyData, keyLen);
 48  	if((keyLen < RC2_MIN_KEY_SIZE_BYTES) || (keyLen > RC2_MAX_KEY_SIZE_BYTES)) {
 49  		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
 50  	}
 51  	
 52  	/* 
 53  	 * Optional effective key size in bits - either from Context,
 54  	 * or the key
 55  	 */
 56  	effectiveBits = context.getInt(CSSM_ATTRIBUTE_EFFECTIVE_BITS);
 57  	if(effectiveBits == 0) {
 58  		CssmKey &key = context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, 
 59  			CSSMERR_CSP_MISSING_ATTR_KEY);
 60  		effectiveBits = key.KeyHeader.LogicalKeySizeInBits;
 61  	}
 62  
 63  	/* init the low-level state */
 64  	RC2_set_key(&rc2Key, (int)keyLen, keyData, effectiveBits);
 65  
 66  	/* Finally, have BlockCryptor do its setup */
 67  	setup(RC2_BLOCK_SIZE_BYTES, context);
 68  }	
 69  
 70  /*
 71   * Functions called by BlockCryptor
 72   */
 73  void RC2Context::encryptBlock(
 74  	const void		*plainText,			// length implied (one block)
 75  	size_t			plainTextLen,
 76  	void			*cipherText,	
 77  	size_t			&cipherTextLen,		// in/out, throws on overflow
 78  	bool			final)				// ignored
 79  {
 80  	if(plainTextLen != RC2_BLOCK_SIZE_BYTES) {
 81  		CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
 82  	}
 83  	if(cipherTextLen < RC2_BLOCK_SIZE_BYTES) {
 84  		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
 85  	}
 86  	
 87  	/*
 88  	 * Low-level code operates on array of unsigned 32-bit integers 
 89  	 */
 90  	RC2_INT	d[2];
 91  	RC2_INT l;
 92  	const unsigned char *pt = (const unsigned char *)plainText;
 93  	c2l(pt, l); d[0]=l;
 94  	c2l(pt, l); d[1]=l;
 95  	RC2_encrypt(d, &rc2Key);
 96  	unsigned char *ct = (unsigned char *)cipherText;
 97  	l=d[0]; l2c(l, ct);
 98  	l=d[1]; l2c(l, ct);
 99  	cipherTextLen = RC2_BLOCK_SIZE_BYTES;
100  }
101  
102  void RC2Context::decryptBlock(
103  	const void		*cipherText,		// length implied (one block)
104  	size_t			cipherTextLen,
105  	void			*plainText,	
106  	size_t			&plainTextLen,		// in/out, throws on overflow
107  	bool			final)				// ignored
108  {
109  	if(plainTextLen < RC2_BLOCK_SIZE_BYTES) {
110  		CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
111  	}
112  	/*
113  	 * Low-level code operates on array of unsigned 32-bit integers 
114  	 */
115  	RC2_INT	d[2];
116  	RC2_INT l;
117  	const unsigned char *ct = (const unsigned char *)cipherText;
118  	c2l(ct, l); d[0]=l;
119  	c2l(ct, l); d[1]=l;
120  	RC2_decrypt(d, &rc2Key);
121  	unsigned char *pt = (unsigned char *)plainText;
122  	l=d[0]; l2c(l, pt);
123  	l=d[1]; l2c(l, pt);
124  	plainTextLen = RC2_BLOCK_SIZE_BYTES;
125  }
126