/// <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)); } }
} // 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); }
///<param name = "the_point">coordinates</param> public Tpm2bEccPoint( EccPoint the_point ) { this.point = the_point; }
/// <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); } }
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; }
public Tpm2bEccPoint() { point = new EccPoint(); }
public Tpm2EcEphemeralResponse() { Q = new EccPoint(); }
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; }
public Tpm2EcdhZGenResponse(Tpm2EcdhZGenResponse the_Tpm2EcdhZGenResponse) { if((Object) the_Tpm2EcdhZGenResponse == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); outPoint = the_Tpm2EcdhZGenResponse.outPoint; }
public Tpm2CommitResponse() { K = new EccPoint(); L = new EccPoint(); E = new EccPoint(); }
///<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; }
public Tpm2EcdhZGenResponse() { outPoint = new EccPoint(); }
public Tpm2EcdhZGenRequest(Tpm2EcdhZGenRequest the_Tpm2EcdhZGenRequest) { if((Object) the_Tpm2EcdhZGenRequest == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); keyHandle = the_Tpm2EcdhZGenRequest.keyHandle; inPoint = the_Tpm2EcdhZGenRequest.inPoint; }
public Tpm2EcdhZGenRequest() { keyHandle = new TpmHandle(); inPoint = new EccPoint(); }
///<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; }
public Tpm2EcdhKeyGenResponse() { zPoint = new EccPoint(); pubPoint = new EccPoint(); }
///<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; }
///<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; }
public Tpm2ZGen2PhaseRequest() { keyA = new TpmHandle(); inQsB = new EccPoint(); inQeB = new EccPoint(); inScheme = TpmAlgId.Null; }
///<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; }
///<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; }
///<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; }
public Tpm2ZGen2PhaseResponse() { outZ1 = new EccPoint(); outZ2 = new EccPoint(); }
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; }
public Tpm2ZGen2PhaseResponse(Tpm2ZGen2PhaseResponse the_Tpm2ZGen2PhaseResponse) { if((Object) the_Tpm2ZGen2PhaseResponse == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); outZ1 = the_Tpm2ZGen2PhaseResponse.outZ1; outZ2 = the_Tpm2ZGen2PhaseResponse.outZ2; }
public EccPoint(EccPoint the_EccPoint) { if((Object) the_EccPoint == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); x = the_EccPoint.x; y = the_EccPoint.y; }
///<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; }
public Tpm2bEccPoint(Tpm2bEccPoint the_Tpm2bEccPoint) { if((Object) the_Tpm2bEccPoint == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); point = the_Tpm2bEccPoint.point; }
/// <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)); } }
/// <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; } }
public Tpm2EcEphemeralResponse() { Q = new EccPoint(); counter = 0; }
public Tpm2CommitRequest() { signHandle = new TpmHandle(); P1 = new EccPoint(); s2 = new byte[0]; y2 = new byte[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); }
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; }
public Tpm2CommitResponse() { K = new EccPoint(); L = new EccPoint(); E = new EccPoint(); counter = 0; }