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
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
00068 EVP_CIPHER_CTX context;
00069 EVP_CIPHER_CTX_init(&context);
00070
00071
00072
00073
00074 EVP_EncryptInit_ex(&context, EVP_bf_cbc(), NULL, NULL, NULL);
00075 EVP_CIPHER_CTX_set_key_length(&context, (int)mSecretSize);
00076
00077
00078
00079
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
00104
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
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
00128 U32 LLBlowfishCipher::requiredEncryptionSpace(U32 len) const
00129 {
00130
00131
00132
00133
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
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
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
00157 U32 LLBlowfishCipher::requiredEncryptionSpace(U32 len) const
00158 {
00159 llerrs << "LLBlowfishCipher only supported on Linux" << llendl;
00160 return 0;
00161 }
00162
00163 #endif
00164