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