diff options
author | Mike Buland <eichlan@xagasoft.com> | 2012-05-03 07:23:37 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2012-05-03 07:23:37 +0000 |
commit | 0214b67982bfbba8184057f8423bd69b50c6dd3f (patch) | |
tree | 8cfb6b4d83ea19ee955c0ef49cda654e14b88f0e | |
parent | df6a899ad6c9a1c792582ef1a3b838c7eb6d330c (diff) | |
download | libbu++-0214b67982bfbba8184057f8423bd69b50c6dd3f.tar.gz libbu++-0214b67982bfbba8184057f8423bd69b50c6dd3f.tar.bz2 libbu++-0214b67982bfbba8184057f8423bd69b50c6dd3f.tar.xz libbu++-0214b67982bfbba8184057f8423bd69b50c6dd3f.zip |
The cipher base class does nice buffering now based on the blocksize. This
means that you can write odd numbers of bytes or read odd numbers of bytes
from/to the ciphers and it'll just buffer until it gets a full block.
Next up is adding padding support. Right now it doesn't flush the buffers with
padding if you don't fill the last block. For that matter, it doesn't do any
padding at all.
-rw-r--r-- | src/experimental/cipher.h | 87 | ||||
-rw-r--r-- | src/tests/blowfish.cpp | 26 |
2 files changed, 81 insertions, 32 deletions
diff --git a/src/experimental/cipher.h b/src/experimental/cipher.h index 9e6f87d..6e1fa69 100644 --- a/src/experimental/cipher.h +++ b/src/experimental/cipher.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define BU_CIPHER_H | 2 | #define BU_CIPHER_H |
3 | 3 | ||
4 | #include "bu/filter.h" | 4 | #include "bu/filter.h" |
5 | #include "bu/util.h" | ||
5 | 6 | ||
6 | namespace Bu | 7 | namespace Bu |
7 | { | 8 | { |
@@ -10,7 +11,10 @@ namespace Bu | |||
10 | { | 11 | { |
11 | public: | 12 | public: |
12 | Cipher( Bu::Stream &rNext ) : | 13 | Cipher( Bu::Stream &rNext ) : |
13 | Bu::Filter( rNext ) | 14 | Bu::Filter( rNext ), |
15 | iReadBufFill( 0 ), | ||
16 | iReadBufPos( 0 ), | ||
17 | iWriteBufFill( 0 ) | ||
14 | { | 18 | { |
15 | } | 19 | } |
16 | 20 | ||
@@ -29,47 +33,59 @@ namespace Bu | |||
29 | 33 | ||
30 | virtual Bu::size read( void *pBuf, Bu::size iBytes ) | 34 | virtual Bu::size read( void *pBuf, Bu::size iBytes ) |
31 | { | 35 | { |
32 | uint32_t i; | 36 | Bu::size iRead = 0; |
33 | 37 | while( iRead < iBytes ) | |
34 | if (iBytes%iBlockSize) | ||
35 | { | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | iBytes /= iBlockSize; | ||
40 | |||
41 | for (i=0;i<iBytes;i++) | ||
42 | { | 38 | { |
43 | void *pSeg = ((char *)pBuf)+(i*iBlockSize); | 39 | if( iReadBufFill < iBlockSize ) |
44 | int iRead = rNext.read( pSeg, iBlockSize ); | 40 | { |
45 | decipher( pSeg ); | 41 | int iR = rNext.read( |
42 | aReadBuf+iReadBufFill, | ||
43 | iBlockSize-iReadBufFill | ||
44 | ); | ||
45 | if( iR == 0 ) | ||
46 | return iRead; | ||
47 | |||
48 | iReadBufFill += iR; | ||
49 | |||
50 | if( iReadBufFill == iBlockSize ) | ||
51 | decipher( aReadBuf ); | ||
52 | } | ||
53 | |||
54 | if( iReadBufFill == iBlockSize ) | ||
55 | { | ||
56 | int iCpy = Bu::min( (int)(iBytes-iRead), iBlockSize-iReadBufPos ); | ||
57 | memcpy( ((char *)pBuf)+iRead, aReadBuf+iReadBufPos, iCpy ); | ||
58 | iRead += iCpy; | ||
59 | iReadBufPos += iCpy; | ||
60 | if( iReadBufPos == iBlockSize ) | ||
61 | { | ||
62 | iReadBufPos = iReadBufFill = 0; | ||
63 | } | ||
64 | } | ||
46 | } | 65 | } |
47 | 66 | ||
48 | return iBytes*iBlockSize; | 67 | return iRead; |
49 | } | 68 | } |
50 | 69 | ||
51 | virtual Bu::size write( const void *pBuf, Bu::size iBytes ) | 70 | virtual Bu::size write( const void *pBuf, Bu::size iBytes ) |
52 | { | 71 | { |
53 | uint32_t i; | 72 | Bu::size iPos = 0; |
54 | 73 | ||
55 | if (iBytes%iBlockSize) | 74 | while( iPos < iBytes ) |
56 | { | 75 | { |
57 | return 0; | 76 | int iLeft = Bu::min((int)(iBytes-iPos),iBlockSize-iReadBufFill); |
77 | memcpy( aReadBuf+iReadBufFill, (char *)pBuf+iPos, iLeft ); | ||
78 | iPos += iLeft; | ||
79 | iReadBufFill += iLeft; | ||
80 | if( iReadBufFill == iBlockSize ) | ||
81 | { | ||
82 | encipher( aReadBuf ); | ||
83 | rNext.write( aReadBuf, iBlockSize ); | ||
84 | iReadBufFill = 0; | ||
85 | } | ||
58 | } | 86 | } |
59 | 87 | ||
60 | iBytes /= iBlockSize; | 88 | return iPos; |
61 | |||
62 | char buf[iBlockSize]; | ||
63 | |||
64 | for (i=0;i<iBytes;i++) | ||
65 | { | ||
66 | memcpy( buf, ((const char *)pBuf)+(i*iBlockSize), 8 ); | ||
67 | encipher( buf ); | ||
68 | rNext.write( buf, iBlockSize ); | ||
69 | } | ||
70 | |||
71 | memset( &buf, 0, iBlockSize ); | ||
72 | return iBytes*iBlockSize; | ||
73 | } | 89 | } |
74 | 90 | ||
75 | using Bu::Stream::read; | 91 | using Bu::Stream::read; |
@@ -78,6 +94,13 @@ namespace Bu | |||
78 | protected: | 94 | protected: |
79 | virtual void encipher( void *pData )=0; | 95 | virtual void encipher( void *pData )=0; |
80 | virtual void decipher( void *pData )=0; | 96 | virtual void decipher( void *pData )=0; |
97 | |||
98 | private: | ||
99 | char aReadBuf[iBlockSize]; | ||
100 | char aWriteBuf[iBlockSize]; | ||
101 | int iReadBufFill; | ||
102 | int iReadBufPos; | ||
103 | int iWriteBufFill; | ||
81 | }; | 104 | }; |
82 | }; | 105 | }; |
83 | 106 | ||
diff --git a/src/tests/blowfish.cpp b/src/tests/blowfish.cpp index 293539d..89183e4 100644 --- a/src/tests/blowfish.cpp +++ b/src/tests/blowfish.cpp | |||
@@ -48,6 +48,32 @@ static const char *testdat[34][3] ={ | |||
48 | 48 | ||
49 | int main( int argc, char *argv[] ) | 49 | int main( int argc, char *argv[] ) |
50 | { | 50 | { |
51 | MemBuf mb; | ||
52 | { | ||
53 | BlowfishEcb bf( mb ); | ||
54 | bf.setPassword( "01234567" ); | ||
55 | for( int j = 0; j < 4; j++ ) | ||
56 | { | ||
57 | bf.write("this is a test!!"+j, 1 ); | ||
58 | } | ||
59 | bf.write("this is a test!!"+4, 12 ); | ||
60 | } | ||
61 | mb.setPos( 0 ); | ||
62 | BlowfishEcb bf( mb ); | ||
63 | bf.setPassword( "01234567" ); | ||
64 | for( int j = 0; j < 3; j++ ) | ||
65 | { | ||
66 | char c; | ||
67 | bf.read( &c, 1 ); | ||
68 | sio << "char: '" << c << "'" << sio.nl; | ||
69 | } | ||
70 | |||
71 | char buf[100]; | ||
72 | int iR = bf.read( buf, 100 ); | ||
73 | buf[iR] = '\0'; | ||
74 | sio << "Got(" << iR << ") = '" << buf << "'" << sio.nl; | ||
75 | |||
76 | return 0; | ||
51 | 77 | ||
52 | for( int j = 0; j < 34; j++ ) | 78 | for( int j = 0; j < 34; j++ ) |
53 | { | 79 | { |