llblowfishcipher.cpp

Go to the documentation of this file.
00001 
00035 #include "linden_common.h"
00036 
00037 #include "llblowfishcipher.h"
00038 
00039 
00040 LLBlowfishCipher::LLBlowfishCipher(const U8* secret, size_t secret_size)
00041 :       LLCipher()
00042 {
00043         llassert(secret);
00044 
00045         mSecretSize = secret_size;
00046         mSecret = new U8[mSecretSize];
00047         memcpy(mSecret, secret, mSecretSize);
00048 }
00049 
00050 LLBlowfishCipher::~LLBlowfishCipher()
00051 {
00052         delete [] mSecret;
00053         mSecret = NULL;
00054 }
00055 
00056 
00057 #if LL_LINUX
00058 
00059 #include <openssl/evp.h>
00060 
00061 // virtual
00062 U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
00063 {
00064         if (!src || !src_len || !dst || !dst_len) return 0;
00065         if (src_len > dst_len) return 0;
00066 
00067         // OpenSSL uses "cipher contexts" to hold encryption parameters.
00068     EVP_CIPHER_CTX context;
00069     EVP_CIPHER_CTX_init(&context);
00070 
00071         // We want a blowfish cyclic block chain cipher, but need to set 
00072         // the key length before we pass in a key, so call EncryptInit 
00073         // first with NULLs.
00074         EVP_EncryptInit_ex(&context, EVP_bf_cbc(), NULL, NULL, NULL);
00075         EVP_CIPHER_CTX_set_key_length(&context, (int)mSecretSize);
00076         
00077         // Complete initialization.  Per EVP_EncryptInit man page, the
00078         // cipher pointer must be NULL.  Apparently initial_vector must
00079         // be 8 bytes for blowfish, as this is the block size.
00080     unsigned char initial_vector[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
00081         EVP_EncryptInit_ex(&context, NULL, NULL, mSecret, initial_vector);
00082 
00083     int blocksize = EVP_CIPHER_CTX_block_size(&context);
00084     int keylen = EVP_CIPHER_CTX_key_length(&context);
00085     int iv_length = EVP_CIPHER_CTX_iv_length(&context);
00086     lldebugs << "LLBlowfishCipher blocksize " << blocksize
00087                 << " keylen " << keylen
00088                 << " iv_len " << iv_length
00089                 << llendl;
00090 
00091         int output_len = 0;
00092         int temp_len = 0;
00093         if (!EVP_EncryptUpdate(&context,
00094                         dst,
00095                         &output_len,
00096                         src,
00097                         src_len))
00098         {
00099                 llwarns << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << llendl;
00100                 goto ERROR;
00101         }
00102 
00103         // There may be some final data left to encrypt if the input is
00104         // not an exact multiple of the block size.
00105         if (!EVP_EncryptFinal_ex(&context, (unsigned char*)(dst + output_len), &temp_len))
00106         {
00107                 llwarns << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << llendl;
00108                 goto ERROR;
00109         }
00110         output_len += temp_len;
00111 
00112         EVP_CIPHER_CTX_cleanup(&context);
00113         return output_len;
00114 
00115 ERROR:
00116         EVP_CIPHER_CTX_cleanup(&context);
00117         return 0;
00118 }
00119 
00120 // virtual
00121 U32 LLBlowfishCipher::decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
00122 {
00123         llerrs << "LLBlowfishCipher decrypt unsupported" << llendl;
00124         return 0;
00125 }
00126 
00127 // virtual
00128 U32 LLBlowfishCipher::requiredEncryptionSpace(U32 len) const
00129 {
00130         // *HACK: We know blowfish uses an 8 byte block size.
00131         // Oddly, sometimes EVP_Encrypt produces an extra block
00132         // if the input is an exact multiple of the block size.
00133         // So round up.
00134         const U32 BLOCK_SIZE = 8;
00135         len += BLOCK_SIZE;
00136         len -= (len % BLOCK_SIZE);
00137         return len;
00138 }
00139 
00140 #else   // !LL_LINUX
00141 
00142 // virtual
00143 U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
00144 {
00145         llerrs << "LLBlowfishCipher only supported on Linux" << llendl;
00146         return 0;
00147 }
00148 
00149 // virtual
00150 U32 LLBlowfishCipher::decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
00151 {
00152         llerrs << "LLBlowfishCipher only supported on Linux" << llendl;
00153         return 0;
00154 }
00155 
00156 // virtual
00157 U32 LLBlowfishCipher::requiredEncryptionSpace(U32 len) const
00158 {
00159         llerrs << "LLBlowfishCipher only supported on Linux" << llendl;
00160         return 0;
00161 }
00162 
00163 #endif
00164 

Generated on Thu Jul 1 06:08:19 2010 for Second Life Viewer by  doxygen 1.4.7