* FileSystemInfo.cs: corrected COM visibility of UTC properties
[mono.git] / mcs / class / Mono.Security / Mono.Security.Cryptography / CryptoTools.cs
1 //
2 // Mono.Security.Cryptography.CryptoTools
3 //      Shared class for common cryptographic functionalities
4 //
5 // Authors:
6 //      Sebastien Pouliot (spouliot@motus.com)
7 //
8 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
9 //
10
11 using System;
12 using System.Security.Cryptography;
13
14 namespace Mono.Security.Cryptography {
15
16 #if INSIDE_CORLIB
17         internal
18 #else
19         public
20 #endif
21         class KeyBuilder {
22         
23                 static private RandomNumberGenerator rng;
24         
25                 static KeyBuilder () 
26                 {
27                         rng = RandomNumberGenerator.Create ();
28                 }
29         
30                 static public byte[] Key (int size) 
31                 {
32                         byte[] key = new byte [size];
33                         rng.GetBytes (key);
34                         return key;
35                 }
36         
37                 static public byte[] IV (int size) 
38                 {
39                         byte[] iv = new byte [size];
40                         rng.GetBytes (iv);
41                         return iv;
42                 }
43         }
44         
45         // Process an array as a sequence of blocks
46 #if INSIDE_CORLIB
47         internal
48 #else
49         public
50 #endif
51         class BlockProcessor {
52                 private ICryptoTransform transform;
53                 private byte[] block;
54                 private int blockSize;  // in bytes (not in bits)
55                 private int blockCount;
56         
57                 public BlockProcessor (ICryptoTransform transform) 
58                         : this (transform, transform.InputBlockSize) {} 
59         
60                 // some Transforms (like HashAlgorithm descendant) return 1 for
61                 // block size (which isn't their real internal block size)
62                 public BlockProcessor (ICryptoTransform transform, int blockSize)
63                 {
64                         this.transform = transform;
65                         this.blockSize = blockSize;
66                         block = new byte [blockSize];
67                 }
68         
69                 ~BlockProcessor () 
70                 {
71                         // zeroize our block (so we don't retain any information)
72                         Array.Clear (block, 0, blockSize);
73                 }
74         
75                 public void Initialize ()
76                 {
77                         Array.Clear (block, 0, blockSize);
78                         blockCount = 0;
79                 }
80         
81                 public void Core (byte[] rgb) 
82                 {
83                         Core (rgb, 0, rgb.Length);
84                 }
85         
86                 public void Core (byte[] rgb, int ib, int cb) 
87                 {
88                         // 1. fill the rest of the "block"
89                         int n = System.Math.Min (blockSize - blockCount, cb);
90                         Array.Copy (rgb, ib, block, blockCount, n); 
91                         blockCount += n;
92         
93                         // 2. if block is full then transform it
94                         if (blockCount == blockSize) {
95                                 transform.TransformBlock (block, 0, blockSize, block, 0);
96         
97                                 // 3. transform any other full block in specified buffer
98                                 int b = (int) ((cb - n) / blockSize);
99                                 for (int i=0; i < b; i++) {
100                                         transform.TransformBlock (rgb, n, blockSize, block, 0);
101                                         n += blockSize;
102                                 }
103         
104                                 // 4. if data is still present fill the "block" with the remainder
105                                 blockCount = cb - n;
106                                 if (blockCount > 0)
107                                         Array.Copy (rgb, n, block, 0, blockCount);
108                         }
109                 }
110         
111                 public byte[] Final () 
112                 {
113                         return transform.TransformFinalBlock (block, 0, blockCount);
114                 }
115         }
116 }