aboutsummaryrefslogtreecommitdiff
path: root/src/unstable/cipher.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/unstable/cipher.h')
-rw-r--r--src/unstable/cipher.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/unstable/cipher.h b/src/unstable/cipher.h
new file mode 100644
index 0000000..eed73af
--- /dev/null
+++ b/src/unstable/cipher.h
@@ -0,0 +1,137 @@
1/*
2 * Copyright (C) 2007-2012 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_CIPHER_H
9#define BU_CIPHER_H
10
11#include "bu/filter.h"
12#include "bu/util.h"
13
14namespace Bu
15{
16 /**
17 * Represents a nice base class for a stream filter block encryption scheme.
18 * This class handles efficient caching during reading and writing,
19 * encrypting and decrypting for block ciphers. For each individual cipher
20 * you only have to worry about the block encryption and decryption. Cipher
21 * modes are handled with seperate classes, see Bu::CipherModeCbc,
22 * Bu::CipherModeCfb, Bu::CipherModeEcb, and Bu::CipherModeOfb.
23 *
24 *
25 */
26 template<int iBlockSize>
27 class Cipher : public Bu::Filter
28 {
29 public:
30 Cipher( Bu::Stream &rNext ) :
31 Bu::Filter( rNext ),
32 iReadBufFill( 0 ),
33 iReadBufPos( 0 ),
34 iWriteBufFill( 0 )
35 {
36 }
37
38 virtual ~Cipher()
39 {
40 }
41
42 virtual void start()
43 {
44 }
45
46 virtual Bu::size stop()
47 {
48 flush();
49 return 0;
50 }
51
52 virtual Bu::size read( void *pBuf, Bu::size iBytes )
53 {
54 Bu::size iRead = 0;
55 while( iRead < iBytes )
56 {
57 if( iReadBufFill < iBlockSize )
58 {
59 int iR = rNext.read(
60 aReadBuf+iReadBufFill,
61 iBlockSize-iReadBufFill
62 );
63 if( iR == 0 )
64 return iRead;
65
66 iReadBufFill += iR;
67
68 if( iReadBufFill == iBlockSize )
69 decipher( aReadBuf );
70 }
71
72 if( iReadBufFill == iBlockSize )
73 {
74 int iCpy = Bu::buMin( (int)(iBytes-iRead), iBlockSize-iReadBufPos );
75 memcpy( ((char *)pBuf)+iRead, aReadBuf+iReadBufPos, iCpy );
76 iRead += iCpy;
77 iReadBufPos += iCpy;
78 if( iReadBufPos == iBlockSize )
79 {
80 iReadBufPos = iReadBufFill = 0;
81 }
82 }
83 }
84
85 return iRead;
86 }
87
88 virtual Bu::size write( const void *pBuf, Bu::size iBytes )
89 {
90 Bu::size iPos = 0;
91
92 while( iPos < iBytes )
93 {
94 int iLeft = Bu::buMin((int)(iBytes-iPos),iBlockSize-iWriteBufFill);
95 memcpy( aWriteBuf+iWriteBufFill, (char *)pBuf+iPos, iLeft );
96 iPos += iLeft;
97 iWriteBufFill += iLeft;
98 if( iWriteBufFill == iBlockSize )
99 {
100 encipher( aWriteBuf );
101 rNext.write( aWriteBuf, iBlockSize );
102 iWriteBufFill = 0;
103 }
104 }
105
106 return iPos;
107 }
108
109 virtual void flush()
110 {
111 if( iWriteBufFill > 0 && iWriteBufFill < iBlockSize )
112 {
113 memset( aWriteBuf+iWriteBufFill, 0, iBlockSize-iWriteBufFill );
114 encipher( aWriteBuf );
115 rNext.write( aWriteBuf, iBlockSize );
116 iWriteBufFill = 0;
117 }
118 rNext.flush();
119 }
120
121 using Bu::Stream::read;
122 using Bu::Stream::write;
123
124 protected:
125 virtual void encipher( void *pData )=0;
126 virtual void decipher( void *pData )=0;
127
128 private:
129 char aReadBuf[iBlockSize];
130 char aWriteBuf[iBlockSize];
131 int iReadBufFill;
132 int iReadBufPos;
133 int iWriteBufFill;
134 };
135};
136
137#endif