상속: TpmStructureBase, IPublicIdUnion
예제 #1
0
파일: TpmKey.cs 프로젝트: jimsdog/TSS.MSR
 /// <summary>
 /// Get an ECDH key exchange key (one pass ephemeral) and the public key of
 /// the ephemeral key using ECDH with encodingParms as input to the KDF (ECC only).
 /// </summary>
 /// <param name="encodingParms"></param>
 /// <param name="pubEphem"></param>
 /// <returns></returns>
 public byte[] EcdhGetKeyExchangeKey(byte[] encodingParms, out EccPoint ephemPubPt)
 {
     using (AsymCryptoSystem encryptor = AsymCryptoSystem.CreateFrom(this))
     {
         return(encryptor.EcdhGetKeyExchangeKey(encodingParms, nameAlg, out ephemPubPt));
     }
 }
예제 #2
0
        } // VerifySignature()

        /// <summary>
        /// Generates the key exchange key and the public part of the ephemeral key
        /// using specified encoding parameters in the KDF (ECC only).
        /// </summary>
        /// <param name="encodingParms"></param>
        /// <param name="decryptKeyNameAlg"></param>
        /// <param name="ephemPub"></param>
        /// <returns>key exchange key blob</returns>
        public byte[] EcdhGetKeyExchangeKey(byte[] encodingParms, TpmAlgId decryptKeyNameAlg, out EccPoint ephemPub)
        {
            byte[] keyExchangeKey = null;
            ephemPub = null;

#if !__MonoCS__
            var eccParms = (EccParms)PublicParms.parameters;
            int keyBits  = RawEccKey.GetKeyLength(eccParms.curveID);

            // Make a new ephemeral key
#if TSS_USE_BCRYPT
            var    ephKey   = Generate(RawEccKey.GetEccAlg(PublicParms), (uint)keyBits);
            byte[] ephPub   = ephKey.Export(Native.BCRYPT_ECCPUBLIC_BLOB);
            byte[] otherPub = Key.Export(Native.BCRYPT_ECCPUBLIC_BLOB);
#else
            using (var eph = new ECDiffieHellmanCng(keyBits))
            {
                byte[] otherPub = EcDhProvider.PublicKey.ToByteArray();
                byte[] ephPub   = eph.PublicKey.ToByteArray();

                eph.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                eph.HashAlgorithm         = GetCngAlgorithm(decryptKeyNameAlg);
#endif // !TSS_USE_BCRYPT

            byte[] herPubX, herPubY;
            RawEccKey.KeyInfoFromPublicBlob(otherPub, out herPubX, out herPubY);

            byte[] myPubX, myPubY;
            RawEccKey.KeyInfoFromPublicBlob(ephPub, out myPubX, out myPubY);

            byte[] otherInfo = Globs.Concatenate(new[] { encodingParms, myPubX, herPubX });

            // The TPM uses the following number of bytes from the KDF
            int bytesNeeded = CryptoLib.DigestSize(decryptKeyNameAlg);
            keyExchangeKey = new byte[bytesNeeded];

            for (int pos = 0, count = 1, bytesToCopy = 0;
                 pos < bytesNeeded;
                 ++count, pos += bytesToCopy)
            {
                byte[] secretPrepend = Marshaller.GetTpmRepresentation((UInt32)count);
#if TSS_USE_BCRYPT
                byte[] fragment = ephKey.DeriveKey(Key, decryptKeyNameAlg, secretPrepend, otherInfo);
#else
                eph.SecretAppend  = otherInfo;
                eph.SecretPrepend = secretPrepend;
                byte[] fragment = eph.DeriveKeyMaterial(EcDhProvider.Key);
#endif // !TSS_USE_BCRYPT
                bytesToCopy = Math.Min(bytesNeeded - pos, fragment.Length);
                Array.Copy(fragment, 0, keyExchangeKey, pos, bytesToCopy);
            }
            ephemPub = new EccPoint(myPubX, myPubY);
#if !TSS_USE_BCRYPT
        }
#endif
#endif // !__MonoCS__
            return(keyExchangeKey);
        }
예제 #3
0
 ///<param name = "the_point">coordinates</param>
 public Tpm2bEccPoint(
 EccPoint the_point
 )
 {
     this.point = the_point;
 }
예제 #4
0
 /// <summary>
 /// Get an ECDH key exchange key (one pass ephemeral) and the public key of the ephemeral
 /// key using ECDH with encodingParms as input to the KDF (ECC only)
 /// </summary>
 /// <param name="encodingParms"></param>
 /// <param name="decryptKeyNameAlg"></param>
 /// <param name="pubEphem"></param>
 /// <returns></returns>
 public byte[] EcdhGetKeyExchangeKey(byte[] encodingParms, TpmAlgId decryptKeyNameAlg, out EccPoint pubEphem)
 {
     using (AsymCryptoSystem encryptor = AsymCryptoSystem.CreateFrom(this))
     {
         return encryptor.EcdhGetKeyExchangeKey(encodingParms, decryptKeyNameAlg, out pubEphem);
     }
 }
예제 #5
0
 public EccPoint Commit(
     TpmHandle signHandle,
     EccPoint P1,
     byte[] s2,
     byte[] y2,
     [SuppressMessage("Microsoft.Design", "CA1021")]
     out EccPoint L,
     [SuppressMessage("Microsoft.Design", "CA1021")]
     out EccPoint E,
     [SuppressMessage("Microsoft.Design", "CA1021")]
     out ushort counter
 )
 {
     Tpm2CommitRequest inS = new Tpm2CommitRequest();
     inS.signHandle = signHandle;
     inS.P1 = P1;
     inS.s2 = s2;
     inS.y2 = y2;
     TpmStructureBase outSBase;
     DispatchMethod(TpmCc.Commit, (TpmStructureBase) inS, typeof(Tpm2CommitResponse), out outSBase, 1, 0);
     Tpm2CommitResponse outS = (Tpm2CommitResponse) outSBase;
     L = outS.L;
     E = outS.E;
     counter = outS.counter;
     return outS.K;
 }
예제 #6
0
 public Tpm2bEccPoint()
 {
     point = new EccPoint();
 }
예제 #7
0
 public Tpm2EcEphemeralResponse()
 {
     Q = new EccPoint();
 }
예제 #8
0
 public EccPoint EcdhZGen(
     TpmHandle keyHandle,
     EccPoint inPoint
 )
 {
     Tpm2EcdhZGenRequest inS = new Tpm2EcdhZGenRequest();
     inS.keyHandle = keyHandle;
     inS.inPoint = inPoint;
     TpmStructureBase outSBase;
     DispatchMethod(TpmCc.EcdhZGen, (TpmStructureBase) inS, typeof(Tpm2EcdhZGenResponse), out outSBase, 1, 0);
     Tpm2EcdhZGenResponse outS = (Tpm2EcdhZGenResponse) outSBase;
     return outS.outPoint;
 }
예제 #9
0
 public Tpm2EcdhZGenResponse(Tpm2EcdhZGenResponse the_Tpm2EcdhZGenResponse)
 {
     if((Object) the_Tpm2EcdhZGenResponse == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     outPoint = the_Tpm2EcdhZGenResponse.outPoint;
 }
예제 #10
0
 public Tpm2CommitResponse()
 {
     K = new EccPoint();
     L = new EccPoint();
     E = new EccPoint();
 }
예제 #11
0
 ///<param name = "the_keyHandle">handle of a loaded ECC key Auth Index: 1 Auth Role: USER</param>
 ///<param name = "the_inPoint">a public key</param>
 public Tpm2EcdhZGenRequest(
 TpmHandle the_keyHandle,
 EccPoint the_inPoint
 )
 {
     this.keyHandle = the_keyHandle;
     this.inPoint = the_inPoint;
 }
예제 #12
0
 public Tpm2EcdhZGenResponse()
 {
     outPoint = new EccPoint();
 }
예제 #13
0
 public Tpm2EcdhZGenRequest(Tpm2EcdhZGenRequest the_Tpm2EcdhZGenRequest)
 {
     if((Object) the_Tpm2EcdhZGenRequest == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     keyHandle = the_Tpm2EcdhZGenRequest.keyHandle;
     inPoint = the_Tpm2EcdhZGenRequest.inPoint;
 }
예제 #14
0
 public Tpm2EcdhZGenRequest()
 {
     keyHandle = new TpmHandle();
     inPoint = new EccPoint();
 }
예제 #15
0
 ///<param name = "the_zPoint">results of P  h[de]Qs</param>
 ///<param name = "the_pubPoint">generated ephemeral public point (Qe)</param>
 public Tpm2EcdhKeyGenResponse(
 EccPoint the_zPoint,
 EccPoint the_pubPoint
 )
 {
     this.zPoint = the_zPoint;
     this.pubPoint = the_pubPoint;
 }
예제 #16
0
 public Tpm2EcdhKeyGenResponse()
 {
     zPoint = new EccPoint();
     pubPoint = new EccPoint();
 }
예제 #17
0
 ///<param name = "the_outPoint">X and Y coordinates of the product of the multiplication Z = (xZ , yZ)  [hdS]QB</param>
 public Tpm2EcdhZGenResponse(
 EccPoint the_outPoint
 )
 {
     this.outPoint = the_outPoint;
 }
예제 #18
0
 ///<param name = "the_signHandle">handle of the key that will be used in the signing operation Auth Index: 1 Auth Role: USER</param>
 ///<param name = "the_P1">a point (M) on the curve used by signHandle</param>
 ///<param name = "the_s2">octet array used to derive x-coordinate of a base point</param>
 ///<param name = "the_y2">y coordinate of the point associated with s2</param>
 public Tpm2CommitRequest(
 TpmHandle the_signHandle,
 EccPoint the_P1,
 byte[] the_s2,
 byte[] the_y2
 )
 {
     this.signHandle = the_signHandle;
     this.P1 = the_P1;
     this.s2 = the_s2;
     this.y2 = the_y2;
 }
예제 #19
0
 public Tpm2ZGen2PhaseRequest()
 {
     keyA = new TpmHandle();
     inQsB = new EccPoint();
     inQeB = new EccPoint();
     inScheme = TpmAlgId.Null;
 }
예제 #20
0
 ///<param name = "the_K">ECC point K  [ds](x2, y2)</param>
 ///<param name = "the_L">ECC point L  [r](x2, y2)</param>
 ///<param name = "the_E">ECC point E  [r]P1</param>
 ///<param name = "the_counter">least-significant 16 bits of commitCount</param>
 public Tpm2CommitResponse(
 EccPoint the_K,
 EccPoint the_L,
 EccPoint the_E,
 ushort the_counter
 )
 {
     this.K = the_K;
     this.L = the_L;
     this.E = the_E;
     this.counter = the_counter;
 }
예제 #21
0
 ///<param name = "the_keyA">handle of an unrestricted decryption key ECC The private key referenced by this handle is used as dS,A Auth Index: 1 Auth Role: USER</param>
 ///<param name = "the_inQsB">other partys static public key (Qs,B = (Xs,B, Ys,B))</param>
 ///<param name = "the_inQeB">other party's ephemeral public key (Qe,B = (Xe,B, Ye,B))</param>
 ///<param name = "the_inScheme">the key exchange scheme</param>
 ///<param name = "the_counter">value returned by TPM2_EC_Ephemeral()</param>
 public Tpm2ZGen2PhaseRequest(
 TpmHandle the_keyA,
 EccPoint the_inQsB,
 EccPoint the_inQeB,
 TpmAlgId the_inScheme,
 ushort the_counter
 )
 {
     this.keyA = the_keyA;
     this.inQsB = the_inQsB;
     this.inQeB = the_inQeB;
     this.inScheme = the_inScheme;
     this.counter = the_counter;
 }
예제 #22
0
 ///<param name = "the_Q">ephemeral public key Q  [r]G</param>
 ///<param name = "the_counter">least-significant 16 bits of commitCount</param>
 public Tpm2EcEphemeralResponse(
 EccPoint the_Q,
 ushort the_counter
 )
 {
     this.Q = the_Q;
     this.counter = the_counter;
 }
예제 #23
0
 public Tpm2ZGen2PhaseResponse()
 {
     outZ1 = new EccPoint();
     outZ2 = new EccPoint();
 }
예제 #24
0
 public EccPoint ZGen2Phase(
     TpmHandle keyA,
     EccPoint inQsB,
     EccPoint inQeB,
     TpmAlgId inScheme,
     ushort counter,
     [SuppressMessage("Microsoft.Design", "CA1021")]
     out EccPoint outZ2
 )
 {
     Tpm2ZGen2PhaseRequest inS = new Tpm2ZGen2PhaseRequest();
     inS.keyA = keyA;
     inS.inQsB = inQsB;
     inS.inQeB = inQeB;
     inS.inScheme = inScheme;
     inS.counter = counter;
     TpmStructureBase outSBase;
     DispatchMethod(TpmCc.ZGen2Phase, (TpmStructureBase) inS, typeof(Tpm2ZGen2PhaseResponse), out outSBase, 1, 0);
     Tpm2ZGen2PhaseResponse outS = (Tpm2ZGen2PhaseResponse) outSBase;
     outZ2 = outS.outZ2;
     return outS.outZ1;
 }
예제 #25
0
 public Tpm2ZGen2PhaseResponse(Tpm2ZGen2PhaseResponse the_Tpm2ZGen2PhaseResponse)
 {
     if((Object) the_Tpm2ZGen2PhaseResponse == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     outZ1 = the_Tpm2ZGen2PhaseResponse.outZ1;
     outZ2 = the_Tpm2ZGen2PhaseResponse.outZ2;
 }
예제 #26
0
 public EccPoint(EccPoint the_EccPoint)
 {
     if((Object) the_EccPoint == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     x = the_EccPoint.x;
     y = the_EccPoint.y;
 }
예제 #27
0
 ///<param name = "the_outZ1">X and Y coordinates of the computed value (scheme dependent)</param>
 ///<param name = "the_outZ2">X and Y coordinates of the second computed value (scheme dependent)</param>
 public Tpm2ZGen2PhaseResponse(
 EccPoint the_outZ1,
 EccPoint the_outZ2
 )
 {
     this.outZ1 = the_outZ1;
     this.outZ2 = the_outZ2;
 }
예제 #28
0
 public Tpm2bEccPoint(Tpm2bEccPoint the_Tpm2bEccPoint)
 {
     if((Object) the_Tpm2bEccPoint == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     point = the_Tpm2bEccPoint.point;
 }
예제 #29
0
 /// <summary>
 /// Get an ECDH key exchange key (one pass ephemeral) and the public key of the ephemeral
 /// key using ECDH with encodingParms as input to the KDF (ECC only)
 /// </summary>
 /// <param name="encodingParms"></param>
 /// <param name="decryptKeyNameAlg"></param>
 /// <param name="pubEphem"></param>
 /// <returns></returns>
 public byte[] EcdhGetKeyExchangeKey(byte[] encodingParms, TpmAlgId decryptKeyNameAlg, out EccPoint pubEphem)
 {
     using (AsymCryptoSystem encryptor = AsymCryptoSystem.CreateFrom(this))
     {
         return(encryptor.EcdhGetKeyExchangeKey(encodingParms, decryptKeyNameAlg, out pubEphem));
     }
 }
예제 #30
0
        /// <summary>
        /// Create a new random software key (public and private) matching the parameters in keyParams.
        /// </summary>
        /// <param name="keyParams"></param>
        /// <returns></returns>
        public AsymCryptoSystem(TpmPublic keyParams)
        {
            TpmAlgId keyAlgId = keyParams.type;

            PublicParms = keyParams.Copy();

            switch (keyAlgId)
            {
            case TpmAlgId.Rsa:
            {
                var rsaParams = keyParams.parameters as RsaParms;
#if TSS_USE_BCRYPT
                Key = Generate(Native.BCRYPT_RSA_ALGORITHM, rsaParams.keyBits);
                if (Key == UIntPtr.Zero)
                {
                    Globs.Throw("Failed to generate RSA key");
                    return;
                }
                byte[] blob   = Export(Native.BCRYPT_RSAPUBLIC_BLOB);
                var    m      = new Marshaller(blob, DataRepresentation.LittleEndian);
                var    header = m.Get <BCryptRsaKeyBlob>();
                /*var exponent = */ m.GetArray <byte>((int)header.cbPublicExp);
                var modulus = m.GetArray <byte>((int)header.cbModulus);
#else
                RsaProvider = new RSACryptoServiceProvider(rsaParams.keyBits);
                var modulus = RsaProvider.ExportParameters(true).Modulus;
#endif
                var pubId = new Tpm2bPublicKeyRsa(modulus);
                PublicParms.unique = pubId;
                break;
            }

#if !__MonoCS__
            case TpmAlgId.Ecc:
            {
                var eccParms = keyParams.parameters as EccParms;
                var alg      = RawEccKey.GetEccAlg(keyParams);
                if (alg == null)
                {
                    Globs.Throw <ArgumentException>("Unknown ECC curve");
                    return;
                }
#if TSS_USE_BCRYPT
                Key = Generate(alg, (uint)RawEccKey.GetKeyLength(eccParms.curveID));
#else
                var keyParmsX = new CngKeyCreationParameters {
                    ExportPolicy = CngExportPolicies.AllowPlaintextExport
                };
                using (CngKey key = CngKey.Create(alg, null, keyParmsX))
                {
                    byte[] keyIs = key.Export(CngKeyBlobFormat.EccPublicBlob);
                    CngKey.Import(keyIs, CngKeyBlobFormat.EccPublicBlob);

                    if (keyParams.objectAttributes.HasFlag(ObjectAttr.Sign))
                    {
                        EcdsaProvider = new ECDsaCng(key);
                    }
                    else
                    {
                        EcDhProvider = new ECDiffieHellmanCng(key);
                    }
                    // Store the public key
                    const int offset  = 8;
                    int       keySize = 0;
                    switch (eccParms.curveID)
                    {
                    case EccCurve.TpmEccNistP256:
                    case EccCurve.TpmEccBnP256:
                    case EccCurve.TpmEccSm2P256:
                        keySize = 32;
                        break;

                    case EccCurve.TpmEccNistP384:
                        keySize = 48;
                        break;

                    case EccCurve.TpmEccNistP521:
                        keySize = 66;
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                    var pubId = new EccPoint(
                        Globs.CopyData(keyIs, offset, keySize),
                        Globs.CopyData(keyIs, offset + keySize, keySize));
                    PublicParms.unique = pubId;
                }
#endif // !TSS_USE_BCRYPT
                break;
            }
#endif // !__MonoCS__
            default:
                Globs.Throw <ArgumentException>("Algorithm not supported");
                break;
            }
        }
예제 #31
0
 public Tpm2EcEphemeralResponse()
 {
     Q = new EccPoint();
     counter = 0;
 }
예제 #32
0
 public Tpm2CommitRequest()
 {
     signHandle = new TpmHandle();
     P1 = new EccPoint();
     s2 = new byte[0];
     y2 = new byte[0];
 }
예제 #33
0
        } // VerifySignature()

        /// <summary>
        /// Generates the key exchange key and the public part of the ephemeral key
        /// using specified encoding parameters in the KDF (ECC only).
        /// </summary>
        /// <param name="encodingParms"></param>
        /// <param name="decryptKeyNameAlg"></param>
        /// <param name="ephemPub"></param>
        /// <returns>key exchange key blob</returns>
        public byte[] EcdhGetKeyExchangeKey(byte[] encodingParms, TpmAlgId decryptKeyNameAlg, out EccPoint ephemPub)
        {
            var eccParms = (EccParms)PublicParms.parameters;
            int keyBits  = RawEccKey.GetKeyLength(eccParms.curveID);

            byte[] keyExchangeKey = null;
            ephemPub = new EccPoint();

            // Make a new ephemeral key
            var     prov      = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(RawEccKey.GetEccAlg(PublicParms));
            var     ephKey    = prov.CreateKeyPair((uint)keyBits);
            IBuffer ephPubBuf = ephKey.ExportPublicKey(CryptographicPublicKeyBlobType.BCryptEccFullPublicKey);

            byte[] ephPub;
            CryptographicBuffer.CopyToByteArray(ephPubBuf, out ephPub);

            IBuffer otherPubBuf = Key.ExportPublicKey(CryptographicPublicKeyBlobType.BCryptEccFullPublicKey);

            byte[] otherPub;
            CryptographicBuffer.CopyToByteArray(otherPubBuf, out otherPub);

            byte[] herPubX, herPubY;
            RawEccKey.KeyInfoFromPublicBlob(otherPub, out herPubX, out herPubY);

            byte[] myPubX, myPubY;
            RawEccKey.KeyInfoFromPublicBlob(ephPub, out myPubX, out myPubY);

            byte[] otherInfo = Globs.Concatenate(new[] { encodingParms, myPubX, herPubX });

            // The TPM uses the following number of bytes from the KDF
            int bytesNeeded = CryptoLib.DigestSize(decryptKeyNameAlg);

            keyExchangeKey = new byte[bytesNeeded];

            for (int pos = 0, count = 1, bytesToCopy = 0;
                 pos < bytesNeeded;
                 ++count, pos += bytesToCopy)
            {
                byte[] secretPrepend = Marshaller.GetTpmRepresentation((UInt32)count);
                string algName;
                KeyDerivationParameters deriveParams;
                switch (decryptKeyNameAlg)
                {
                case TpmAlgId.Kdf1Sp800108:
                    algName      = KeyDerivationAlgorithmNames.Sp800108CtrHmacSha256;
                    deriveParams = KeyDerivationParameters.BuildForSP800108(CryptographicBuffer.CreateFromByteArray(secretPrepend), CryptographicBuffer.CreateFromByteArray(otherInfo));
                    break;

                case TpmAlgId.Kdf1Sp80056a:
                    algName      = KeyDerivationAlgorithmNames.Sp80056aConcatSha256;
                    deriveParams = KeyDerivationParameters.BuildForSP80056a(CryptographicBuffer.ConvertStringToBinary(algName, BinaryStringEncoding.Utf8),
                                                                            CryptographicBuffer.ConvertStringToBinary("TPM", BinaryStringEncoding.Utf8),
                                                                            CryptographicBuffer.CreateFromByteArray(secretPrepend),
                                                                            CryptographicBuffer.ConvertStringToBinary("", BinaryStringEncoding.Utf8),
                                                                            CryptographicBuffer.CreateFromByteArray(otherInfo));
                    break;

                case TpmAlgId.Kdf2:
                    algName      = KeyDerivationAlgorithmNames.Pbkdf2Sha256;
                    deriveParams = KeyDerivationParameters.BuildForPbkdf2(CryptographicBuffer.CreateFromByteArray(secretPrepend), 1000);
                    break;

                default:
                    Globs.Throw <ArgumentException>("wrong KDF name");
                    return(null);
                }
                KeyDerivationAlgorithmProvider deriveProv = KeyDerivationAlgorithmProvider.OpenAlgorithm(algName);
                IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(Key, deriveParams, (uint)keyBits);
                byte[]  fragment;
                CryptographicBuffer.CopyToByteArray(keyMaterial, out fragment);
                bytesToCopy = Math.Min(bytesNeeded - pos, fragment.Length);
                Array.Copy(fragment, 0, keyExchangeKey, pos, bytesToCopy);
            }
            ephemPub = new EccPoint(myPubX, myPubY);
            return(keyExchangeKey);
        }
예제 #34
0
 public Tpm2CommitRequest(Tpm2CommitRequest the_Tpm2CommitRequest)
 {
     if((Object) the_Tpm2CommitRequest == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     signHandle = the_Tpm2CommitRequest.signHandle;
     P1 = the_Tpm2CommitRequest.P1;
     s2 = the_Tpm2CommitRequest.s2;
     y2 = the_Tpm2CommitRequest.y2;
 }
예제 #35
0
 public Tpm2CommitResponse()
 {
     K = new EccPoint();
     L = new EccPoint();
     E = new EccPoint();
     counter = 0;
 }