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 * bfContext.cpp - glue between BlockCrytpor and ssleay Blowfish 21 * implementation 22 */ 23 24#include "bfContext.h" 25 26BlowfishContext::~BlowfishContext() 27{ 28 deleteKey(); 29} 30 31void BlowfishContext::deleteKey() 32{ 33 memset(&mBfKey, 0, sizeof(mBfKey)); 34 mInitFlag = false; 35} 36 37/* 38 * Standard CSPContext init, called from CSPFullPluginSession::init(). 39 * Reusable, e.g., query followed by en/decrypt. 40 */ 41void BlowfishContext::init( 42 const Context &context, 43 bool encrypting) 44{ 45 if(mInitFlag && !opStarted()) { 46 return; 47 } 48 49 CSSM_SIZE keyLen; 50 uint8 *keyData = NULL; 51 bool sameKeySize = false; 52 53 /* obtain key from context */ 54 symmetricKeyBits(context, session(), CSSM_ALGID_BLOWFISH, 55 encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT, 56 keyData, keyLen); 57 if((keyLen < BF_MIN_KEY_SIZE_BYTES) || (keyLen > BF_MAX_KEY_SIZE_BYTES)) { 58 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY); 59 } 60 61 /* 62 * Delete existing key if key size changed 63 */ 64 if(mRawKeySize == keyLen) { 65 sameKeySize = true; 66 } 67 else { 68 deleteKey(); 69 } 70 71 /* init key only if key size or key bits have changed */ 72 if(!sameKeySize || memcmp(mRawKey, keyData, mRawKeySize)) { 73 BF_set_key(&mBfKey, (int)keyLen, keyData); 74 75 /* save this raw key data */ 76 memmove(mRawKey, keyData, keyLen); 77 mRawKeySize = (unsigned int)keyLen; 78 } 79 80 /* Finally, have BlockCryptor do its setup */ 81 setup(BF_BLOCK, context); 82 mInitFlag = true; 83} 84 85/* 86 * Functions called by BlockCryptor 87 */ 88void BlowfishContext::encryptBlock( 89 const void *plainText, // length implied (one block) 90 size_t plainTextLen, 91 void *cipherText, 92 size_t &cipherTextLen, // in/out, throws on overflow 93 bool final) // ignored 94{ 95 if(plainTextLen != BF_BLOCK) { 96 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR); 97 } 98 if(cipherTextLen < BF_BLOCK) { 99 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); 100 } 101 BF_ecb_encrypt((const unsigned char *)plainText, (unsigned char *)cipherText, 102 &mBfKey, BF_ENCRYPT); 103 cipherTextLen = BF_BLOCK; 104} 105 106void BlowfishContext::decryptBlock( 107 const void *cipherText, // length implied (one block) 108 size_t cipherTextLen, 109 void *plainText, 110 size_t &plainTextLen, // in/out, throws on overflow 111 bool final) // ignored 112{ 113 if(plainTextLen < BF_BLOCK) { 114 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); 115 } 116 BF_ecb_encrypt((const unsigned char *)cipherText, (unsigned char *)plainText, 117 &mBfKey, BF_DECRYPT); 118 plainTextLen = BF_BLOCK; 119} 120