Saner handling if config.mk doesn't exist: use a default config.defaults.mk.
[wvstreams.git] / crypto / wvblowfish.cc
blob9dd7b5ef133dbaed55ca28960a0e73b71634438d
1 /*
2 * Worldvisions Tunnel Vision Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * Blowfish cryptography abstractions.
6 */
7 #include "wvblowfish.h"
8 #include <assert.h>
9 #include <openssl/rand.h>
10 #include <openssl/blowfish.h>
12 /***** WvBlowfishEncoder ****/
14 WvBlowfishEncoder::WvBlowfishEncoder(Mode _mode,
15 const void *_key, size_t _keysize) :
16 mode(_mode), key(NULL), bfkey(NULL)
18 setkey(_key, _keysize);
22 WvBlowfishEncoder::~WvBlowfishEncoder()
24 deletev key;
25 delete bfkey;
29 bool WvBlowfishEncoder::_reset()
31 preparekey();
32 return true;
36 void WvBlowfishEncoder::setkey(const void *_key, size_t _keysize)
38 deletev key;
39 keysize = _keysize;
40 key = new unsigned char[keysize];
41 memcpy(key, _key, keysize);
42 preparekey();
46 void WvBlowfishEncoder::setiv(const void *_iv)
48 memcpy(ivec, _iv, sizeof(ivec));
49 ivecoff = 0;
53 void WvBlowfishEncoder::preparekey()
55 delete bfkey;
56 bfkey = new BF_KEY;
57 BF_set_key(bfkey, keysize, key);
58 memset(ivec, 0, sizeof(ivec));
59 ivecoff = 0;
63 bool WvBlowfishEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
65 size_t len = in.used();
66 bool success = true;
67 switch (mode) {
68 case ECBEncrypt:
69 case ECBDecrypt:
71 size_t remainder = len & 7;
72 len -= remainder;
73 if (remainder != 0 && flush)
75 if (mode == ECBEncrypt)
77 // if flushing on encryption, add some randomized padding
78 size_t padlen = 8 - remainder;
79 unsigned char *pad = in.alloc(padlen);
80 RAND_pseudo_bytes(pad, padlen);
81 len += 8;
83 else // nothing we can do here, flushing does not make sense!
84 success = false;
88 default:
89 break;
91 if (len == 0) return success;
93 const unsigned char *data = in.get(len);
94 unsigned char *crypt = out.alloc(len);
96 switch (mode)
98 case ECBEncrypt:
99 case ECBDecrypt:
100 // ECB works 64bits at a time
101 while (len >= 8)
103 BF_ecb_encrypt(data, crypt, bfkey,
104 mode == ECBEncrypt ? BF_ENCRYPT : BF_DECRYPT);
105 len -= 8;
106 data += 8;
107 crypt += 8;
109 break;
111 case CFBEncrypt:
112 case CFBDecrypt:
113 // CFB simulates a stream
114 BF_cfb64_encrypt(data, crypt, len, bfkey, ivec, &ivecoff,
115 mode == CFBEncrypt ? BF_ENCRYPT : BF_DECRYPT);
116 break;
118 return success;
122 /***** WvBlowfishStream *****/
124 WvBlowfishStream::WvBlowfishStream(WvStream *_cloned,
125 const void *_key, size_t _keysize,
126 WvBlowfishEncoder::Mode readmode, WvBlowfishEncoder::Mode writemode) :
127 WvEncoderStream(_cloned)
129 readchain.append(new WvBlowfishEncoder(readmode,
130 _key, _keysize), true);
131 writechain.append(new WvBlowfishEncoder(writemode,
132 _key, _keysize), true);