WvStreams
wvcountermode.cc
1 /*
2  * Worldvisions Tunnel Vision Software:
3  * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4  *
5  * A 'counter mode' cryptography engine abstraction.
6  */
7 #include "wvcountermode.h"
8 
9 
11  const void *_counter, size_t _countersize) :
12  keycrypt(_keycrypt), counter(NULL)
13 {
14  setcounter(_counter, _countersize);
15 }
16 
17 
18 WvCounterModeEncoder::~WvCounterModeEncoder()
19 {
20  delete keycrypt;
21  deletev counter;
22 }
23 
24 
25 void WvCounterModeEncoder::setcounter(const void *_counter, size_t _countersize)
26 {
27  deletev counter;
28  counter = new unsigned char[_countersize];
29  countersize = _countersize;
30  memcpy(counter, _counter, countersize);
31 }
32 
33 
34 void WvCounterModeEncoder::getcounter(void *_counter) const
35 {
36  memcpy(_counter, counter, countersize);
37 }
38 
39 
41 {
42  for (size_t i = 0; i < countersize && ! ++counter[i]; ++i);
43 }
44 
45 
47  bool flush)
48 {
49  bool success = true;
50  size_t avail = inbuf.used();
51  size_t offset = outbuf.used();
52 
53  // generate a key stream
54  size_t len;
55  for (len = avail; len >= countersize; len -= countersize)
56  {
57  counterbuf.reset(counter, countersize);
58  success = keycrypt->encode(counterbuf, outbuf, true);
59  if (! success) break;
60  incrcounter();
61  }
62  if (flush && len != 0 && success)
63  {
64  counterbuf.reset(counter, countersize);
65  success = keycrypt->encode(counterbuf, outbuf, true);
66  if (success)
67  {
68  outbuf.unalloc(countersize - len);
69  len = 0;
70  incrcounter();
71  }
72  else
73  outbuf.unalloc(outbuf.used() - offset - avail);
74  }
75  avail -= len;
76 
77  // XOR in the data
78  while (avail > 0)
79  {
80  len = outbuf.optpeekable(offset);
81  unsigned char *dataout = outbuf.mutablepeek(offset, len);
82  size_t lenopt = inbuf.optgettable();
83  if (len > lenopt)
84  len = lenopt;
85  const unsigned char *datain = inbuf.get(len);
86 
87  if (len >= avail)
88  {
89  len = avail;
90  avail = 0;
91  }
92  else
93  {
94  avail -= len;
95  offset += len;
96  }
97  while (len-- > 0)
98  *(dataout++) ^= *(datain++);
99  }
100  return success;
101 }