1+ using System . Collections . Generic ;
2+ using System . Security . Cryptography ;
3+
4+ public class Aes128CounterMode : SymmetricAlgorithm
5+ {
6+ private readonly byte [ ] Counter ;
7+
8+ private readonly AesManaged AESCtr ; public Aes128CounterMode ( byte [ ] CTR )
9+ {
10+ AESCtr = new AesManaged
11+ {
12+ Mode = CipherMode . ECB ,
13+ Padding = PaddingMode . None
14+ } ;
15+ Counter = CTR ;
16+ }
17+
18+ public override ICryptoTransform CreateEncryptor ( byte [ ] Key , byte [ ] Input )
19+ {
20+ return new CryptoTransform ( AESCtr , Key , Counter ) ;
21+ }
22+
23+ public override ICryptoTransform CreateDecryptor ( byte [ ] Key , byte [ ] Input )
24+ {
25+ return new CryptoTransform ( AESCtr , Key , Counter ) ;
26+ }
27+
28+ public override void GenerateKey ( )
29+ {
30+ AESCtr . GenerateKey ( ) ;
31+ }
32+
33+ public override void GenerateIV ( )
34+ {
35+ }
36+ }
37+
38+ public class CryptoTransform : ICryptoTransform
39+ {
40+ private readonly byte [ ] Counter ;
41+ private readonly ICryptoTransform Transform ;
42+ private readonly Queue < byte > QueuedBytes = new Queue < byte > ( ) ;
43+ private readonly SymmetricAlgorithm Algorithm ;
44+
45+ public CryptoTransform ( SymmetricAlgorithm Alg , byte [ ] Key , byte [ ] Counter )
46+ {
47+ Algorithm = Alg ;
48+ this . Counter = Counter ;
49+ var Block = new byte [ Algorithm . BlockSize / 8 ] ;
50+ Transform = Alg . CreateEncryptor ( Key , Block ) ;
51+ }
52+
53+ public byte [ ] TransformFinalBlock ( byte [ ] InputData , int StartOffset , int Length )
54+ {
55+ var EncryptedData = new byte [ Length ] ;
56+ TransformBlock ( InputData , StartOffset , Length , EncryptedData , 0 ) ;
57+ return EncryptedData ;
58+ }
59+
60+ public int TransformBlock ( byte [ ] InputData , int StartOffset , int Length , byte [ ] Output , int OutOffset )
61+ {
62+ for ( var i = 0 ; i < Length ; i ++ )
63+ {
64+ if ( Null ( ) ) CounterTransform ( ) ; var TransformBytes = QueuedBytes . Dequeue ( ) ;
65+ Output [ OutOffset + i ] = ( byte ) ( InputData [ StartOffset + i ] ^ TransformBytes ) ;
66+ }
67+ return Length ;
68+ }
69+
70+ private bool Null ( )
71+ {
72+ return QueuedBytes . Count == 0 ;
73+ }
74+
75+ private void CounterTransform ( )
76+ {
77+ var Output = new byte [ Algorithm . BlockSize / 8 ] ;
78+ Transform . TransformBlock ( Counter , 0 , Counter . Length , Output , 0 ) ;
79+ Countup ( ) ;
80+ foreach ( var Byte in Output )
81+ {
82+ QueuedBytes . Enqueue ( Byte ) ;
83+ }
84+ }
85+
86+ private void Countup ( )
87+ {
88+ for ( var i = Counter . Length - 1 ; i >= 0 ; i -- )
89+ {
90+ if ( ++ Counter [ i ] != 0 ) break ;
91+ }
92+ }
93+
94+ public int InputBlockSize
95+ {
96+ get
97+ {
98+ return Algorithm . BlockSize / 8 ;
99+ }
100+ }
101+
102+ public int OutputBlockSize
103+ {
104+ get
105+ {
106+ return Algorithm . BlockSize / 8 ;
107+ }
108+ }
109+
110+ public bool CanTransformMultipleBlocks
111+ {
112+ get
113+ {
114+ return true ;
115+ }
116+ }
117+
118+ public bool CanReuseTransform
119+ {
120+ get
121+ {
122+ return false ;
123+ }
124+ }
125+
126+ public void Dispose ( )
127+ {
128+ }
129+ }
0 commit comments