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 
13 WvTripleDESEncoder::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 
38 void 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 
55 void WvTripleDESEncoder::setiv(const void *_iv)
56 {
57  memcpy(ivec, _iv, sizeof(ivec));
58  ivecoff = 0;
59 }
60 
61 bool 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 
144 WvTripleDESStream::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 }
T * alloc(size_t count)
Allocates exactly the specified number of elements and returns a pointer to an UNINITIALIZED storage ...
Definition: wvbufbase.h:379
WvEncoderStream chains a series of encoders on the input and output ports of the underlying stream to...
Unified support for streams, that is, sequences of bytes that may or may not be ready for read/write ...
Definition: wvstream.h:24
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers...
Definition: wvbuf.h:22
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Template method implementation of encode().
Definition: wvtripledes.cc:61
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
An encoder implementing the TripleDES encryption method.
Definition: wvtripledes.h:22
virtual bool _reset()
Template method implementation of reset().
Definition: wvtripledes.cc:30
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
Definition: wvbufbase.h:114