b6849e276b27953f0a8fbf364bd3742981afa8a4
[mono.git] / mcs / class / corlib / System.Security.Cryptography / RNGCryptoServiceProvider.cs
1 //
2 // System.Security.Cryptography.RNGCryptoServiceProvider
3 //
4 // Authors:
5 //      Mark Crichton (crichton@gimp.org)
6 //      Sebastien Pouliot (sebastien@ximian.com)
7 //
8 // (C) 2002
9 // (C) 2004 Novell (http://www.novell.com)
10 //
11
12 // "In the beginning there was Chaos,
13 // and within this Chaos was Power,
14 // Great Power without form."
15 // -- The Verrah Rubicon of Verena, Book One
16
17 using System;
18 using System.Runtime.CompilerServices;
19 using System.Text;
20
21 namespace System.Security.Cryptography {
22         
23 #if NET_1_0
24         public class RNGCryptoServiceProvider : RandomNumberGenerator {
25 #else
26         public sealed class RNGCryptoServiceProvider : RandomNumberGenerator {
27 #endif
28                 public RNGCryptoServiceProvider ()
29                 {
30                 }
31                 
32                 public RNGCryptoServiceProvider (byte[] rgb) 
33                 {
34                         Seed (rgb);
35                 }
36                 
37                 public RNGCryptoServiceProvider (CspParameters cspParams)
38                 {
39                         // CSP selection isn't supported
40                         // but we still return random (no exception) for compatibility
41                 }
42                 
43                 public RNGCryptoServiceProvider (string str) 
44                 {
45                         Seed (Encoding.UTF8.GetBytes (str));
46                 }
47                 
48                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
49                 private static extern void Seed (byte[] data);
50
51                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
52                 private extern void InternalGetBytes (byte[] data);
53                 
54                 public override void GetBytes (byte[] data) 
55                 {
56                         if (data == null)
57                                 throw new ArgumentNullException ("data");
58
59                         InternalGetBytes (data);
60                 }
61                 
62                 public override void GetNonZeroBytes (byte[] data) 
63                 {
64                         if (data == null)
65                                 throw new ArgumentNullException ("data");
66
67                         byte[] random = new byte [data.Length * 2];
68                         int i = 0;
69                         // one pass should be enough but hey this is random ;-)
70                         while (i < data.Length) {
71                                 GetBytes (random);
72                                 for (int j=0; j < random.Length; j++) {
73                                         if (i == data.Length)
74                                                 break;
75                                         if (random [j] != 0)
76                                                 data [i++] = random [j];
77                                 }
78                         }
79                 }
80                 
81                 /* Commented as we don't require this right now (and it will perform better that way)
82                 ~RNGCryptoServiceProvider () 
83                 {
84                         // in our case we have nothing unmanaged to dispose
85                 }*/
86         }
87 }