/// <summary> /// OEAP pad and encrypt the data using the specified encoding parameters (RSA only). /// </summary> /// <param name="dataToEncrypt"></param> /// <param name="encodingParms"></param> /// <returns></returns> public byte[] EncryptOaep(byte[] dataToEncrypt, byte[] encodingParms) { using (AsymCryptoSystem encryptor = AsymCryptoSystem.CreateFrom(this)) { return(encryptor.EncryptOaep(dataToEncrypt, encodingParms)); } }
/// <summary> /// The TPM always signs hash-sized data. This version of the VerifySignature /// performs the necessary hashing operation over arbitrarily-length data and /// verifies that the hash is properly signed. /// </summary> /// <param name="data"></param> /// <param name="sig"></param> /// <returns></returns> public bool VerifySignatureOverData(byte[] data, ISignatureUnion sig) { using (AsymCryptoSystem verifier = AsymCryptoSystem.CreateFrom(this)) { return(verifier.VerifySignatureOverData(data, sig)); } }
/// <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)); } }
/// <summary> /// Verify a TPM signature structure of the hash of some data (caller hashes /// the data that will be verified). /// </summary> public bool VerifySignatureOverHash(byte[] digest, ISignatureUnion sig) { using (AsymCryptoSystem verifier = AsymCryptoSystem.CreateFrom(this)) { return(verifier.VerifySignatureOverHash(digest, sig)); } }
/// <summary> /// Verify a TPM signature structure of the hash of some data (caller hashes the data that will be verified) /// </summary> /// <param name="signedHash"></param> /// <param name="signature"></param> /// <returns></returns> public bool VerifySignatureOverHash(TpmHash signedHash, ISignatureUnion signature) { using (AsymCryptoSystem verifier = AsymCryptoSystem.CreateFrom(this)) { return(verifier.VerifySignatureOverHash(signedHash, signature)); } }
/// <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> /// The TPM always signs hash-sized data. This version of the VerifySignature performs the necessary /// hash operation over arbitrarily-length data and verifies that the hash is properly signed /// (i.e. the library performs the hash) /// </summary> /// <param name="signedData"></param> /// <param name="signature"></param> /// <returns></returns> public bool VerifySignatureOverData(byte[] signedData, ISignatureUnion signature, TpmAlgId sigHashAlg = TpmAlgId.Null) { using (AsymCryptoSystem verifier = AsymCryptoSystem.CreateFrom(this)) { bool sigOk = verifier.VerifySignatureOverData(signedData, signature, sigHashAlg); return(sigOk); } }
/// <summary> /// Creates a duplication blob for the current key that can be Imported as a child /// of newParent. Three forms are possible. GetPlaintextDuplicationBlob() allows /// plaintext-import. This function enables duplication with and without an /// inner wrapper (depending on whether innerWrapper is null) /// </summary> /// <param name="newParent"></param> /// <param name="innerWrapper"></param> /// <param name="encSecret"></param> /// <returns></returns> public TpmPrivate GetDuplicationBlob( TpmPublic pubNewParent, SymCipher innerWrapper, out byte[] encSecret) { byte[] encSensitive; if (innerWrapper == null) { // No inner wrapper encSensitive = Marshaller.ToTpm2B(Sensitive.GetTpmRepresentation()); Transform(encSensitive); } else { byte[] sens = Marshaller.ToTpm2B(Sensitive.GetTpmRepresentation()); byte[] toHash = Globs.Concatenate(sens, GetName()); Transform(toHash); byte[] innerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData( Public.nameAlg, toHash)); byte[] innerData = Globs.Concatenate(innerIntegrity, sens); Transform(innerData); encSensitive = innerWrapper.Encrypt(innerData); Transform(encSensitive); } byte[] seed; SymDefObject symDef = GetSymDef(pubNewParent).Copy(); // TPM duplication procedures always use CFB mode symDef.Mode = TpmAlgId.Cfb; using (var swNewParent = AsymCryptoSystem.CreateFrom(pubNewParent)) { switch (pubNewParent.type) { case TpmAlgId.Rsa: // The seed should be the same size as the scheme hash LastSeed = seed = Globs.GetRandomBytes( CryptoLib.DigestSize(swNewParent.OaepHash)); encSecret = swNewParent.EncryptOaep(seed, DuplicateEncodingParms); break; case TpmAlgId.Ecc: EccPoint pubEphem; seed = swNewParent.EcdhGetKeyExchangeKey(DuplicateEncodingParms, pubNewParent.nameAlg, out pubEphem); encSecret = Marshaller.GetTpmRepresentation(pubEphem); break; default: Globs.Throw <NotImplementedException>( "GetDuplicationBlob: Unsupported algorithm"); encSecret = new byte[0]; return(new TpmPrivate()); } } Transform(seed); Transform(encSecret); byte[] symKey = KDF.KDFa(pubNewParent.nameAlg, seed, "STORAGE", Public.GetName(), new byte[0], symDef.KeyBits); Transform(symKey); byte[] dupSensitive; using (SymCipher enc2 = SymCipher.Create(symDef, symKey)) { if (enc2 == null) { return(null); } dupSensitive = enc2.Encrypt(encSensitive); } Transform(dupSensitive); var npNameNumBits = CryptoLib.DigestSize(pubNewParent.nameAlg) * 8; byte[] hmacKey = KDF.KDFa(pubNewParent.nameAlg, seed, "INTEGRITY", new byte[0], new byte[0], npNameNumBits); byte[] outerDataToHmac = Globs.Concatenate(dupSensitive, Public.GetName()); Transform(outerDataToHmac); byte[] outerHmac = Marshaller.ToTpm2B(CryptoLib.Hmac(pubNewParent.nameAlg, hmacKey, outerDataToHmac)); Transform(outerHmac); byte[] dupBlob = Globs.Concatenate(outerHmac, dupSensitive); Transform(dupBlob); return(new TpmPrivate(dupBlob)); }
/// <summary> /// Creates a duplication blob for the current key that can be Imported as a child /// of newParent. Three forms are possible. GetPlaintextDuplicationBlob() allows /// plaintext-import. This function enables duplication with and without an /// inner wrapper (depending on whether innerWrapper is null) /// </summary> /// <param name="newParent"></param> /// <param name="innerWrapper"></param> /// <param name="encryptedWrappingKey"></param> /// <returns></returns> public TpmPrivate GetDuplicationBlob( TpmPublic newParent, SymmCipher innerWrapper, out byte[] encryptedWrappingKey) { byte[] encSensitive; if (innerWrapper == null) { // No inner wrapper encSensitive = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation()); } else { byte[] sens = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation()); byte[] toHash = Globs.Concatenate(sens, GetName()); byte[] innerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData(publicPart.nameAlg, toHash)); byte[] innerData = Globs.Concatenate(innerIntegrity, sens); encSensitive = innerWrapper.Encrypt(innerData); } byte[] seed, encSecret; SymDefObject symDef = GetSymDef(newParent); using (AsymCryptoSystem newParentPubKey = AsymCryptoSystem.CreateFrom(newParent)) { switch (newParent.type) { case TpmAlgId.Rsa: // The seed should be the same size as the symmKey seed = Globs.GetRandomBytes((symDef.KeyBits + 7) / 8); encSecret = newParentPubKey.EncryptOaep(seed, DuplicateEncodingParms); break; case TpmAlgId.Ecc: EccPoint pubEphem; seed = newParentPubKey.EcdhGetKeyExchangeKey(DuplicateEncodingParms, newParent.nameAlg, out pubEphem); encSecret = Marshaller.GetTpmRepresentation(pubEphem); break; default: Globs.Throw <NotImplementedException>("GetDuplicationBlob: Unsupported algorithm"); encryptedWrappingKey = new byte[0]; return(new TpmPrivate()); } } encryptedWrappingKey = encSecret; byte[] symKey = KDF.KDFa(newParent.nameAlg, seed, "STORAGE", publicPart.GetName(), new byte[0], symDef.KeyBits); byte[] dupSensitive; using (SymmCipher enc2 = SymmCipher.Create(symDef, symKey)) { dupSensitive = enc2.Encrypt(encSensitive); } var npNameNumBits = CryptoLib.DigestSize(newParent.nameAlg) * 8; byte[] hmacKey = KDF.KDFa(newParent.nameAlg, seed, "INTEGRITY", new byte[0], new byte[0], npNameNumBits); byte[] outerDataToHmac = Globs.Concatenate(dupSensitive, publicPart.GetName()); byte[] outerHmac = Marshaller.ToTpm2B(CryptoLib.HmacData(newParent.nameAlg, hmacKey, outerDataToHmac)); byte[] dupBlob = Globs.Concatenate(outerHmac, dupSensitive); return(new TpmPrivate(dupBlob)); }