WvStreams
wvblowfish.cc
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>
11
12/***** WvBlowfishEncoder ****/
13
15 const void *_key, size_t _keysize) :
16 mode(_mode), key(NULL), bfkey(NULL)
17{
18 setkey(_key, _keysize);
19}
20
21
22WvBlowfishEncoder::~WvBlowfishEncoder()
23{
24 deletev key;
25 delete bfkey;
26}
27
28
30{
31 preparekey();
32 return true;
33}
34
35
36void WvBlowfishEncoder::setkey(const void *_key, size_t _keysize)
37{
38 deletev key;
39 keysize = _keysize;
40 key = new unsigned char[keysize];
41 memcpy(key, _key, keysize);
42 preparekey();
43}
44
45
46void WvBlowfishEncoder::setiv(const void *_iv)
47{
48 memcpy(ivec, _iv, sizeof(ivec));
49 ivecoff = 0;
50}
51
52
53void WvBlowfishEncoder::preparekey()
54{
55 delete bfkey;
56 bfkey = new BF_KEY;
57 BF_set_key(bfkey, keysize, key);
58 memset(ivec, 0, sizeof(ivec));
59 ivecoff = 0;
60}
61
62
63bool WvBlowfishEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
64{
65 size_t len = in.used();
66 bool success = true;
67 switch (mode) {
68 case ECBEncrypt:
69 case ECBDecrypt:
70 {
71 size_t remainder = len & 7;
72 len -= remainder;
73 if (remainder != 0 && flush)
74 {
75 if (mode == ECBEncrypt)
76 {
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;
82 }
83 else // nothing we can do here, flushing does not make sense!
84 success = false;
85 }
86 }
87
88 default:
89 break;
90 }
91 if (len == 0) return success;
92
93 const unsigned char *data = in.get(len);
94 unsigned char *crypt = out.alloc(len);
95
96 switch (mode)
97 {
98 case ECBEncrypt:
99 case ECBDecrypt:
100 // ECB works 64bits at a time
101 while (len >= 8)
102 {
103 BF_ecb_encrypt(data, crypt, bfkey,
104 mode == ECBEncrypt ? BF_ENCRYPT : BF_DECRYPT);
105 len -= 8;
106 data += 8;
107 crypt += 8;
108 }
109 break;
110
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;
117 }
118 return success;
119}
120
121
122/***** WvBlowfishStream *****/
123
124WvBlowfishStream::WvBlowfishStream(WvStream *_cloned,
125 const void *_key, size_t _keysize,
127 WvEncoderStream(_cloned)
128{
129 readchain.append(new WvBlowfishEncoder(readmode,
130 _key, _keysize), true);
131 writechain.append(new WvBlowfishEncoder(writemode,
132 _key, _keysize), true);
133}
An encoder implementing the Blowfish encryption method.
Definition wvblowfish.h:22
WvBlowfishEncoder(Mode mode, const void *key, size_t keysize)
Creates a new Blowfish cipher encoder.
Definition wvblowfish.cc:14
virtual bool _reset()
Template method implementation of reset().
Definition wvblowfish.cc:29
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Template method implementation of encode().
Definition wvblowfish.cc:63
void setiv(const void *iv)
Sets the current Blowfish initialization vector.
Definition wvblowfish.cc:46
void setkey(const void *key, size_t keysize)
Sets the current Blowfish key and resets the initialization vector to all nulls.
Definition wvblowfish.cc:36
WvEncoderStream chains a series of encoders on the input and output ports of the underlying stream to...
bool flush(WvBuf &inbuf, WvBuf &outbuf, bool finish=false)
Flushes the encoder and optionally finishes it.
Definition wvencoder.h:163
Unified support for streams, that is, sequences of bytes that may or may not be ready for read/write ...
Definition wvstream.h:25