示例#1
0
        internal static unsafe byte[] GetPrimeCurveParameterBlob(ref ECCurve curve)
        {
            // We need to build a key blob structured as follows:
            //     BCRYPT_ECC_PARAMETER_HEADER  header
            //     byte[cbFieldLength]          P
            //     byte[cbFieldLength]          A
            //     byte[cbFieldLength]          B
            //     byte[cbFieldLength]          G.X
            //     byte[cbFieldLength]          G.Y
            //     byte[cbSubgroupOrder]        Order (n)
            //     byte[cbCofactor]             Cofactor (h)
            //     byte[cbSeed]                 Seed

            int blobSize = sizeof(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 ? 0 : curve.Seed.Length);

            byte[] blob = new byte[blobSize];
            fixed(byte *pBlob = &blob[0])
            {
                // Build the header
                BCRYPT_ECC_PARAMETER_HEADER *pBcryptBlob = (BCRYPT_ECC_PARAMETER_HEADER *)pBlob;

                pBcryptBlob->Version              = Interop.BCrypt.BCRYPT_ECC_PARAMETER_HEADER_V1;
                pBcryptBlob->cbCofactor           = curve.Cofactor.Length;
                pBcryptBlob->cbFieldLength        = curve.A.Length; // P, A, B, X, Y have the same length
                pBcryptBlob->cbSeed               = curve.Seed == null ? 0 : curve.Seed.Length;
                pBcryptBlob->cbSubgroupOrder      = curve.Order.Length;
                pBcryptBlob->CurveGenerationAlgId = ECCng.GetHashAlgorithmId(curve.Hash);
                pBcryptBlob->CurveType            = ECCng.ConvertToCurveTypeEnum(curve.CurveType);

                // Emit the blob
                int offset = sizeof(BCRYPT_ECC_PARAMETER_HEADER);

                Interop.BCrypt.Emit(blob, ref offset, curve.Prime);
                Interop.BCrypt.Emit(blob, ref offset, curve.A);
                Interop.BCrypt.Emit(blob, ref offset, curve.B);
                Interop.BCrypt.Emit(blob, ref offset, curve.G.X);
                Interop.BCrypt.Emit(blob, ref offset, curve.G.Y);
                Interop.BCrypt.Emit(blob, ref offset, curve.Order);
                Interop.BCrypt.Emit(blob, ref offset, curve.Cofactor);
                if (curve.Seed != null)
                {
                    Interop.BCrypt.Emit(blob, ref offset, curve.Seed);
                }

                // We better have computed the right allocation size above!
                Debug.Assert(offset == blobSize, "offset == blobSize");
            }

            return(blob);
        }