WvStreams
wvtripledes.cc
1/*
2 * Worldvisions Tunnel Vision Software:
3 * Copyright (C) 1997-2003 Net Integration Technologies, Inc.
4 *
5 * TripleDES cryptography abstractions.
6 */
7#include "wvtripledes.h"
8#include <assert.h>
9#include <openssl/rand.h>
10
11/***** WvTripleDESEncoder ****/
12
13WvTripleDESEncoder::WvTripleDESEncoder(Mode _mode, const void *_key1,
14 const void *_key2, const void *_key3) :
15 mode(_mode)
16{
17 setkey(_key1, _key2, _key3);
18}
19
20
21// WvTripleDESEncoder::~WvTripleDESEncoder()
22// {
23// delete[] key;
24// delete deskey1;
25// delete deskey2;
26// delete deskey3;
27// }
28
29
31{
32 memset(ivec, 0, sizeof(ivec));
33 ivecoff = 0;
34 return true;
35}
36
37
38void WvTripleDESEncoder::setkey(const void *_key1, const void *_key2,
39 const void *_key3)
40{
41 memcpy(key, _key1, DES_KEY_SZ);
42 DES_set_key(&key, &deskey1);
43
44 memcpy(key, _key2, DES_KEY_SZ);
45 DES_set_key(&key, &deskey2);
46
47 memcpy(key, _key3, DES_KEY_SZ);
48 DES_set_key(&key, &deskey3);
49
50 memset(ivec, 0, sizeof(ivec));
51 ivecoff = 0;
52}
53
54
55void WvTripleDESEncoder::setiv(const void *_iv)
56{
57 memcpy(ivec, _iv, sizeof(ivec));
58 ivecoff = 0;
59}
60
61bool WvTripleDESEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
62{
63 size_t len = in.used();
64 bool success = true;
65 switch (mode) {
66 case ECBEncrypt:
67 case ECBDecrypt:
68 case CBCEncrypt: // The caller should ensure the padding is correct or
69 case CBCDecrypt: // we do it for them, in probably the wrong way.
70 {
71 size_t remainder = len & 7; // conviently this is the same as len % 8
72 len -= remainder;
73 if (remainder != 0 && flush)
74 {
75 if (mode == ECBEncrypt || mode == CBCEncrypt)
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
92 if (len == 0)
93 return success;
94
95 const unsigned char *data = in.get(len);
96 unsigned char *crypt = out.alloc(len);
97
98 switch (mode)
99 {
100 case ECBEncrypt:
101 case ECBDecrypt:
102 // ECB works 64bits at a time
103 while (len >= 8)
104 {
105#if OPENSSL_VERSION_NUMBER >= 0x0090705fL \
106 && OPENSSL_VERSION_NUMBER < 0x0090800fL
107 DES_ecb3_encrypt(data, crypt,
108 &deskey1, &deskey2, &deskey3,
109 mode == ECBEncrypt ? DES_ENCRYPT : DES_DECRYPT);
110#else
111 DES_ecb3_encrypt(reinterpret_cast<const_DES_cblock*>(&data),
112 reinterpret_cast<DES_cblock*>(&crypt),
113 &deskey1, &deskey2, &deskey3,
114 mode == ECBEncrypt ? DES_ENCRYPT : DES_DECRYPT);
115#endif
116 len -= 8;
117 data += 8;
118 crypt += 8;
119 }
120 break;
121
122 case CFBEncrypt:
123 case CFBDecrypt:
124 // CFB simulates a stream
125 DES_ede3_cfb64_encrypt(data, crypt, len, &deskey1, &deskey2, &deskey3,
126 &ivec, &ivecoff,
127 mode == CFBEncrypt ? DES_ENCRYPT : DES_DECRYPT);
128 break;
129 case CBCEncrypt:
130 DES_ede3_cbc_encrypt(data, crypt, len, &deskey1, &deskey2, &deskey3,
131 &ivec, DES_ENCRYPT);
132 break;
133 case CBCDecrypt:
134 DES_ede3_cbc_encrypt(data, crypt, len, &deskey1, &deskey2, &deskey3,
135 &ivec, DES_DECRYPT);
136 break;
137 }
138 return success;
139}
140
141
142/***** WvTripleDESStream *****/
143
144WvTripleDESStream::WvTripleDESStream(WvStream *_cloned, const void *_key1,
145 const void *_key2, const void *_key3,
146 WvTripleDESEncoder::Mode readmode,
147 WvTripleDESEncoder::Mode writemode) :
148 WvEncoderStream(_cloned)
149{
150 readchain.append(new WvTripleDESEncoder(readmode,
151 _key1, _key2, _key3), true);
152 writechain.append(new WvTripleDESEncoder(writemode,
153 _key1, _key2, _key3), true);
154}
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.
Unified support for streams, that is, sequences of bytes that may or may not be ready for read/write ...
An encoder implementing the TripleDES encryption method.
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Template method implementation of encode().
virtual bool _reset()
Template method implementation of reset().