11 if (!name.HasValue ||
string.IsNullOrEmpty(name.Value.Name))
13 return global::Interop.BCrypt.ECC_CURVE_ALG_ID_ENUM.BCRYPT_NO_CURVE_GENERATION_ALG_ID;
15 global::Interop.Crypt32.CRYPT_OID_INFO cRYPT_OID_INFO = global::Interop.Crypt32.FindOidInfo(global::Interop.Crypt32.CryptOidInfoKeyType.CRYPT_OID_INFO_NAME_KEY, name.Value.Name,
OidGroup.HashAlgorithm, fallBackToAllGroups:
false);
16 if (cRYPT_OID_INFO.AlgId == -1)
20 return (global::Interop.BCrypt.ECC_CURVE_ALG_ID_ENUM)cRYPT_OID_INFO.AlgId;
25 global::Interop.Crypt32.CRYPT_OID_INFO cRYPT_OID_INFO = global::Interop.Crypt32.FindAlgIdOidInfo(hashId);
26 if (cRYPT_OID_INFO.AlgId == -1)
35 if (!(algorithm ==
"ECDH"))
37 return algorithm ==
"ECDSA";
48 oidValue =
"1.2.840.10045.3.1.7";
52 oidValue =
"1.3.132.0.34";
56 oidValue =
"1.3.132.0.35";
65 bool flag = parameters.D !=
null;
66 int num =
sizeof(global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB) + parameters.Q.X.Length + parameters.Q.Y.Length;
69 num += parameters.D.Length;
71 byte[]
array =
new byte[num];
72 fixed (
byte* ptr = &
array[0])
74 global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB* ptr2 = (global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB*)ptr;
76 ptr2->cbKey = parameters.Q.X.Length;
77 int offset =
sizeof(global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB);
78 global::Interop.BCrypt.Emit(
array, ref
offset, parameters.Q.X);
79 global::Interop.BCrypt.Emit(
array, ref
offset, parameters.Q.Y);
82 global::Interop.BCrypt.Emit(
array, ref
offset, parameters.D);
90 bool flag = parameters.D !=
null;
91 ECCurve curve = parameters.Curve;
92 int num =
sizeof(global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB) + curve.
Prime.Length + curve.
A.Length + curve.
B.Length + curve.
G.
X.Length + curve.
G.
Y.Length + curve.
Order.Length + curve.
Cofactor.Length + ((curve.
Seed !=
null) ? curve.Seed.Length : 0) + parameters.Q.X.Length + parameters.Q.Y.Length;
95 num += parameters.D.Length;
97 byte[]
array =
new byte[num];
98 fixed (
byte* ptr = &
array[0])
100 global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB* ptr2 = (global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB*)ptr;
102 ptr2->Magic = ((!flag) ? (ecdh ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC) : (ecdh ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC));
103 ptr2->cbCofactor = curve.
Cofactor.Length;
104 ptr2->cbFieldLength = parameters.Q.X.Length;
105 ptr2->cbSeed = ((curve.Seed !=
null) ? curve.
Seed.Length : 0);
106 ptr2->cbSubgroupOrder = curve.
Order.Length;
109 int offset =
sizeof(global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB);
111 global::Interop.BCrypt.Emit(
array, ref
offset, curve.
A);
112 global::Interop.BCrypt.Emit(
array, ref
offset, curve.
B);
117 if (curve.
Seed !=
null)
121 global::Interop.BCrypt.Emit(
array, ref
offset, parameters.Q.X);
122 global::Interop.BCrypt.Emit(
array, ref
offset, parameters.Q.Y);
125 global::Interop.BCrypt.Emit(
array, ref
offset, parameters.D);
133 global::Interop.BCrypt.KeyBlobMagicNumber magic = (global::Interop.BCrypt.KeyBlobMagicNumber)
BitConverter.
ToInt32(ecBlob, 0);
135 if (ecBlob.Length <
sizeof(global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB))
137 throw global::Interop.NCrypt.ErrorCode.E_FAIL.ToCryptographicException();
139 fixed (
byte* ptr = &ecBlob[0])
141 global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB* ptr2 = (global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB*)ptr;
142 int offset =
sizeof(global::Interop.BCrypt.BCRYPT_ECCKEY_BLOB);
145 X = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbKey),
146 Y = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbKey)
148 if (includePrivateParameters)
150 ecParams.D = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbKey);
157 global::Interop.BCrypt.KeyBlobMagicNumber magic = (global::Interop.BCrypt.KeyBlobMagicNumber)
BitConverter.
ToInt32(ecBlob, 0);
159 if (ecBlob.Length <
sizeof(global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB))
161 throw global::Interop.NCrypt.ErrorCode.E_FAIL.ToCryptographicException();
163 fixed (
byte* ptr = &ecBlob[0])
165 global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB* ptr2 = (global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB*)ptr;
169 int offset =
sizeof(global::Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB);
170 curve.Prime = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbFieldLength);
171 curve.A = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbFieldLength);
172 curve.B = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbFieldLength);
175 X = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbFieldLength),
176 Y = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbFieldLength)
178 curve.Order = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbSubgroupOrder);
179 curve.Cofactor = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbCofactor);
180 curve.Seed = ((ptr2->cbSeed == 0) ?
null : global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbSeed));
183 X = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbFieldLength),
184 Y = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbFieldLength)
186 if (includePrivateParameters)
188 ecParams.D = global::Interop.BCrypt.Consume(ecBlob, ref
offset, ptr2->cbSubgroupOrder);
190 ecParams.Curve = curve;
196 int num =
sizeof(global::Interop.BCrypt.BCRYPT_ECC_PARAMETER_HEADER) + curve.Prime.Length + curve.A.Length + curve.B.Length + curve.G.X.Length + curve.G.Y.Length + curve.Order.Length + curve.Cofactor.Length + ((curve.Seed !=
null) ? curve.Seed.Length : 0);
197 byte[]
array =
new byte[num];
198 fixed (
byte* ptr = &
array[0])
200 global::Interop.BCrypt.BCRYPT_ECC_PARAMETER_HEADER* ptr2 = (global::Interop.BCrypt.BCRYPT_ECC_PARAMETER_HEADER*)ptr;
202 ptr2->cbCofactor = curve.Cofactor.Length;
203 ptr2->cbFieldLength = curve.A.Length;
204 ptr2->cbSeed = ((curve.Seed !=
null) ? curve.Seed.Length : 0);
205 ptr2->cbSubgroupOrder = curve.Order.Length;
208 int offset =
sizeof(global::Interop.BCrypt.BCRYPT_ECC_PARAMETER_HEADER);
209 global::Interop.BCrypt.Emit(
array, ref
offset, curve.Prime);
210 global::Interop.BCrypt.Emit(
array, ref
offset, curve.A);
211 global::Interop.BCrypt.Emit(
array, ref
offset, curve.B);
212 global::Interop.BCrypt.Emit(
array, ref
offset, curve.G.X);
213 global::Interop.BCrypt.Emit(
array, ref
offset, curve.G.Y);
214 global::Interop.BCrypt.Emit(
array, ref
offset, curve.Order);
215 global::Interop.BCrypt.Emit(
array, ref
offset, curve.Cofactor);
216 if (curve.Seed !=
null)
218 global::Interop.BCrypt.Emit(
array, ref
offset, curve.Seed);
224 private static void CheckMagicValueOfKey(global::Interop.BCrypt.KeyBlobMagicNumber magic,
bool includePrivateParameters)
226 if (includePrivateParameters)
243 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P256_MAGIC:
244 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P256_MAGIC:
245 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P384_MAGIC:
246 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P384_MAGIC:
247 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P521_MAGIC:
248 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P521_MAGIC:
249 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC:
250 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC:
261 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P256_MAGIC:
262 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P256_MAGIC:
263 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P384_MAGIC:
264 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P384_MAGIC:
265 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P521_MAGIC:
266 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P521_MAGIC:
267 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC:
268 case global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC:
279 "ECDSA_P256" => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P256_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P256_MAGIC,
280 "ECDSA_P384" => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P384_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P384_MAGIC,
281 "ECDSA_P521" => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P521_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P521_MAGIC,
282 _ => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC,
290 "ECDH_P256" => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P256_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P256_MAGIC,
291 "ECDH_P384" => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P384_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P384_MAGIC,
292 "ECDH_P521" => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P521_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P521_MAGIC,
293 _ => includePrivateParameters ? global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC : global::Interop.BCrypt.KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC,
299 return (global::Interop.BCrypt.ECC_CURVE_TYPE_ENUM)
value;
309 global::Interop.NCrypt.ErrorCode errorCode;
313 global::Interop.BCrypt.BCryptBufferDesc structure =
default(global::Interop.BCrypt.BCryptBufferDesc);
314 global::Interop.BCrypt.BCryptBuffer structure2 =
default(global::Interop.BCrypt.BCryptBuffer);
321 structure2.cbBuffer = (curveName.Length + 1) * 2;
322 structure2.BufferType = global::Interop.BCrypt.CngBufferDescriptors.NCRYPTBUFFER_ECC_CURVE_NAME;
325 structure.cBuffers = 1;
326 structure.pBuffers = intPtr2;
327 structure.ulVersion = 0;
329 errorCode = global::Interop.NCrypt.NCryptImportKey(provider,
IntPtr.
Zero, blobType, intPtr, out phKey, ref
MemoryMarshal.GetReference(keyBlob), keyBlob.
Length, 0);
339 Exception ex = errorCode.ToCryptographicException();
340 if (errorCode == global::Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER)
static int ToInt32(byte[] value, int startIndex)
static void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld)
static void FreeHGlobal(IntPtr hglobal)
static int SizeOf(object structure)
static IntPtr AllocHGlobal(int cb)
IntPtr DangerousGetHandle()
static string Cryptography_NotValidPrivateKey
static string Cryptography_UnknownHashAlgorithm
static string Cryptography_CurveNotSupported
static string Format(string resourceFormat, object p1)
static string Cryptography_NotValidPublicOrPrivateKey
static SafeNCryptKeyHandle ImportKeyBlob(string blobType, ReadOnlySpan< byte > keyBlob, string curveName, SafeNCryptProviderHandle provider)
static string EcdhCurveNameToAlgorithm(string algorithm)
static ? HashAlgorithmName GetHashAlgorithmName(global::Interop.BCrypt.ECC_CURVE_ALG_ID_ENUM hashId)
static global::Interop.BCrypt.KeyBlobMagicNumber EcdsaCurveNameToMagicNumber(string name, bool includePrivateParameters)
static unsafe byte[] GetPrimeCurveParameterBlob(ref ECCurve curve)
static unsafe byte[] GetPrimeCurveBlob(ref ECParameters parameters, bool ecdh)
static unsafe void ExportNamedCurveParameters(ref ECParameters ecParams, byte[] ecBlob, bool includePrivateParameters)
static global::Interop.BCrypt.KeyBlobMagicNumber EcdhCurveNameToMagicNumber(string name, bool includePrivateParameters)
static bool IsMagicValueOfKeyPrivate(global::Interop.BCrypt.KeyBlobMagicNumber magic)
static string EcdsaCurveNameToAlgorithm(string algorithm)
static ECCurve.ECCurveType ConvertToCurveTypeEnum(global::Interop.BCrypt.ECC_CURVE_TYPE_ENUM value)
static global::Interop.BCrypt.ECC_CURVE_ALG_ID_ENUM GetHashAlgorithmId(HashAlgorithmName? name)
static void CheckMagicValueOfKey(global::Interop.BCrypt.KeyBlobMagicNumber magic, bool includePrivateParameters)
static bool IsMagicValueOfKeyPublic(global::Interop.BCrypt.KeyBlobMagicNumber magic)
static unsafe byte[] GetNamedCurveBlob(ref ECParameters parameters, bool ecdh)
static bool IsECNamedCurve(string algorithm)
static global::Interop.BCrypt.ECC_CURVE_TYPE_ENUM ConvertToCurveTypeEnum(ECCurve.ECCurveType value)
static unsafe void ExportPrimeCurveParameters(ref ECParameters ecParams, byte[] ecBlob, bool includePrivateParameters)
static string SpecialNistAlgorithmToCurveName(string algorithm, out string oidValue)
static readonly IntPtr Zero