00001
00002
00003
00004
00005
00006
00007
#include "wvcountermode.h"
00008
00009
00010 WvCounterModeEncoder::WvCounterModeEncoder(
WvEncoder *_keycrypt,
00011
const void *_counter, size_t _countersize) :
00012 keycrypt(_keycrypt), counter(NULL)
00013 {
00014
setcounter(_counter, _countersize);
00015 }
00016
00017
00018 WvCounterModeEncoder::~WvCounterModeEncoder()
00019 {
00020
delete keycrypt;
00021
delete[]
counter;
00022 }
00023
00024
00025 void WvCounterModeEncoder::setcounter(
const void *_counter, size_t _countersize)
00026 {
00027
delete[]
counter;
00028
counter =
new unsigned char[_countersize];
00029
countersize = _countersize;
00030 memcpy(
counter, _counter,
countersize);
00031 }
00032
00033
00034 void WvCounterModeEncoder::getcounter(
void *_counter)
const
00035
{
00036 memcpy(_counter,
counter,
countersize);
00037 }
00038
00039
00040 void WvCounterModeEncoder::incrcounter()
00041 {
00042
for (size_t i = 0; i <
countersize && ! ++
counter[i]; ++i);
00043 }
00044
00045
00046 bool WvCounterModeEncoder::_encode(
WvBuf &inbuf,
WvBuf &outbuf,
00047
bool flush)
00048 {
00049
bool success =
true;
00050 size_t avail = inbuf.
used();
00051 size_t offset = outbuf.
used();
00052
00053
00054 size_t len;
00055
for (len = avail; len >=
countersize; len -= countersize)
00056 {
00057 counterbuf.
reset(
counter, countersize);
00058 success =
keycrypt->
encode(counterbuf, outbuf,
true);
00059
if (! success)
break;
00060
incrcounter();
00061 }
00062
if (flush && len != 0 && success)
00063 {
00064 counterbuf.
reset(
counter, countersize);
00065 success =
keycrypt->
encode(counterbuf, outbuf,
true);
00066
if (success)
00067 {
00068 outbuf.
unalloc(countersize - len);
00069 len = 0;
00070
incrcounter();
00071 }
00072
else
00073 outbuf.
unalloc(outbuf.
used() - offset - avail);
00074 }
00075 avail -= len;
00076
00077
00078
while (avail > 0)
00079 {
00080 len = outbuf.
optpeekable(offset);
00081
unsigned char *dataout = outbuf.
mutablepeek(offset, len);
00082 size_t lenopt = inbuf.
optgettable();
00083
if (len > lenopt)
00084 len = lenopt;
00085
const unsigned char *datain = inbuf.
get(len);
00086
00087
if (len >= avail)
00088 {
00089 len = avail;
00090 avail = 0;
00091 }
00092
else
00093 {
00094 avail -= len;
00095 offset += len;
00096 }
00097
while (len-- > 0)
00098 *(dataout++) ^= *(datain++);
00099 }
00100
return success;
00101 }