00001
00002
00003
00004
00005
00006
00007
#include "wvblowfish.h"
00008
#include <assert.h>
00009
#include <openssl/rand.h>
00010
#include <openssl/blowfish.h>
00011
00012
00013
00014 WvBlowfishEncoder::WvBlowfishEncoder(Mode _mode,
00015
const void *_key, size_t _keysize) :
00016 mode(_mode), key(NULL), bfkey(NULL)
00017 {
00018
setkey(_key, _keysize);
00019 }
00020
00021
00022 WvBlowfishEncoder::~WvBlowfishEncoder()
00023 {
00024
delete[]
key;
00025
delete bfkey;
00026 }
00027
00028
00029 bool WvBlowfishEncoder::_reset()
00030 {
00031
preparekey();
00032
return true;
00033 }
00034
00035
00036 void WvBlowfishEncoder::setkey(
const void *_key, size_t _keysize)
00037 {
00038
delete[]
key;
00039
keysize = _keysize;
00040
key =
new unsigned char[
keysize];
00041 memcpy(
key, _key,
keysize);
00042
preparekey();
00043 }
00044
00045
00046 void WvBlowfishEncoder::setiv(
const void *_iv)
00047 {
00048 memcpy(
ivec, _iv,
sizeof(
ivec));
00049
ivecoff = 0;
00050 }
00051
00052
00053 void WvBlowfishEncoder::preparekey()
00054 {
00055
delete bfkey;
00056
bfkey =
new BF_KEY;
00057 BF_set_key(
bfkey,
keysize,
key);
00058 memset(
ivec, 0,
sizeof(
ivec));
00059
ivecoff = 0;
00060 }
00061
00062
00063 bool WvBlowfishEncoder::_encode(
WvBuf &in,
WvBuf &out,
bool flush)
00064 {
00065 size_t len = in.
used();
00066
bool success =
true;
00067
switch (
mode) {
00068
case ECBEncrypt:
00069
case ECBDecrypt:
00070 {
00071 size_t remainder = len & 7;
00072 len -= remainder;
00073
if (remainder != 0 && flush)
00074 {
00075
if (
mode ==
ECBEncrypt)
00076 {
00077
00078 size_t padlen = 8 - remainder;
00079
unsigned char *pad = in.
alloc(padlen);
00080 RAND_pseudo_bytes(pad, padlen);
00081 len += 8;
00082 }
00083
else
00084 success =
false;
00085 }
00086 }
00087
00088
default:
00089
break;
00090 }
00091
if (len == 0)
return success;
00092
00093
const unsigned char *data = in.
get(len);
00094
unsigned char *crypt = out.
alloc(len);
00095
00096
switch (
mode)
00097 {
00098
case ECBEncrypt:
00099
case ECBDecrypt:
00100
00101
while (len >= 8)
00102 {
00103 BF_ecb_encrypt(data, crypt,
bfkey,
00104
mode ==
ECBEncrypt ? BF_ENCRYPT : BF_DECRYPT);
00105 len -= 8;
00106 data += 8;
00107 crypt += 8;
00108 }
00109
break;
00110
00111
case CFBEncrypt:
00112
case CFBDecrypt:
00113
00114 BF_cfb64_encrypt(data, crypt, len,
bfkey,
ivec, &
ivecoff,
00115
mode ==
CFBEncrypt ? BF_ENCRYPT : BF_DECRYPT);
00116
break;
00117 }
00118
return success;
00119 }
00120
00121
00122
00123
00124 WvBlowfishStream::WvBlowfishStream(
WvStream *_cloned,
00125
const void *_key, size_t _keysize,
00126 WvBlowfishEncoder::Mode readmode, WvBlowfishEncoder::Mode writemode) :
00127
WvEncoderStream(_cloned)
00128 {
00129 readchain.
append(
new WvBlowfishEncoder(readmode,
00130 _key, _keysize),
true);
00131 writechain.
append(
new WvBlowfishEncoder(writemode,
00132 _key, _keysize),
true);
00133 }