3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>[....]</OWNER>
10 // RNGCryptoServiceProvider.cs
13 namespace System.Security.Cryptography {
14 using Microsoft.Win32;
15 using System.Runtime.CompilerServices;
16 using System.Runtime.InteropServices;
17 using System.Security;
18 using System.Runtime.Versioning;
19 using System.Diagnostics.Contracts;
22 [System.Runtime.InteropServices.ComVisible(true)]
23 #endif // !FEATURE_CORECLR
24 public sealed class RNGCryptoServiceProvider : RandomNumberGenerator {
26 [System.Security.SecurityCritical] // auto-generated
27 SafeProvHandle m_safeProvHandle;
29 #else // !FEATURE_CORECLR
31 [System.Security.SecurityCritical] // auto-generated
33 SafeCspHandle m_cspHandle;
34 #endif // !FEATURE_CORECLR
37 // public constructors
43 public RNGCryptoServiceProvider() : this((CspParameters) null) {}
45 public RNGCryptoServiceProvider() { }
46 #endif // !FEATURE_PAL
49 public RNGCryptoServiceProvider(string str) : this((CspParameters) null) {}
51 public RNGCryptoServiceProvider(byte[] rgb) : this((CspParameters) null) {}
53 [System.Security.SecuritySafeCritical] // auto-generated
54 public RNGCryptoServiceProvider(CspParameters cspParams) {
55 if (cspParams != null) {
56 m_safeProvHandle = Utils.AcquireProvHandle(cspParams);
60 m_safeProvHandle = Utils.StaticProvHandle;
65 [System.Security.SecuritySafeCritical] // auto-generated
66 protected override void Dispose(bool disposing) {
67 base.Dispose(disposing);
69 if (disposing && m_ownsHandle) {
70 m_safeProvHandle.Dispose();
73 #endif // !FEATURE_PAL
75 #else // !FEATURE_CORECLR
78 [System.Security.SecuritySafeCritical] // auto-generated
80 public RNGCryptoServiceProvider() {
81 m_cspHandle = CapiNative.AcquireCsp(null,
82 CapiNative.ProviderNames.MicrosoftEnhanced,
83 CapiNative.ProviderType.RsaFull,
84 CapiNative.CryptAcquireContextFlags.VerifyContext);
86 #endif // !FEATURE_CORECLR
92 [System.Security.SecuritySafeCritical] // auto-generated
93 public override void GetBytes(byte[] data) {
94 if (data == null) throw new ArgumentNullException("data");
95 Contract.EndContractBlock();
97 GetBytes(m_safeProvHandle, data, data.Length);
99 if (!Win32Native.Random(true, data, data.Length))
100 throw new CryptographicException(Marshal.GetLastWin32Error());
101 #endif // !FEATURE_PAL
104 [System.Security.SecuritySafeCritical] // auto-generated
105 public override void GetNonZeroBytes(byte[] data) {
107 throw new ArgumentNullException("data");
108 Contract.EndContractBlock();
111 GetNonZeroBytes(m_safeProvHandle, data, data.Length);
115 int indexOfFirst0Byte = data.Length;
116 for (int i = 0; i < data.Length; i++) {
118 indexOfFirst0Byte = i;
122 for (int i = indexOfFirst0Byte; i < data.Length; i++) {
124 data[indexOfFirst0Byte++] = data[i];
128 while (indexOfFirst0Byte < data.Length) {
129 // this should be more than enough to fill the rest in one iteration
130 byte[] tmp = new byte[2 * (data.Length - indexOfFirst0Byte)];
133 for (int i = 0; i < tmp.Length; i++) {
135 data[indexOfFirst0Byte++] = tmp[i];
136 if (indexOfFirst0Byte >= data.Length) break;
140 #endif // !FEATURE_PAL
143 #else // !FEATURE_CORECLR
146 [System.Security.SecuritySafeCritical] // auto-generated
148 protected override void Dispose(bool disposing) {
151 if (m_cspHandle != null) {
152 m_cspHandle.Dispose();
157 base.Dispose(disposing);
162 [System.Security.SecuritySafeCritical] // auto-generated
164 public override void GetBytes(byte[] data) {
166 throw new ArgumentNullException("data");
168 Contract.EndContractBlock();
170 if (data.Length > 0) {
171 CapiNative.GenerateRandomBytes(m_cspHandle, data);
176 [System.Security.SecuritySafeCritical] // auto-generated
178 public override void GetBytes(byte[] data, int offset, int count) {
179 if (data == null) throw new ArgumentNullException("data");
180 if (offset < 0) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
181 if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
182 if (offset + count > data.Length) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
185 CapiNative.GenerateRandomBytes(m_cspHandle, data, offset, count);
188 #endif // !FEATURE_CORECLR
191 [System.Security.SecurityCritical] // auto-generated
192 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
193 [ResourceExposure(ResourceScope.None)]
194 private static extern void GetBytes(SafeProvHandle hProv, byte[] randomBytes, int count);
196 [System.Security.SecurityCritical] // auto-generated
197 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
198 [ResourceExposure(ResourceScope.None)]
199 private static extern void GetNonZeroBytes(SafeProvHandle hProv, byte[] randomBytes, int count);