* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / corlib / Mono.Security.Cryptography / CryptoTools.cs
1 //
2 // Mono.Security.Cryptography.CryptoTools
3 //      Shared class for common cryptographic functionalities
4 //
5 // Authors:
6 //      Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
9 // (C) 2004 Novell (http://www.novell.com)
10 //
11
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.Security.Cryptography;
37
38 namespace Mono.Security.Cryptography {
39
40 #if INSIDE_CORLIB
41         internal
42 #else
43         public
44 #endif
45         sealed class KeyBuilder {
46         
47                 static private RandomNumberGenerator rng;
48
49                 private KeyBuilder ()
50                 {
51                 }
52         
53                 static public byte[] Key (int size) 
54                 {
55                         if (rng == null)
56                                 rng = RandomNumberGenerator.Create ();
57
58                         byte[] key = new byte [size];
59                         rng.GetBytes (key);
60                         return key;
61                 }
62         
63                 static public byte[] IV (int size) 
64                 {
65                         if (rng == null)
66                                 rng = RandomNumberGenerator.Create ();
67
68                         byte[] iv = new byte [size];
69                         rng.GetBytes (iv);
70                         return iv;
71                 }
72         }
73         
74         // Process an array as a sequence of blocks
75 #if INSIDE_CORLIB
76         internal
77 #else
78         public
79 #endif
80         class BlockProcessor {
81                 private ICryptoTransform transform;
82                 private byte[] block;
83                 private int blockSize;  // in bytes (not in bits)
84                 private int blockCount;
85         
86                 public BlockProcessor (ICryptoTransform transform) 
87                         : this (transform, transform.InputBlockSize) {} 
88         
89                 // some Transforms (like HashAlgorithm descendant) return 1 for
90                 // block size (which isn't their real internal block size)
91                 public BlockProcessor (ICryptoTransform transform, int blockSize)
92                 {
93                         this.transform = transform;
94                         this.blockSize = blockSize;
95                         block = new byte [blockSize];
96                 }
97         
98                 ~BlockProcessor () 
99                 {
100                         // zeroize our block (so we don't retain any information)
101                         Array.Clear (block, 0, blockSize);
102                 }
103         
104                 public void Initialize ()
105                 {
106                         Array.Clear (block, 0, blockSize);
107                         blockCount = 0;
108                 }
109         
110                 public void Core (byte[] rgb) 
111                 {
112                         Core (rgb, 0, rgb.Length);
113                 }
114         
115                 public void Core (byte[] rgb, int ib, int cb) 
116                 {
117                         // 1. fill the rest of the "block"
118                         int n = System.Math.Min (blockSize - blockCount, cb);
119                         Buffer.BlockCopy (rgb, ib, block, blockCount, n); 
120                         blockCount += n;
121         
122                         // 2. if block is full then transform it
123                         if (blockCount == blockSize) {
124                                 transform.TransformBlock (block, 0, blockSize, block, 0);
125         
126                                 // 3. transform any other full block in specified buffer
127                                 int b = (int) ((cb - n) / blockSize);
128                                 for (int i=0; i < b; i++) {
129                                         transform.TransformBlock (rgb, n + ib, blockSize, block, 0);
130                                         n += blockSize;
131                                 }
132         
133                                 // 4. if data is still present fill the "block" with the remainder
134                                 blockCount = cb - n;
135                                 if (blockCount > 0)
136                                         Buffer.BlockCopy (rgb, n, block, 0, blockCount);
137                         }
138                 }
139         
140                 public byte[] Final () 
141                 {
142                         return transform.TransformFinalBlock (block, 0, blockCount);
143                 }
144         }
145 }