internal static CngKey Create(ECCurve curve, Func <string, CngAlgorithm> algorithmResolver) { System.Diagnostics.Debug.Assert(algorithmResolver != null); curve.Validate(); CngKeyCreationParameters creationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; CngAlgorithm alg; if (curve.IsNamed) { // Map curve name to algorithm to support pre-Win10 curves alg = algorithmResolver(curve.Oid.FriendlyName); if (CngKey.IsECNamedCurve(alg.Algorithm)) { creationParameters.Parameters.Add(GetPropertyFromNamedCurve(curve)); } else { if (alg == CngAlgorithm.ECDsaP256 || alg == CngAlgorithm.ECDiffieHellmanP256 || alg == CngAlgorithm.ECDsaP384 || alg == CngAlgorithm.ECDiffieHellmanP384 || alg == CngAlgorithm.ECDsaP521 || alg == CngAlgorithm.ECDiffieHellmanP521) { // No parameters required, the algorithm ID has everything built-in. } else { Debug.Fail(string.Format("Unknown algorithm {0}", alg.ToString())); throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidKeySize)); } } } else if (curve.IsPrime) { byte[] parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref curve); CngProperty prop = new CngProperty( KeyPropertyName.ECCParameters, parametersBlob, CngPropertyOptions.None); creationParameters.Parameters.Add(prop); alg = algorithmResolver(null); } else { throw new PlatformNotSupportedException( SR.GetString(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); } try { return(Create(alg, null, creationParameters)); } catch (CryptographicException e) { Interop.NCrypt.ErrorCode errorCode = (Interop.NCrypt.ErrorCode)e.HResult; if (errorCode == Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER || errorCode == Interop.NCrypt.ErrorCode.NTE_NOT_SUPPORTED) { string target = curve.IsNamed ? curve.Oid.FriendlyName : curve.CurveType.ToString(); throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_CurveNotSupported, target), e); } throw; } }