public async Task<ISignatureUnion> SignAsync( TpmHandle keyHandle, byte[] digest, ISigSchemeUnion inScheme, TkHashcheck validation) { var inS = new Tpm2SignRequest { keyHandle = keyHandle, digest = digest, inScheme = inScheme, validation = validation }; TpmStructureBase outSBase = null; await Task.Run(() => DispatchMethod(TpmCc.Sign, inS, typeof (Tpm2SignResponse), out outSBase, 1, 0)); var outS = (Tpm2SignResponse)outSBase; return outS.signature; }
/// <summary> /// This sample illustrates the creation and use of an RSA signing key to /// "quote" PCR state /// </summary> /// <param name="tpm">Reference to the TPM object.</param> static void QuotePcrs(Tpm2 tpm) { // // First use a library routine to create an RSA/AES primary storage key // with null user-auth. // TpmPublic rsaPrimaryPublic; var primaryAuth = new byte[0]; TpmHandle primHandle = CreateRsaPrimaryStorageKey(tpm, primaryAuth, out rsaPrimaryPublic); // // Template for a signing key. We will make the key restricted so that we // can quote with it too. // var signKeyPubTemplate = new TpmPublic(TpmAlgId.Sha1, ObjectAttr.Sign | ObjectAttr.Restricted | // A "quoting" key ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-duplicable ObjectAttr.UserWithAuth | // Authorize with auth-data ObjectAttr.SensitiveDataOrigin, // TPM will create a new key new byte[0], new RsaParms(new SymDefObject(), new SchemeRsassa(TpmAlgId.Sha1), 2048, 0), new Tpm2bPublicKeyRsa()); // // Auth-data for new key // var userAuth = new byte[] { 1, 2, 3, 4 }; var sensCreate = new SensitiveCreate(userAuth, new byte[0]); // // Creation data (not used in this sample) // CreationData childCreationData; TkCreation creationTicket; byte[] creationHash; // // Create the key // TpmPublic keyPub; TpmPrivate keyPriv = tpm[primaryAuth].Create(primHandle, // Child of primary key created above sensCreate, // Auth-data signKeyPubTemplate, // Template created above new byte[0], // Other parms are not used here new PcrSelection[0], out keyPub, out childCreationData, out creationHash, out creationTicket); Console.WriteLine("New public key\n" + keyPub.ToString()); // // Load the key as a child of the primary that it // was created under. // TpmHandle signHandle = tpm[primaryAuth].Load(primHandle, keyPriv, keyPub); // // Note that Load returns the "name" of the key and this is automatically // associated with the handle. // Console.WriteLine("Name of key:" + BitConverter.ToString(signHandle.Name)); // // Aome data to quote // TpmHash hashToSign = TpmHash.FromData(TpmAlgId.Sha1, new byte[] { 4, 3, 2, 1 }); // // PCRs to quote. SHA-1 bank, PCR-indices 1, 2, and 3 // var pcrsToQuote = new PcrSelection[] { new PcrSelection(TpmAlgId.Sha, new uint[] { 1, 2, 3 }) }; // // Ask the TPM to quote the PCR (and the nonce). The TPM // returns the quote-signature and the data that was signed // ISignatureUnion quoteSig; Attest quotedInfo = tpm[userAuth].Quote(signHandle, hashToSign.HashData, new SchemeRsassa(TpmAlgId.Sha1), pcrsToQuote, out quoteSig); // // Print out what was quoted // var info = (QuoteInfo)quotedInfo.attested; Console.WriteLine("PCRs that were quoted: " + info.pcrSelect[0].ToString() + "\nHash of PCR-array: " + BitConverter.ToString(info.pcrDigest)); // // Read the PCR to check the quoted value // PcrSelection[] outSelection; Tpm2bDigest[] outValues; tpm.PcrRead(new PcrSelection[] { new PcrSelection(TpmAlgId.Sha, new uint[] { 1, 2, 3 }) }, out outSelection, out outValues); // // Use the Tpm2Lib library to validate the quote against the // values just read. // bool quoteOk = keyPub.VerifyQuote(TpmAlgId.Sha1, outSelection, outValues, hashToSign.HashData, quotedInfo, quoteSig); if (!quoteOk) { throw new Exception("Quote did not validate"); } Console.WriteLine("Quote correctly validated."); // // Test other uses of the signing key. A restricted key can only // sign data that the TPM knows does not start with a magic // number (that identifies TPM internal data). So this does not // work // var nullProof = new TkHashcheck(TpmHandle.RhNull, new byte[0]); tpm[userAuth]._ExpectError(TpmRc.Ticket).Sign(signHandle, hashToSign.HashData, new SchemeRsassa(TpmAlgId.Sha1), nullProof); // // But if we ask the TPM to hash the same data and then sign it // then the TPM can be sure that the data is safe, so it will // sign it. // TkHashcheck safeHashTicket; TpmHandle hashHandle = tpm.HashSequenceStart(_nullAuth, TpmAlgId.Sha1); // // The ticket is only generated if the data is "safe." // tpm[_nullAuth].SequenceComplete(hashHandle, new byte[] { 4, 3, 2, 1 }, TpmHandle.RhOwner, out safeHashTicket); // // This will now work because the ticket proves to the // TPM that the data that it is about to sign does not // start with TPM_GENERATED // ISignatureUnion sig = tpm[userAuth].Sign(signHandle, hashToSign.HashData, new SchemeRsassa(TpmAlgId.Sha1), safeHashTicket); // // And we can verify the signature // bool sigOk = keyPub.VerifySignatureOverData(new byte[] { 4, 3, 2, 1 }, sig); if (!sigOk) { throw new Exception("Signature did not verify"); } Console.WriteLine("Signature verified."); // // Clean up // tpm.FlushContext(primHandle); tpm.FlushContext(signHandle); }
public ISignatureUnion Sign( TpmHandle keyHandle, byte[] digest, ISigSchemeUnion inScheme, TkHashcheck validation ) { Tpm2SignRequest inS = new Tpm2SignRequest(); inS.keyHandle = keyHandle; inS.digest = digest; inS.inScheme = inScheme; inS.validation = validation; TpmStructureBase outSBase; DispatchMethod(TpmCc.Sign, (TpmStructureBase) inS, typeof(Tpm2SignResponse), out outSBase, 1, 0); Tpm2SignResponse outS = (Tpm2SignResponse) outSBase; return outS.signature; }
public TkHashcheck(TkHashcheck the_TkHashcheck) { if((Object) the_TkHashcheck == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); hierarchy = the_TkHashcheck.hierarchy; digest = the_TkHashcheck.digest; }
public Tpm2SignRequest(Tpm2SignRequest the_Tpm2SignRequest) { if((Object) the_Tpm2SignRequest == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); keyHandle = the_Tpm2SignRequest.keyHandle; digest = the_Tpm2SignRequest.digest; validation = the_Tpm2SignRequest.validation; }
///<param name = "the_keyHandle">Handle of key that will perform signing Auth Index: 1 Auth Role: USER</param> ///<param name = "the_digest">digest to be signed</param> ///<param name = "the_inScheme">signing scheme to use if the scheme for keyHandle is TPM_ALG_NULL(One of SigSchemeRsassa, SigSchemeRsapss, SigSchemeEcdsa, SigSchemeEcdaa, SigSchemeSm2, SigSchemeEcschnorr, SchemeHmac, SchemeHash, NullSigScheme)</param> ///<param name = "the_validation">proof that digest was created by the TPM If keyHandle is not a restricted signing key, then this may be a NULL Ticket with tag = TPM_ST_CHECKHASH.</param> public Tpm2SignRequest( TpmHandle the_keyHandle, byte[] the_digest, ISigSchemeUnion the_inScheme, TkHashcheck the_validation ) { this.keyHandle = the_keyHandle; this.digest = the_digest; this.inScheme = the_inScheme; this.validation = the_validation; }
///<param name = "the_result">the returned HMAC or digest in a sized buffer</param> ///<param name = "the_validation">ticket indicating that the sequence of octets used to compute outDigest did not start with TPM_GENERATED_VALUE This is a NULL Ticket when the sequence is HMAC.</param> public Tpm2SequenceCompleteResponse( byte[] the_result, TkHashcheck the_validation ) { this.result = the_result; this.validation = the_validation; }
public Tpm2SignRequest() { keyHandle = new TpmHandle(); digest = new byte[0]; validation = new TkHashcheck(); }
public Tpm2SequenceCompleteResponse(Tpm2SequenceCompleteResponse the_Tpm2SequenceCompleteResponse) { if((Object) the_Tpm2SequenceCompleteResponse == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); result = the_Tpm2SequenceCompleteResponse.result; validation = the_Tpm2SequenceCompleteResponse.validation; }
public Tpm2SequenceCompleteResponse() { result = new byte[0]; validation = new TkHashcheck(); }
///<param name = "the_outHash">results</param> ///<param name = "the_validation">ticket indicating that the sequence of octets used to compute outDigest did not start with TPM_GENERATED_VALUE will be a NULL ticket if the digest may not be signed with a restricted key</param> public Tpm2HashResponse( byte[] the_outHash, TkHashcheck the_validation ) { this.outHash = the_outHash; this.validation = the_validation; }
public Tpm2HashResponse(Tpm2HashResponse the_Tpm2HashResponse) { if((Object) the_Tpm2HashResponse == null ) throw new ArgumentException(Globs.GetResourceString("parmError")); outHash = the_Tpm2HashResponse.outHash; validation = the_Tpm2HashResponse.validation; }
public Tpm2HashResponse() { outHash = new byte[0]; validation = new TkHashcheck(); }