2  * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. 
   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 
  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. 
  20  * desContext.cpp - glue between BlockCrytpor and DES implementation 
  23 #include "desContext.h" 
  24 #include <security_utilities/debugging.h> 
  25 #include <security_utilities/globalizer.h> 
  26 #include <security_utilities/threading.h> 
  28 #define DESDebug(args...)       secinfo("desContext", ## args) 
  31  * DES encrypt/decrypt. 
  33 DESContext::DESContext(AppleCSPSession 
&session
) : BlockCryptor(session
), DesInst(NULL
) 
  37 DESContext::~DESContext() 
  39     if (DesInst 
!= NULL
) { 
  40         CCCryptorRelease(DesInst
); 
  47  * Standard CSPContext init, called from CSPFullPluginSession::init(). 
  48  * Reusable, e.g., query followed by en/decrypt. 
  50 void DESContext::init(  
  51         const Context 
&context
,  
  55         uint8           
*keyData        
= NULL
; 
  57         /* obtain key from context */ 
  58         symmetricKeyBits(context
, session(), CSSM_ALGID_DES
,  
  59                 encrypting 
? CSSM_KEYUSE_ENCRYPT 
: CSSM_KEYUSE_DECRYPT
,  
  61         if(keyLen 
!= (DES_KEY_SIZE_BITS_EXTERNAL 
/ 8)) { 
  62                 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY
); 
  67         CCCryptorRelease(DesInst
); 
  70     (void) CCCryptorCreateWithMode(0, kCCModeECB
, kCCAlgorithmDES
, ccDefaultPadding
, NULL
, keyData
, kCCKeySizeDES
, NULL
, 0, 0, 0, &DesInst
); 
  72         /* Finally, have BlockCryptor do its setup */ 
  73         setup(DES_BLOCK_SIZE_BYTES
, context
); 
  77  * Functions called by BlockCryptor 
  78  * DES does encrypt/decrypt in place 
  80 void DESContext::encryptBlock( 
  81         const void              *plainText
,                     // length implied (one block) 
  84         size_t                  &cipherTextLen
,         // in/out, throws on overflow 
  85         bool                    final
)                          // ignored 
  87         if(plainTextLen 
!= DES_BLOCK_SIZE_BYTES
) { 
  88                 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR
); 
  90         if(cipherTextLen 
< DES_BLOCK_SIZE_BYTES
) { 
  91                 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
); 
  93     (void) CCCryptorEncryptDataBlock(DesInst
, NULL
, plainText
, DES_BLOCK_SIZE_BYTES
, cipherText
); 
  94         cipherTextLen 
= DES_BLOCK_SIZE_BYTES
; 
  97 void DESContext::decryptBlock( 
  98         const void              *cipherText
,            // length implied (one block) 
 101         size_t                  &plainTextLen
,          // in/out, throws on overflow 
 102         bool                    final
)                          // ignored 
 104         if(plainTextLen 
< DES_BLOCK_SIZE_BYTES
) { 
 105                 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
); 
 107         if(plainText 
!= cipherText
) { 
 108                 /* little optimization for callers who want to decrypt in place */ 
 109                 memmove(plainText
, cipherText
, DES_BLOCK_SIZE_BYTES
); 
 111     (void) CCCryptorDecryptDataBlock(DesInst
, NULL
, cipherText
, DES_BLOCK_SIZE_BYTES
, plainText
); 
 112         plainTextLen 
= DES_BLOCK_SIZE_BYTES
; 
 116  *** Triple-DES - EDE, 24-bit key only 
 119 DES3Context::DES3Context(AppleCSPSession 
&session
) : BlockCryptor(session
), DesInst(NULL
) 
 125 DES3Context::~DES3Context() 
 127     if (DesInst 
!= NULL
) { 
 128         CCCryptorRelease(DesInst
); 
 135  * Standard CSPContext init, called from CSPFullPluginSession::init(). 
 136  * Reusable, e.g., query followed by en/decrypt. 
 138 void DES3Context::init(  
 139         const Context 
&context
,  
 143         uint8           
*keyData        
= NULL
; 
 145         /* obtain key from context */ 
 146         symmetricKeyBits(context
, session(), CSSM_ALGID_3DES_3KEY_EDE
,  
 147                 encrypting 
? CSSM_KEYUSE_ENCRYPT 
: CSSM_KEYUSE_DECRYPT
, 
 149         if(keyLen 
!= DES3_KEY_SIZE_BYTES
) { 
 150                 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY
); 
 153     if (DesInst 
!= NULL
) { 
 154         CCCryptorRelease(DesInst
); 
 157     (void) CCCryptorCreateWithMode(0, kCCModeECB
, kCCAlgorithm3DES
, ccDefaultPadding
, NULL
, keyData
, kCCKeySize3DES
, NULL
, 0, 0, 0, &DesInst
); 
 159         /* Finally, have BlockCryptor do its setup */ 
 160         setup(DES3_BLOCK_SIZE_BYTES
, context
); 
 164  * Functions called by BlockCryptor 
 165  * DES does encrypt/decrypt in place 
 167 void DES3Context::encryptBlock( 
 168         const void              *plainText
,                     // length implied (one block) 
 171         size_t                  &cipherTextLen
,         // in/out, throws on overflow 
 172         bool                    final
)                          // ignored 
 174         if(plainTextLen 
!= DES3_BLOCK_SIZE_BYTES
) { 
 175                 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR
); 
 177         if(cipherTextLen 
< DES3_BLOCK_SIZE_BYTES
) { 
 178                 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
); 
 180     (void) CCCryptorEncryptDataBlock(DesInst
, NULL
, plainText
, DES3_BLOCK_SIZE_BYTES
, cipherText
); 
 181         cipherTextLen 
= DES3_BLOCK_SIZE_BYTES
; 
 184 void DES3Context::decryptBlock( 
 185         const void              *cipherText
,            // length implied (one block) 
 186         size_t                  cipherTextLen
, 
 188         size_t                  &plainTextLen
,          // in/out, throws on overflow 
 189         bool                    final
)                          // ignored 
 191         if(plainTextLen 
< DES3_BLOCK_SIZE_BYTES
) { 
 192                 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
); 
 194     (void) CCCryptorDecryptDataBlock(DesInst
, NULL
, cipherText
, DES3_BLOCK_SIZE_BYTES
, plainText
); 
 195         plainTextLen 
= DES3_BLOCK_SIZE_BYTES
;