3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
15 namespace System.Security.Cryptography
17 using Microsoft.Win32;
19 using System.Reflection;
20 using System.Globalization;
21 using System.Runtime.CompilerServices;
22 using System.Runtime.InteropServices;
24 using System.Security.AccessControl;
25 #endif // FEATURE_MACL
26 using System.Security.Cryptography.X509Certificates;
27 using System.Security.Permissions;
28 #if FEATURE_IMPERSONATION
29 using System.Security.Principal;
30 #endif // FEATURE_IMPERSONATION
32 using System.Threading;
33 using System.Diagnostics.Contracts;
34 using System.Runtime.Versioning;
36 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
38 internal enum CspAlgorithmType {
43 internal enum CspAlgorithmType {
49 internal static class Constants {
50 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
51 internal const int S_OK = 0;
52 internal const int NTE_FILENOTFOUND = unchecked((int) 0x80070002); // The system cannot find the file specified.
53 internal const int NTE_NO_KEY = unchecked((int) 0x8009000D); // Key does not exist.
54 internal const int NTE_BAD_KEYSET = unchecked((int) 0x80090016); // Keyset does not exist.
55 internal const int NTE_KEYSET_NOT_DEF = unchecked((int) 0x80090019); // The keyset is not defined.
57 internal const int KP_IV = 1;
58 internal const int KP_MODE = 4;
59 internal const int KP_MODE_BITS = 5;
60 internal const int KP_EFFECTIVE_KEYLEN = 19;
62 internal const int ALG_CLASS_SIGNATURE = (1 << 13);
63 internal const int ALG_CLASS_DATA_ENCRYPT = (3 << 13);
64 internal const int ALG_CLASS_HASH = (4 << 13);
65 internal const int ALG_CLASS_KEY_EXCHANGE = (5 << 13);
67 internal const int ALG_TYPE_DSS = (1 << 9);
68 internal const int ALG_TYPE_RSA = (2 << 9);
69 internal const int ALG_TYPE_BLOCK = (3 << 9);
70 internal const int ALG_TYPE_STREAM = (4 << 9);
71 internal const int ALG_TYPE_ANY = (0);
73 internal const int CALG_MD5 = (ALG_CLASS_HASH | ALG_TYPE_ANY | 3);
74 internal const int CALG_SHA1 = (ALG_CLASS_HASH | ALG_TYPE_ANY | 4);
75 internal const int CALG_SHA_256 = (ALG_CLASS_HASH | ALG_TYPE_ANY | 12);
76 internal const int CALG_SHA_384 = (ALG_CLASS_HASH | ALG_TYPE_ANY | 13);
77 internal const int CALG_SHA_512 = (ALG_CLASS_HASH | ALG_TYPE_ANY | 14);
78 internal const int CALG_RSA_KEYX = (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | 0);
79 internal const int CALG_RSA_SIGN = (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | 0);
80 internal const int CALG_DSS_SIGN = (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | 0);
81 internal const int CALG_DES = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 1);
82 internal const int CALG_RC2 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 2);
83 internal const int CALG_3DES = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 3);
84 internal const int CALG_3DES_112 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 9);
85 internal const int CALG_AES_128 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 14);
86 internal const int CALG_AES_192 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 15);
87 internal const int CALG_AES_256 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 16);
88 internal const int CALG_RC4 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | 1);
89 #endif // FEATURE_CRYPTO
91 internal const int PROV_RSA_FULL = 1;
92 internal const int PROV_DSS_DH = 13;
93 internal const int PROV_RSA_AES = 24;
95 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
96 internal const int AT_KEYEXCHANGE = 1;
97 #endif // FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
98 internal const int AT_SIGNATURE = 2;
99 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
100 internal const int PUBLICKEYBLOB = 0x6;
101 internal const int PRIVATEKEYBLOB = 0x7;
102 internal const int CRYPT_OAEP = 0x40;
105 internal const uint CRYPT_VERIFYCONTEXT = 0xF0000000;
106 internal const uint CRYPT_NEWKEYSET = 0x00000008;
107 internal const uint CRYPT_DELETEKEYSET = 0x00000010;
108 internal const uint CRYPT_MACHINE_KEYSET = 0x00000020;
109 internal const uint CRYPT_SILENT = 0x00000040;
110 internal const uint CRYPT_EXPORTABLE = 0x00000001;
112 internal const uint CLR_KEYLEN = 1;
113 internal const uint CLR_PUBLICKEYONLY = 2;
114 internal const uint CLR_EXPORTABLE = 3;
115 internal const uint CLR_REMOVABLE = 4;
116 internal const uint CLR_HARDWARE = 5;
117 internal const uint CLR_ACCESSIBLE = 6;
118 internal const uint CLR_PROTECTED = 7;
119 internal const uint CLR_UNIQUE_CONTAINER = 8;
120 internal const uint CLR_ALGID = 9;
121 internal const uint CLR_PP_CLIENT_HWND = 10;
122 internal const uint CLR_PP_PIN = 11;
124 internal const string OID_RSA_SMIMEalgCMS3DESwrap = "1.2.840.113549.1.9.16.3.6";
125 internal const string OID_RSA_MD5 = "1.2.840.113549.2.5";
126 internal const string OID_RSA_RC2CBC = "1.2.840.113549.3.2";
127 internal const string OID_RSA_DES_EDE3_CBC = "1.2.840.113549.3.7";
128 internal const string OID_OIWSEC_desCBC = "1.3.14.3.2.7";
129 internal const string OID_OIWSEC_SHA1 = "1.3.14.3.2.26";
130 internal const string OID_OIWSEC_SHA256 = "2.16.840.1.101.3.4.2.1";
131 internal const string OID_OIWSEC_SHA384 = "2.16.840.1.101.3.4.2.2";
132 internal const string OID_OIWSEC_SHA512 = "2.16.840.1.101.3.4.2.3";
133 internal const string OID_OIWSEC_RIPEMD160 = "1.3.36.3.2.1";
134 #endif // FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
137 internal static class Utils {
139 #if !FEATURE_PAL && FEATURE_CRYPTO
140 [SecuritySafeCritical]
147 // The default provider value must remain '1' for Mono, otherwise we won't be able
148 // to locate keypairs that were serialized by Mono versions 4.0 and lower.
149 // (The ProviderType property in the CspParameters class affects serialization)
150 internal const int DefaultRsaProviderType = 1;
152 // Provider type to use by default for RSA operations. We want to use RSA-AES CSP
153 // since it enables access to SHA-2 operations. All currently supported OSes support RSA-AES.
154 internal const int DefaultRsaProviderType = Constants.PROV_RSA_AES;
158 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
159 // Private object for locking instead of locking on a public type for SQL reliability work.
160 private static Object s_InternalSyncObject = new Object();
162 private static Object InternalSyncObject {
163 get { return s_InternalSyncObject; }
166 [System.Security.SecurityCritical] // auto-generated
167 private static volatile SafeProvHandle _safeProvHandle;
168 internal static SafeProvHandle StaticProvHandle {
169 [System.Security.SecurityCritical] // auto-generated
171 if (_safeProvHandle == null) {
172 lock (InternalSyncObject) {
173 if (_safeProvHandle == null) {
174 _safeProvHandle = AcquireProvHandle(new CspParameters(DefaultRsaProviderType));
178 return _safeProvHandle;
182 [System.Security.SecurityCritical] // auto-generated
183 private static volatile SafeProvHandle _safeDssProvHandle;
184 internal static SafeProvHandle StaticDssProvHandle {
185 [System.Security.SecurityCritical] // auto-generated
187 if (_safeDssProvHandle == null) {
188 lock (InternalSyncObject) {
189 if (_safeDssProvHandle == null) {
190 _safeDssProvHandle = CreateProvHandle(new CspParameters(Constants.PROV_DSS_DH), true);
194 return _safeDssProvHandle;
199 [System.Security.SecurityCritical] // auto-generated
200 [ResourceExposure(ResourceScope.None)]
201 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
202 internal static SafeProvHandle AcquireProvHandle (CspParameters parameters) {
203 if (parameters == null)
204 parameters = new CspParameters(DefaultRsaProviderType);
206 SafeProvHandle safeProvHandle = SafeProvHandle.InvalidHandle;
207 Utils._AcquireCSP(parameters, ref safeProvHandle);
208 return safeProvHandle;
211 [System.Security.SecurityCritical] // auto-generated
212 [ResourceExposure(ResourceScope.None)]
213 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
214 internal static SafeProvHandle CreateProvHandle (CspParameters parameters, bool randomKeyContainer) {
215 SafeProvHandle safeProvHandle = SafeProvHandle.InvalidHandle;
216 int hr = Utils._OpenCSP(parameters, 0, ref safeProvHandle);
217 KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
218 if (hr != Constants.S_OK) {
219 // If UseExistingKey flag is used and the key container does not exist
220 // throw an exception without attempting to create the container.
221 if ((parameters.Flags & CspProviderFlags.UseExistingKey) != 0 || (hr != Constants.NTE_KEYSET_NOT_DEF && hr != Constants.NTE_BAD_KEYSET && hr != Constants.NTE_FILENOTFOUND))
222 throw new CryptographicException(hr);
223 if (!randomKeyContainer) {
224 if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
225 KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Create);
226 kp.AccessEntries.Add(entry);
230 Utils._CreateCSP(parameters, randomKeyContainer, ref safeProvHandle);
232 if (!randomKeyContainer) {
233 if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
234 KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open);
235 kp.AccessEntries.Add(entry);
240 return safeProvHandle;
242 #endif // !FEATURE_PAL
245 [System.Security.SecurityCritical] // auto-generated
246 internal static CryptoKeySecurity GetKeySetSecurityInfo (SafeProvHandle hProv, AccessControlSections accessControlSections) {
247 SecurityInfos securityInfo = 0;
248 Privilege privilege = null;
250 if ((accessControlSections & AccessControlSections.Owner) != 0)
251 securityInfo |= SecurityInfos.Owner;
252 if ((accessControlSections & AccessControlSections.Group) != 0)
253 securityInfo |= SecurityInfos.Group;
254 if ((accessControlSections & AccessControlSections.Access) != 0)
255 securityInfo |= SecurityInfos.DiscretionaryAcl;
257 byte[] rawSecurityDescriptor = null;
260 RuntimeHelpers.PrepareConstrainedRegions();
262 if ((accessControlSections & AccessControlSections.Audit) != 0) {
263 securityInfo |= SecurityInfos.SystemAcl;
264 privilege = new Privilege("SeSecurityPrivilege");
267 rawSecurityDescriptor = _GetKeySetSecurityInfo(hProv, securityInfo, out error);
270 if (privilege != null)
274 // This means that the object doesn't have a security descriptor. And thus we throw
275 // a specific exception for the caller to catch and handle properly.
276 if (error == Win32Native.ERROR_SUCCESS && (rawSecurityDescriptor == null || rawSecurityDescriptor.Length == 0))
277 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoSecurityDescriptor"));
278 if (error == Win32Native.ERROR_NOT_ENOUGH_MEMORY)
279 throw new OutOfMemoryException();
280 if (error == Win32Native.ERROR_ACCESS_DENIED)
281 throw new UnauthorizedAccessException();
282 if (error == Win32Native.ERROR_PRIVILEGE_NOT_HELD)
283 throw new PrivilegeNotHeldException( "SeSecurityPrivilege" );
284 if (error != Win32Native.ERROR_SUCCESS)
285 throw new CryptographicException(error);
287 CommonSecurityDescriptor sd = new CommonSecurityDescriptor(false /* isContainer */,
289 new RawSecurityDescriptor(rawSecurityDescriptor, 0),
291 return new CryptoKeySecurity(sd);
294 [System.Security.SecurityCritical] // auto-generated
295 internal static void SetKeySetSecurityInfo (SafeProvHandle hProv, CryptoKeySecurity cryptoKeySecurity, AccessControlSections accessControlSections) {
296 SecurityInfos securityInfo = 0;
297 Privilege privilege = null;
299 if ((accessControlSections & AccessControlSections.Owner) != 0 && cryptoKeySecurity._securityDescriptor.Owner != null)
300 securityInfo |= SecurityInfos.Owner;
301 if ((accessControlSections & AccessControlSections.Group) != 0 && cryptoKeySecurity._securityDescriptor.Group != null)
302 securityInfo |= SecurityInfos.Group;
303 if ((accessControlSections & AccessControlSections.Audit) != 0)
304 securityInfo |= SecurityInfos.SystemAcl;
305 if ((accessControlSections & AccessControlSections.Access) != 0 && cryptoKeySecurity._securityDescriptor.IsDiscretionaryAclPresent)
306 securityInfo |= SecurityInfos.DiscretionaryAcl;
308 if (securityInfo == 0) {
309 // Nothing to persist
315 RuntimeHelpers.PrepareConstrainedRegions();
317 if ((securityInfo & SecurityInfos.SystemAcl) != 0) {
318 privilege = new Privilege("SeSecurityPrivilege");
322 byte[] sd = cryptoKeySecurity.GetSecurityDescriptorBinaryForm();
323 if (sd != null && sd.Length > 0)
324 error = SetKeySetSecurityInfo (hProv, securityInfo, sd);
327 if (privilege != null)
331 if (error == Win32Native.ERROR_ACCESS_DENIED || error == Win32Native.ERROR_INVALID_OWNER || error == Win32Native.ERROR_INVALID_PRIMARY_GROUP)
332 throw new UnauthorizedAccessException();
333 else if (error == Win32Native.ERROR_PRIVILEGE_NOT_HELD)
334 throw new PrivilegeNotHeldException("SeSecurityPrivilege");
335 else if (error == Win32Native.ERROR_INVALID_HANDLE)
336 throw new NotSupportedException(Environment.GetResourceString("AccessControl_InvalidHandle"));
337 else if (error != Win32Native.ERROR_SUCCESS)
338 throw new CryptographicException(error);
340 #endif //FEATURE_MACL
342 [System.Security.SecurityCritical] // auto-generated
343 internal static byte[] ExportCspBlobHelper (bool includePrivateParameters, CspParameters parameters, SafeKeyHandle safeKeyHandle) {
344 if (includePrivateParameters) {
345 if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
346 KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
347 KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Export);
348 kp.AccessEntries.Add(entry);
353 Utils.ExportCspBlob(safeKeyHandle, includePrivateParameters ? Constants.PRIVATEKEYBLOB : Constants.PUBLICKEYBLOB, JitHelpers.GetObjectHandleOnStack(ref blob));
357 [System.Security.SecuritySafeCritical] // auto-generated
358 [ResourceExposure(ResourceScope.None)]
359 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
360 internal static void GetKeyPairHelper (CspAlgorithmType keyType, CspParameters parameters, bool randomKeyContainer, int dwKeySize, ref SafeProvHandle safeProvHandle, ref SafeKeyHandle safeKeyHandle) {
361 SafeProvHandle TempFetchedProvHandle = Utils.CreateProvHandle(parameters, randomKeyContainer);
364 // If the user wanted to set the security descriptor on the provider context, apply it now.
365 if (parameters.CryptoKeySecurity != null) {
366 KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
367 KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.ChangeAcl);
368 kp.AccessEntries.Add(entry);
370 SetKeySetSecurityInfo(TempFetchedProvHandle, parameters.CryptoKeySecurity, parameters.CryptoKeySecurity.ChangedAccessControlSections);
372 #endif //FEATURE_MACL
374 #if FEATURE_X509_SECURESTRINGS
375 // If the user wanted to specify a PIN or HWND for a smart card CSP, apply those settings now.
376 if (parameters.ParentWindowHandle != IntPtr.Zero) {
377 // Copy the value onto the stack.
378 // Then, for versions beyond 4.6.2 take the address of that copy, since &hwnd is what the API wants.
379 IntPtr parentWindowHandle = parameters.ParentWindowHandle;
380 IntPtr pHwnd = parentWindowHandle;
382 if (!AppContextSwitches.DoNotAddrOfCspParentWindowHandle) {
384 pHwnd = new IntPtr(&parentWindowHandle);
388 SetProviderParameter(TempFetchedProvHandle, parameters.KeyNumber, Constants.CLR_PP_CLIENT_HWND, pHwnd);
390 else if (parameters.KeyPassword != null) {
391 IntPtr szPassword = Marshal.SecureStringToCoTaskMemAnsi(parameters.KeyPassword);
393 SetProviderParameter(TempFetchedProvHandle, parameters.KeyNumber, Constants.CLR_PP_PIN, szPassword);
396 if (szPassword != IntPtr.Zero)
397 Marshal.ZeroFreeCoTaskMemAnsi(szPassword);
400 #endif //FEATURE_X509_SECURESTRINGS
402 safeProvHandle = TempFetchedProvHandle;
404 // If the key already exists, use it, else generate a new one
405 SafeKeyHandle TempFetchedKeyHandle = SafeKeyHandle.InvalidHandle;
406 int hr = Utils._GetUserKey(safeProvHandle, parameters.KeyNumber, ref TempFetchedKeyHandle);
407 if (hr != Constants.S_OK) {
408 if ((parameters.Flags & CspProviderFlags.UseExistingKey) != 0 || hr != Constants.NTE_NO_KEY)
409 throw new CryptographicException(hr);
410 // _GenerateKey will check for failures and throw an exception
411 Utils._GenerateKey(safeProvHandle, parameters.KeyNumber, parameters.Flags, dwKeySize, ref TempFetchedKeyHandle);
414 // check that this is indeed an RSA/DSS key.
415 byte[] algid = (byte[]) Utils._GetKeyParameter(TempFetchedKeyHandle, Constants.CLR_ALGID);
416 int dwAlgId = (algid[0] | (algid[1] << 8) | (algid[2] << 16) | (algid[3] << 24));
417 if ((keyType == CspAlgorithmType.Rsa && dwAlgId != Constants.CALG_RSA_KEYX && dwAlgId != Constants.CALG_RSA_SIGN) ||
418 (keyType == CspAlgorithmType.Dss && dwAlgId != Constants.CALG_DSS_SIGN)) {
419 TempFetchedKeyHandle.Dispose();
420 throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_WrongKeySpec"));
423 safeKeyHandle = TempFetchedKeyHandle;
426 [System.Security.SecurityCritical] // auto-generated
427 internal static void ImportCspBlobHelper (CspAlgorithmType keyType, byte[] keyBlob, bool publicOnly, ref CspParameters parameters, bool randomKeyContainer, ref SafeProvHandle safeProvHandle, ref SafeKeyHandle safeKeyHandle) {
428 // Free the current key handle
429 if (safeKeyHandle != null && !safeKeyHandle.IsClosed)
430 safeKeyHandle.Dispose();
431 safeKeyHandle = SafeKeyHandle.InvalidHandle;
434 parameters.KeyNumber = Utils._ImportCspBlob(keyBlob, keyType == CspAlgorithmType.Dss ? Utils.StaticDssProvHandle : Utils.StaticProvHandle, (CspProviderFlags) 0, ref safeKeyHandle);
436 if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
437 KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
438 KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Import);
439 kp.AccessEntries.Add(entry);
442 if (safeProvHandle == null)
443 safeProvHandle = Utils.CreateProvHandle(parameters, randomKeyContainer);
444 parameters.KeyNumber = Utils._ImportCspBlob(keyBlob, safeProvHandle, parameters.Flags, ref safeKeyHandle);
447 #endif // FEATURE_CRYPTO
449 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
450 [System.Security.SecurityCritical] // auto-generated
451 [ResourceExposure(ResourceScope.None)]
452 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
453 internal static CspParameters SaveCspParameters (CspAlgorithmType keyType, CspParameters userParameters, CspProviderFlags defaultFlags, ref bool randomKeyContainer) {
455 CspParameters parameters;
456 if (userParameters == null) {
457 parameters = new CspParameters(keyType == CspAlgorithmType.Dss ? Constants.PROV_DSS_DH : DefaultRsaProviderType, null, null, defaultFlags);
459 ValidateCspFlags(userParameters.Flags);
460 parameters = new CspParameters(userParameters);
463 if (parameters.KeyNumber == -1)
464 parameters.KeyNumber = keyType == CspAlgorithmType.Dss ? Constants.AT_SIGNATURE : Constants.AT_KEYEXCHANGE;
465 else if (parameters.KeyNumber == Constants.CALG_DSS_SIGN || parameters.KeyNumber == Constants.CALG_RSA_SIGN)
466 parameters.KeyNumber = Constants.AT_SIGNATURE;
467 else if (parameters.KeyNumber == Constants.CALG_RSA_KEYX)
468 parameters.KeyNumber = Constants.AT_KEYEXCHANGE;
470 // If no key container was specified and UseDefaultKeyContainer is not used, then use CRYPT_VERIFYCONTEXT
471 // to generate an ephemeral key
472 randomKeyContainer = (parameters.Flags & CspProviderFlags.CreateEphemeralKey) == CspProviderFlags.CreateEphemeralKey;
473 if (parameters.KeyContainerName == null && (parameters.Flags & CspProviderFlags.UseDefaultKeyContainer) == 0) {
474 parameters.Flags |= CspProviderFlags.CreateEphemeralKey;
475 randomKeyContainer = true;
481 [System.Security.SecurityCritical] // auto-generated
482 private static void ValidateCspFlags (CspProviderFlags flags) {
483 // check that the flags are consistent.
484 if ((flags & CspProviderFlags.UseExistingKey) != 0) {
485 CspProviderFlags keyFlags = (CspProviderFlags.UseNonExportableKey | CspProviderFlags.UseArchivableKey | CspProviderFlags.UseUserProtectedKey);
486 if ((flags & keyFlags) != CspProviderFlags.NoFlags)
487 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"));
490 // make sure we are allowed to display the key protection UI if a user protected key is requested.
491 if ((flags & CspProviderFlags.UseUserProtectedKey) != 0) {
492 // UI only allowed in interactive session.
493 if (!System.Environment.UserInteractive)
494 throw new InvalidOperationException(Environment.GetResourceString("Cryptography_NotInteractive"));
496 // we need to demand UI permission here.
497 UIPermission uiPermission = new UIPermission(UIPermissionWindow.SafeTopLevelWindows);
498 uiPermission.Demand();
501 #endif // FEATURE_CRYPTO
504 private static volatile RNGCryptoServiceProvider _rng;
505 internal static RNGCryptoServiceProvider StaticRandomNumberGenerator {
508 _rng = new RNGCryptoServiceProvider();
514 // internal static methods
517 internal static byte[] GenerateRandom (int keySize) {
518 byte[] key = new byte[keySize];
519 StaticRandomNumberGenerator.GetBytes(key);
525 /// Read the FIPS policy from the pre-Vista registry key
528 /// True if the FIPS policy is enabled, false otherwise. An error reading the policy key is
529 /// interpreted as if the policy is enabled, and a missing key is interpreted as the policy being
532 [System.Security.SecurityCritical] // auto-generated
533 [RegistryPermissionAttribute(SecurityAction.Assert, Read="HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Lsa")]
534 internal static bool ReadLegacyFipsPolicy()
536 Contract.Assert(Environment.OSVersion.Version.Major < 6, "CryptGetFIPSAlgorithmMode should be used on Vista+");
540 using (RegistryKey fipsAlgorithmPolicyKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Lsa", false))
542 if (fipsAlgorithmPolicyKey == null)
545 object data = fipsAlgorithmPolicyKey.GetValue("FIPSAlgorithmPolicy");
551 else if (fipsAlgorithmPolicyKey.GetValueKind("FIPSAlgorithmPolicy") != RegistryValueKind.DWord)
557 return ((int)data != 0);
561 catch (SecurityException)
563 // If we could not open the registry key, we'll assume the setting is to enforce FIPS policy.
567 #endif //FEATURE_CRYPTO
569 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
570 // dwKeySize = 0 means the default key size
571 [System.Security.SecurityCritical] // auto-generated
572 internal static bool HasAlgorithm (int dwCalg, int dwKeySize) {
577 // We need to take a lock here since we are querying the provider handle in a loop.
578 // If multiple threads are racing in this code, not all algorithms/key sizes combinations
579 // will be examined; which may lead to a situation where false is wrongfully returned.
580 lock (InternalSyncObject) {
581 r = SearchForAlgorithm(StaticProvHandle, dwCalg, dwKeySize);
587 internal static int ObjToAlgId(object hashAlg, OidGroup group) {
589 throw new ArgumentNullException("hashAlg");
590 Contract.EndContractBlock();
592 string oidValue = null;
593 string hashAlgString = hashAlg as string;
594 if (hashAlgString != null) {
595 oidValue = CryptoConfig.MapNameToOID(hashAlgString, group);
596 if (oidValue == null)
597 oidValue = hashAlgString; // maybe we were passed the OID value
599 else if (hashAlg is HashAlgorithm) {
600 oidValue = CryptoConfig.MapNameToOID(hashAlg.GetType().ToString(), group);
602 else if (hashAlg is Type) {
603 oidValue = CryptoConfig.MapNameToOID(hashAlg.ToString(), group);
606 if (oidValue == null)
607 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
609 return X509Utils.GetAlgIdFromOid(oidValue, group);
612 internal static HashAlgorithm ObjToHashAlgorithm (Object hashAlg) {
614 throw new ArgumentNullException("hashAlg");
615 Contract.EndContractBlock();
617 HashAlgorithm hash = null;
618 if (hashAlg is String) {
619 hash = (HashAlgorithm) CryptoConfig.CreateFromName((string) hashAlg);
621 string oidFriendlyName = X509Utils.GetFriendlyNameFromOid((string) hashAlg, OidGroup.HashAlgorithm);
622 if (oidFriendlyName != null)
623 hash = (HashAlgorithm) CryptoConfig.CreateFromName(oidFriendlyName);
626 else if (hashAlg is HashAlgorithm) {
627 hash = (HashAlgorithm) hashAlg;
629 else if (hashAlg is Type) {
630 hash = (HashAlgorithm) CryptoConfig.CreateFromName(hashAlg.ToString());
634 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
639 internal static String DiscardWhiteSpaces (string inputBuffer) {
640 return DiscardWhiteSpaces(inputBuffer, 0, inputBuffer.Length);
643 internal static String DiscardWhiteSpaces (string inputBuffer, int inputOffset, int inputCount) {
645 for (i=0; i<inputCount; i++)
646 if (Char.IsWhiteSpace(inputBuffer[inputOffset + i])) iCount++;
647 char[] output = new char[inputCount - iCount];
649 for (i=0; i<inputCount; i++) {
650 if (!Char.IsWhiteSpace(inputBuffer[inputOffset + i]))
651 output[iCount++] = inputBuffer[inputOffset + i];
653 return new String(output);
656 internal static int ConvertByteArrayToInt (byte[] input) {
657 // Input to this routine is always big endian
659 for (int i = 0; i < input.Length; i++) {
661 dwOutput += input[i];
666 // output of this routine is always big endian
667 internal static byte[] ConvertIntToByteArray (int dwInput) {
668 byte[] temp = new byte[8]; // int can never be greater than Int64
669 int t1; // t1 is remaining value to account for
670 int t2; // t2 is t1 % 256
673 if (dwInput == 0) return new byte[1];
676 Contract.Assert(i < 8, "Got too big an int here!");
683 // Now, copy only the non-zero part of temp and reverse
684 byte[] output = new byte[i];
685 // copy and reverse in one pass
686 for (int j = 0; j < i; j++) {
687 output[j] = temp[i-j-1];
692 // output is little endian
693 internal static void ConvertIntToByteArray (uint dwInput, ref byte[] counter) {
694 uint t1 = dwInput; // t1 is remaining value to account for
695 uint t2; // t2 is t1 % 256
698 // clear the array first
699 Array.Clear(counter, 0, counter.Length);
700 if (dwInput == 0) return;
702 Contract.Assert(i < 4, "Got too big an int here!");
704 counter[3 - i] = (byte) t2;
710 internal static byte[] FixupKeyParity (byte[] key) {
711 byte[] oddParityKey = new byte[key.Length];
712 for (int index=0; index < key.Length; index++) {
713 // Get the bits we are interested in
714 oddParityKey[index] = (byte) (key[index] & 0xfe);
715 // Get the parity of the sum of the previous bits
716 byte tmp1 = (byte)((oddParityKey[index] & 0xF) ^ (oddParityKey[index] >> 4));
717 byte tmp2 = (byte)((tmp1 & 0x3) ^ (tmp1 >> 2));
718 byte sumBitsMod2 = (byte)((tmp2 & 0x1) ^ (tmp2 >> 1));
719 // We need to set the last bit in oddParityKey[index] to the negation
720 // of the last bit in sumBitsMod2
721 if (sumBitsMod2 == 0)
722 oddParityKey[index] |= 1;
727 // digits == number of DWORDs
728 [System.Security.SecurityCritical] // auto-generated
729 internal unsafe static void DWORDFromLittleEndian (uint* x, int digits, byte* block) {
733 for (i = 0, j = 0; i < digits; i++, j += 4)
734 x[i] = (uint) (block[j] | (block[j+1] << 8) | (block[j+2] << 16) | (block[j+3] << 24));
737 // encodes x (DWORD) into block (unsigned char), least significant byte first.
738 // digits == number of DWORDs
739 internal static void DWORDToLittleEndian (byte[] block, uint[] x, int digits) {
743 for (i = 0, j = 0; i < digits; i++, j += 4) {
744 block[j] = (byte)(x[i] & 0xff);
745 block[j+1] = (byte)((x[i] >> 8) & 0xff);
746 block[j+2] = (byte)((x[i] >> 16) & 0xff);
747 block[j+3] = (byte)((x[i] >> 24) & 0xff);
750 #endif // FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
752 // digits == number of DWORDs
753 [System.Security.SecurityCritical] // auto-generated
754 internal unsafe static void DWORDFromBigEndian (uint* x, int digits, byte* block) {
758 for (i = 0, j = 0; i < digits; i++, j += 4)
759 x[i] = (uint)((block[j] << 24) | (block[j + 1] << 16) | (block[j + 2] << 8) | block[j + 3]);
762 // encodes x (DWORD) into block (unsigned char), most significant byte first.
763 // digits == number of DWORDs
764 internal static void DWORDToBigEndian (byte[] block, uint[] x, int digits) {
768 for (i = 0, j = 0; i < digits; i++, j += 4) {
769 block[j] = (byte)((x[i] >> 24) & 0xff);
770 block[j+1] = (byte)((x[i] >> 16) & 0xff);
771 block[j+2] = (byte)((x[i] >> 8) & 0xff);
772 block[j+3] = (byte)(x[i] & 0xff);
776 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
777 // digits == number of QWORDs
778 [System.Security.SecurityCritical] // auto-generated
779 internal unsafe static void QuadWordFromBigEndian (UInt64* x, int digits, byte* block) {
783 for (i = 0, j = 0; i < digits; i++, j += 8)
785 (((UInt64)block[j]) << 56) | (((UInt64)block[j+1]) << 48) |
786 (((UInt64)block[j+2]) << 40) | (((UInt64)block[j+3]) << 32) |
787 (((UInt64)block[j+4]) << 24) | (((UInt64)block[j+5]) << 16) |
788 (((UInt64)block[j+6]) << 8) | ((UInt64)block[j+7])
792 // encodes x (DWORD) into block (unsigned char), most significant byte first.
793 // digits = number of QWORDS
794 internal static void QuadWordToBigEndian (byte[] block, UInt64[] x, int digits) {
798 for (i = 0, j = 0; i < digits; i++, j += 8) {
799 block[j] = (byte)((x[i] >> 56) & 0xff);
800 block[j+1] = (byte)((x[i] >> 48) & 0xff);
801 block[j+2] = (byte)((x[i] >> 40) & 0xff);
802 block[j+3] = (byte)((x[i] >> 32) & 0xff);
803 block[j+4] = (byte)((x[i] >> 24) & 0xff);
804 block[j+5] = (byte)((x[i] >> 16) & 0xff);
805 block[j+6] = (byte)((x[i] >> 8) & 0xff);
806 block[j+7] = (byte)(x[i] & 0xff);
809 #endif // FEATURE_CRYPTO
811 // encodes the integer i into a 4-byte array, in big endian.
812 internal static byte[] Int(uint i) {
813 return unchecked(new byte[] { (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i });
816 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
817 [System.Security.SecurityCritical] // auto-generated
818 internal static byte[] RsaOaepEncrypt (RSA rsa, HashAlgorithm hash, PKCS1MaskGenerationMethod mgf, RandomNumberGenerator rng, byte[] data) {
820 // It looks like .net managed implementation is buggy. It returns quite different
821 // result compare to old mono code, even PSLength calculation is quite different
822 return Mono.Security.Cryptography.PKCS1.Encrypt_OAEP (rsa, hash, rng, data);
824 int cb = rsa.KeySize / 8;
826 // 1. Hash the parameters to get PHash
827 int cbHash = hash.HashSize / 8;
828 if ((data.Length + 2 + 2*cbHash) > cb)
829 throw new CryptographicException(String.Format(null, Environment.GetResourceString("Cryptography_Padding_EncDataTooBig"), cb-2-2*cbHash));
830 hash.ComputeHash(EmptyArray<Byte>.Value); // Use an empty octet string
832 // 2. Create DB object
833 byte[] DB = new byte[cb - cbHash + 1];
835 // Structure is as follows:
836 // pHash || PS || 01 || M
837 // PS consists of all zeros
839 Buffer.InternalBlockCopy(hash.Hash, 0, DB, 0, cbHash);
840 DB[DB.Length - data.Length - 1] = 1;
841 Buffer.InternalBlockCopy(data, 0, DB, DB.Length-data.Length, data.Length);
843 // 3. Create a random value of size hLen
844 byte[] seed = new byte[cbHash];
847 // 4. Compute the mask value
848 byte[] mask = mgf.GenerateMask(seed, DB.Length);
850 // 5. Xor maskDB into DB
851 for (int i=0; i < DB.Length; i++) {
852 DB[i] = (byte) (DB[i] ^ mask[i]);
855 // 6. Compute seed mask value
856 mask = mgf.GenerateMask(DB, cbHash);
858 // 7. Xor mask into seed
859 for (int i=0; i < seed.Length; i++) {
863 // 8. Concatenate seed and DB to form value to encrypt
864 byte[] pad = new byte[cb];
865 Buffer.InternalBlockCopy(seed, 0, pad, 0, seed.Length);
866 Buffer.InternalBlockCopy(DB, 0, pad, seed.Length, DB.Length);
868 return rsa.EncryptValue(pad);
872 [System.Security.SecurityCritical] // auto-generated
873 internal static byte[] RsaOaepDecrypt (RSA rsa, HashAlgorithm hash, PKCS1MaskGenerationMethod mgf, byte[] encryptedData) {
875 var result = Mono.Security.Cryptography.PKCS1.Decrypt_OAEP (rsa, hash, encryptedData);
877 throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
880 int cb = rsa.KeySize / 8;
882 // 1. Decode the input data
883 // It is important that the Integer to Octet String conversion errors be indistinguishable from the other decoding
884 // errors to protect against chosen cipher text attacks
885 // A lecture given by James Manger during Crypto 2001 explains the issue in details
888 data = rsa.DecryptValue(encryptedData);
890 catch (CryptographicException) {
891 throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
894 // 2. Create the hash object so we can get its size info.
895 int cbHash = hash.HashSize / 8;
897 // 3. Let maskedSeed be the first hLen octects and maskedDB
898 // be the remaining bytes.
899 int zeros = cb - data.Length;
900 if (zeros < 0 || zeros >= cbHash)
901 throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
903 const int leading_zeros = 0;
904 byte[] seed = new byte[cbHash];
905 Buffer.InternalBlockCopy(data, leading_zeros, seed, zeros, seed.Length - zeros);
907 byte[] DB = new byte[data.Length - seed.Length + zeros - leading_zeros];
908 Buffer.InternalBlockCopy(data, seed.Length - zeros + leading_zeros, DB, 0, DB.Length);
910 // 4. seedMask = MGF(maskedDB, hLen);
911 byte[] mask = mgf.GenerateMask(DB, seed.Length);
913 // 5. seed = seedMask XOR maskedSeed
915 for (i=0; i < seed.Length; i++) {
919 // 6. dbMask = MGF(seed, |EM| - hLen);
920 mask = mgf.GenerateMask(seed, DB.Length);
922 // 7. DB = maskedDB xor dbMask
923 for (i=0; i < DB.Length; i++) {
924 DB[i] = (byte) (DB[i] ^ mask[i]);
927 // 8. pHash = HASH(P)
928 hash.ComputeHash(EmptyArray<Byte>.Value);
930 // 9. DB = pHash' || PS || 01 || M
931 // 10. Check that pHash = pHash'
933 byte[] hashValue = hash.Hash;
934 for (i=0; i < cbHash; i++) {
935 if (DB[i] != hashValue[i])
936 throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
939 // Check that PS is all zeros
940 for (; i<DB.Length; i++) {
944 throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
948 throw new CryptographicException(Environment.GetResourceString("Cryptography_OAEPDecoding"));
950 i++; // skip over the one
953 byte[] output = new byte[DB.Length - i];
954 Buffer.InternalBlockCopy(DB, i, output, 0, output.Length);
959 [System.Security.SecurityCritical] // auto-generated
960 internal static byte[] RsaPkcs1Padding (RSA rsa, byte[] oid, byte[] hash) {
961 int cb = rsa.KeySize/8;
962 byte[] pad = new byte[cb];
965 // We want to pad this to the following format:
967 // 00 || 01 || FF ... FF || 00 || prefix || Data
969 // We want basically to ASN 1 encode the OID + hash:
972 // OID <hash algorithm OID>
973 // NULL (0x05 0x00) // this is actually an ANY and contains the parameters of the algorithm specified by the OID, I think
975 // OCTET STRING <hashvalue>
979 // Get the correct prefix
980 byte[] data = new byte[oid.Length + 8 + hash.Length];
981 data[0] = 0x30; // a structure follows
982 int tmp = data.Length - 2;
983 data[1] = (byte) tmp;
985 tmp = oid.Length + 2;
986 data[3] = (byte) tmp;
987 Buffer.InternalBlockCopy(oid, 0, data, 4, oid.Length);
988 data[4 + oid.Length] = 0x05;
989 data[4 + oid.Length + 1] = 0x00;
990 data[4 + oid.Length + 2] = 0x04; // an octet string follows
991 data[4 + oid.Length + 3] = (byte) hash.Length;
992 Buffer.InternalBlockCopy(hash, 0, data, oid.Length + 8, hash.Length);
994 // Construct the whole array
995 int cb1 = cb - data.Length;
997 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_InvalidOID"));
1001 for (int i=2; i<cb1-1; i++) {
1005 Buffer.InternalBlockCopy(data, 0, pad, cb1, data.Length);
1009 // This routine compares 2 big ints; ignoring any leading zeros
1010 internal static bool CompareBigIntArrays (byte[] lhs, byte[] rhs) {
1012 return (rhs == null);
1015 while (i < lhs.Length && lhs[i] == 0) i++;
1016 while (j < rhs.Length && rhs[j] == 0) j++;
1018 int count = (lhs.Length - i);
1019 if ((rhs.Length - j) != count)
1022 for (int k = 0; k < count; k++) {
1023 if (lhs[i + k] != rhs[j + k])
1029 [System.Security.SecurityCritical] // auto-generated
1030 [ResourceExposure(ResourceScope.None)] // Creates a process resource, but it can't be scoped.
1031 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1032 internal static extern SafeHashHandle CreateHash(SafeProvHandle hProv, int algid);
1034 internal static HashAlgorithmName OidToHashAlgorithmName(string oid)
1038 case Constants.OID_OIWSEC_SHA1:
1039 return HashAlgorithmName.SHA1;
1041 case Constants.OID_OIWSEC_SHA256:
1042 return HashAlgorithmName.SHA256;
1044 case Constants.OID_OIWSEC_SHA384:
1045 return HashAlgorithmName.SHA384;
1047 case Constants.OID_OIWSEC_SHA512:
1048 return HashAlgorithmName.SHA512;
1051 throw new NotSupportedException();
1056 // Backward-compat hack for third-party RSA-derived classes:
1058 // Because the SignHash()/VerifyHash()/Encrypt()/Decrypt() methods are new on RSA, we may
1059 // encounter older third-party RSA-derived classes that don't override them
1060 // (and if they don't override them, these methods will throw since they are effectively abstract methods that had to declared non-abstract
1061 // for backward compat reasons.)
1063 internal static bool DoesRsaKeyOverride(RSA rsaKey, string methodName, Type[] parameterTypes)
1065 // A fast-path check for the common cases where we know we implemented the overrides.
1066 Type t = rsaKey.GetType();
1067 if (rsaKey is RSACryptoServiceProvider)
1070 // On checked builds, do the slow-path check anyway so it gets exercised.
1071 bool foundOverride = DoesRsaKeyOverrideSlowPath(t, methodName, parameterTypes);
1072 BCLDebug.Assert(foundOverride, "RSACryptoServiceProvider expected to override " + methodName);
1077 string fullName = t.FullName;
1078 if (fullName == "System.Security.Cryptography.RSACng")
1081 // On checked builds, do the slow-path check anyway so it gets exercised.
1082 bool foundOverride = DoesRsaKeyOverrideSlowPath(t, methodName, parameterTypes);
1083 BCLDebug.Assert(foundOverride, "RSACng expected to override " + methodName);
1087 return DoesRsaKeyOverrideSlowPath(t, methodName, parameterTypes);
1090 private static bool DoesRsaKeyOverrideSlowPath(Type t, string methodName, Type[] parameterTypes)
1092 MethodInfo method = t.GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance, null, parameterTypes, null);
1093 BCLDebug.Assert(method != null, "method != null");
1094 Type declaringType = method.DeclaringType;
1095 if (declaringType == typeof(RSA))
1101 [System.Security.SecurityCritical] // auto-generated
1102 [ResourceExposure(ResourceScope.None)]
1103 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1104 private static extern void EndHash(SafeHashHandle hHash, ObjectHandleOnStack retHash);
1106 [System.Security.SecurityCritical] // auto-generated
1107 internal static byte[] EndHash(SafeHashHandle hHash)
1110 EndHash(hHash, JitHelpers.GetObjectHandleOnStack(ref hash));
1114 [System.Security.SecurityCritical] // auto-generated
1115 [ResourceExposure(ResourceScope.None)]
1116 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1117 private static extern void ExportCspBlob(SafeKeyHandle hKey, int blobType, ObjectHandleOnStack retBlob);
1119 [System.Security.SecurityCritical] // auto-generated
1120 [ResourceExposure(ResourceScope.None)]
1121 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1122 internal static extern bool GetPersistKeyInCsp(SafeProvHandle hProv);
1124 [System.Security.SecurityCritical] // auto-generated
1125 [ResourceExposure(ResourceScope.None)]
1126 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1127 private static extern void HashData(SafeHashHandle hHash, byte[] data, int cbData, int ibStart, int cbSize);
1129 [System.Security.SecurityCritical] // auto-generated
1130 internal static void HashData(SafeHashHandle hHash, byte[] data, int ibStart, int cbSize)
1132 HashData(hHash, data, data.Length, ibStart, cbSize);
1135 [System.Security.SecurityCritical] // auto-generated
1136 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1137 [ResourceExposure(ResourceScope.None)]
1138 private static extern bool SearchForAlgorithm(SafeProvHandle hProv, int algID, int keyLength);
1140 [System.Security.SecurityCritical] // auto-generated
1141 [ResourceExposure(ResourceScope.None)]
1142 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1143 internal static extern void SetKeyParamDw(SafeKeyHandle hKey, int param, int dwValue);
1145 [System.Security.SecurityCritical] // auto-generated
1146 [ResourceExposure(ResourceScope.None)]
1147 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1148 internal static extern void SetKeyParamRgb(SafeKeyHandle hKey, int param, byte[] value, int cbValue);
1151 [System.Security.SecurityCritical] // auto-generated
1152 [ResourceExposure(ResourceScope.None)]
1153 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1154 private static extern int SetKeySetSecurityInfo(SafeProvHandle hProv, SecurityInfos securityInfo, byte[] sd);
1155 #endif //FEATURE_MACL
1156 [System.Security.SecurityCritical] // auto-generated
1157 [ResourceExposure(ResourceScope.None)]
1158 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1159 internal static extern void SetPersistKeyInCsp(SafeProvHandle hProv, bool fPersistKeyInCsp);
1161 [System.Security.SecurityCritical] // auto-generated
1162 [ResourceExposure(ResourceScope.None)]
1163 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1164 internal static extern void SetProviderParameter(SafeProvHandle hProv, int keyNumber, uint paramID, IntPtr pbData);
1166 [System.Security.SecurityCritical] // auto-generated
1167 [ResourceExposure(ResourceScope.None)]
1168 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1169 private static extern void SignValue(SafeKeyHandle hKey, int keyNumber, int calgKey, int calgHash, byte[] hash, int cbHash, ObjectHandleOnStack retSignature);
1171 [System.Security.SecurityCritical] // auto-generated
1172 internal static byte[] SignValue(SafeKeyHandle hKey, int keyNumber, int calgKey, int calgHash, byte[] hash)
1174 byte[] signature = null;
1175 SignValue(hKey, keyNumber, calgKey, calgHash, hash, hash.Length, JitHelpers.GetObjectHandleOnStack(ref signature));
1179 [System.Security.SecurityCritical] // auto-generated
1180 [ResourceExposure(ResourceScope.None)]
1181 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
1182 private static extern bool VerifySign(SafeKeyHandle hKey, int calgKey, int calgHash, byte[] hash, int cbHash, byte[] signature, int cbSignature);
1184 [System.Security.SecurityCritical] // auto-generated
1185 internal static bool VerifySign(SafeKeyHandle hKey, int calgKey, int calgHash, byte[] hash, byte[] signature)
1187 return VerifySign(hKey, calgKey, calgHash, hash, hash.Length, signature, signature.Length);
1190 [System.Security.SecurityCritical] // auto-generated
1191 [ResourceExposure(ResourceScope.Machine)]
1192 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1193 internal static extern void _CreateCSP(CspParameters param, bool randomKeyContainer, ref SafeProvHandle hProv);
1194 [System.Security.SecurityCritical] // auto-generated
1195 [ResourceExposure(ResourceScope.None)]
1196 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1197 internal static extern int _DecryptData(SafeKeyHandle hKey, byte[] data, int ib, int cb, ref byte[] outputBuffer, int outputOffset, PaddingMode PaddingMode, bool fDone);
1198 [System.Security.SecurityCritical] // auto-generated
1199 [ResourceExposure(ResourceScope.None)]
1200 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1201 internal static extern int _EncryptData(SafeKeyHandle hKey, byte[] data, int ib, int cb, ref byte[] outputBuffer, int outputOffset, PaddingMode PaddingMode, bool fDone);
1202 [System.Security.SecurityCritical] // auto-generated
1203 [ResourceExposure(ResourceScope.None)]
1204 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1205 internal static extern void _ExportKey(SafeKeyHandle hKey, int blobType, object cspObject);
1206 [System.Security.SecurityCritical] // auto-generated
1207 [ResourceExposure(ResourceScope.None)]
1208 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1209 internal static extern void _GenerateKey(SafeProvHandle hProv, int algid, CspProviderFlags flags, int keySize, ref SafeKeyHandle hKey);
1211 #endif // FEATURE_CRYPTO
1213 [System.Security.SecurityCritical] // auto-generated
1214 [ResourceExposure(ResourceScope.None)]
1215 [MethodImpl(MethodImplOptions.InternalCall)]
1216 internal static extern bool _GetEnforceFipsPolicySetting();
1217 #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
1218 [System.Security.SecurityCritical] // auto-generated
1219 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1220 internal static extern byte[] _GetKeyParameter(SafeKeyHandle hKey, uint paramID);
1222 [System.Security.SecurityCritical] // auto-generated
1223 [ResourceExposure(ResourceScope.None)]
1224 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1225 internal static extern byte[] _GetKeySetSecurityInfo(SafeProvHandle hProv, SecurityInfos securityInfo, out int error);
1226 #endif //FEATURE_MACL
1227 [System.Security.SecurityCritical] // auto-generated
1228 [ResourceExposure(ResourceScope.None)]
1229 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1230 internal static extern object _GetProviderParameter(SafeProvHandle hProv, int keyNumber, uint paramID);
1231 [System.Security.SecurityCritical] // auto-generated
1232 [ResourceExposure(ResourceScope.None)]
1233 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1234 internal static extern int _GetUserKey(SafeProvHandle hProv, int keyNumber, ref SafeKeyHandle hKey);
1235 [System.Security.SecurityCritical] // auto-generated
1236 [ResourceExposure(ResourceScope.None)]
1237 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1238 internal static extern void _ImportBulkKey(SafeProvHandle hProv, int algid, bool useSalt, byte[] key, ref SafeKeyHandle hKey);
1239 [System.Security.SecurityCritical] // auto-generated
1240 [ResourceExposure(ResourceScope.None)]
1241 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1242 internal static extern int _ImportCspBlob(byte[] keyBlob, SafeProvHandle hProv, CspProviderFlags flags, ref SafeKeyHandle hKey);
1243 [System.Security.SecurityCritical] // auto-generated
1244 [ResourceExposure(ResourceScope.None)]
1245 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1246 internal static extern void _ImportKey(SafeProvHandle hCSP, int keyNumber, CspProviderFlags flags, object cspObject, ref SafeKeyHandle hKey);
1247 [System.Security.SecurityCritical] // auto-generated
1248 [ResourceExposure(ResourceScope.None)]
1249 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1250 internal static extern bool _ProduceLegacyHmacValues();
1251 #endif // FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO
1252 [System.Security.SecurityCritical] // auto-generated
1253 [ResourceExposure(ResourceScope.Machine)]
1254 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1255 internal static extern int _OpenCSP(CspParameters param, uint flags, ref SafeProvHandle hProv);
1256 [System.Security.SecurityCritical] // auto-generated
1257 [ResourceExposure(ResourceScope.Machine)]
1258 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1259 internal static extern void _AcquireCSP(CspParameters param, ref SafeProvHandle hProv);
1262 internal static bool _ProduceLegacyHmacValues()
1264 #if FULL_AOT_RUNTIME
1267 return Environment.GetEnvironmentVariable ("legacyHMACMode") == "1";