00001
00032 #include "linden_common.h"
00033 #include "llblowfishcipher.h"
00034 #include <openssl/evp.h>
00035
00036
00037 LLBlowfishCipher::LLBlowfishCipher(const U8* secret, size_t secret_size)
00038 : LLCipher()
00039 {
00040 llassert(secret);
00041
00042 mSecretSize = secret_size;
00043 mSecret = new U8[mSecretSize];
00044 memcpy(mSecret, secret, mSecretSize);
00045 }
00046
00047 LLBlowfishCipher::~LLBlowfishCipher()
00048 {
00049 delete [] mSecret;
00050 mSecret = NULL;
00051 }
00052
00053
00054 U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
00055 {
00056 if (!src || !src_len || !dst || !dst_len) return 0;
00057 if (src_len > dst_len) return 0;
00058
00059
00060 EVP_CIPHER_CTX context;
00061 EVP_CIPHER_CTX_init(&context);
00062
00063
00064
00065
00066 EVP_EncryptInit_ex(&context, EVP_bf_cbc(), NULL, NULL, NULL);
00067 EVP_CIPHER_CTX_set_key_length(&context, (int)mSecretSize);
00068
00069
00070
00071
00072 unsigned char initial_vector[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
00073 EVP_EncryptInit_ex(&context, NULL, NULL, mSecret, initial_vector);
00074
00075 int blocksize = EVP_CIPHER_CTX_block_size(&context);
00076 int keylen = EVP_CIPHER_CTX_key_length(&context);
00077 int iv_length = EVP_CIPHER_CTX_iv_length(&context);
00078 lldebugs << "LLBlowfishCipher blocksize " << blocksize
00079 << " keylen " << keylen
00080 << " iv_len " << iv_length
00081 << llendl;
00082
00083 int output_len = 0;
00084 int temp_len = 0;
00085 if (!EVP_EncryptUpdate(&context,
00086 dst,
00087 &output_len,
00088 src,
00089 src_len))
00090 {
00091 llwarns << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << llendl;
00092 goto ERROR;
00093 }
00094
00095
00096
00097 if (!EVP_EncryptFinal_ex(&context, (unsigned char*)(dst + output_len), &temp_len))
00098 {
00099 llwarns << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << llendl;
00100 goto ERROR;
00101 }
00102 output_len += temp_len;
00103
00104 EVP_CIPHER_CTX_cleanup(&context);
00105 return output_len;
00106
00107 ERROR:
00108 EVP_CIPHER_CTX_cleanup(&context);
00109 return 0;
00110 }
00111
00112
00113 U32 LLBlowfishCipher::decrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
00114 {
00115 llerrs << "LLBlowfishCipher decrypt unsupported" << llendl;
00116 return 0;
00117 }
00118
00119
00120 U32 LLBlowfishCipher::requiredEncryptionSpace(U32 len) const
00121 {
00122
00123
00124
00125
00126 const U32 BLOCK_SIZE = 8;
00127 len += BLOCK_SIZE;
00128 len -= (len % BLOCK_SIZE);
00129 return len;
00130 }