/// <summary> /// Verifies the signature over data or a digest. /// The data will be hashed internall by the method using hash algorithm from /// the signing scheme digest computed from the specified data buffer. /// The signing scheme is retrieved from the signature. The verification key /// shall have either compatible or null scheme. /// </summary> /// <param name="data">Byte buffer containing either digest or data to check against the signature</param> /// <param name="dataIsDigest">Specifies the type of 'data' parameter contents</param> /// <param name="signature">The signature</param> /// <returns>True if the verification succeeds.</returns> private bool VerifySignature(byte[] data, bool dataIsDigest, ISignatureUnion sig) { #if TSS_USE_BCRYPT Debug.Assert(Key != UIntPtr.Zero); #endif TpmAlgId sigScheme = sig.GetUnionSelector(); TpmAlgId sigHash = CryptoLib.SchemeHash(sig); var rsaParams = PublicParms.parameters as RsaParms; if (rsaParams != null) { #if !TSS_USE_BCRYPT Debug.Assert(RsaProvider != null); #endif var s = sig as SignatureRsa; TpmAlgId keyScheme = rsaParams.scheme.GetUnionSelector(); if (keyScheme != TpmAlgId.Null && keyScheme != sigScheme) { Globs.Throw <ArgumentException>("Key scheme and signature scheme do not match"); return(false); } byte[] digest = dataIsDigest ? data : CryptoLib.HashData(sigHash, data); if (sigScheme == TpmAlgId.Rsassa) { #if TSS_USE_BCRYPT return(Key.VerifySignature(digest, s.sig, sigHash, true)); #else return(RsaProvider.VerifyHash(digest, CryptoLib.GetHashName(sigHash), s.sig)); #endif } if (sigScheme == TpmAlgId.Rsapss) { #if true Globs.Throw <ArgumentException>("VerifySignature(): PSS scheme is not supported"); return(false); #else #if TSS_USE_BCRYPT return(BCryptInterface.VerifySignature(KeyHandle, digest, sig.sig, sigHash, false)); #else var rr = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize); return(rr.PssVerify(digest, sig.sig, sigHash)); #endif #endif // false } Globs.Throw <ArgumentException>("VerifySignature(): Unrecognized scheme"); return(false); } var eccParams = PublicParms.parameters as EccParms; if (eccParams != null) { if (eccParams.scheme.GetUnionSelector() != TpmAlgId.Ecdsa) { Globs.Throw <ArgumentException>("Unsupported ECC sig scheme"); return(false); } TpmAlgId keyScheme = eccParams.scheme.GetUnionSelector(); if (keyScheme != TpmAlgId.Null && keyScheme != sigScheme) { Globs.Throw <ArgumentException>("Key scheme and signature scheme do not match"); return(false); } var s = sig as SignatureEcdsa; byte[] digest = dataIsDigest ? data : CryptoLib.HashData(sigHash, data); byte[] sigBlob = Globs.Concatenate(s.signatureR, s.signatureS); #if TSS_USE_BCRYPT return(Key.VerifySignature(digest, sigBlob)); #elif !__MonoCS__ Debug.Assert(EcdsaProvider != null); EcdsaProvider.HashAlgorithm = GetCngAlgorithm(sigHash); return(EcdsaProvider.VerifyHash(digest, sigBlob)); #endif // !TSS_USE_BCRYPT && !__MonoCS__ } // Should never be here Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm"); return(false); } // VerifySignature()
/// <summary> /// Sign using a non-default hash algorithm. /// </summary> /// <param name="data"></param> /// <param name="sigHash"></param> /// <returns></returns> public ISignatureUnion SignData(byte[] data, TpmAlgId sigHash) { #if TSS_USE_BCRYPT Debug.Assert(Key != UIntPtr.Zero); #endif var rsaParams = PublicParms.parameters as RsaParms; if (rsaParams != null) { #if !TSS_USE_BCRYPT Debug.Assert(RsaProvider != null); #endif TpmAlgId sigScheme = rsaParams.scheme.GetUnionSelector(); switch (sigScheme) { case TpmAlgId.Rsassa: { if (sigHash == TpmAlgId.Null) { sigHash = (rsaParams.scheme as SigSchemeRsassa).hashAlg; } byte[] digest = CryptoLib.HashData(sigHash, data); #if TSS_USE_BCRYPT byte[] sig = Key.SignHash(digest, BcryptScheme.Rsassa, sigHash); #else byte[] sig = RsaProvider.SignData(data, CryptoLib.GetHashName(sigHash)); #endif return(new SignatureRsassa(sigHash, sig)); } case TpmAlgId.Rsapss: { #if true Globs.Throw <ArgumentException>("SignData(): PSS scheme is not supported"); return(null); #else if (sigHash == TpmAlgId.Null) { sigHash = (rsaParams.scheme as SigSchemeRsapss).hashAlg; } #if TSS_USE_BCRYPT byte[] sig = BCryptInterface.SignHash(KeyHandle, digest, sigHash, false); #else var rr = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize); byte[] sig = rr.PssSign(digest, sigHash); #endif return(new SignatureRsapss(sigHash, sig)); #endif // false } } Globs.Throw <ArgumentException>("Unsupported signature scheme"); return(null); } var eccParms = PublicParms.parameters as EccParms; if (eccParms != null) { if (eccParms.scheme.GetUnionSelector() != TpmAlgId.Ecdsa) { Globs.Throw <ArgumentException>("Unsupported ECC sig scheme"); return(null); } if (sigHash == TpmAlgId.Null) { sigHash = (eccParms.scheme as SigSchemeEcdsa).hashAlg; } byte[] digest = CryptoLib.HashData(sigHash, data); #if TSS_USE_BCRYPT //throw new NotImplementedException("ECC signing with BCrypt is not implemented"); byte[] sig = Key.SignHash(digest, BcryptScheme.Ecdsa, sigHash); int len = sig.Length / 2; return(new SignatureEcdsa(sigHash, Globs.CopyData(sig, 0, len), Globs.CopyData(sig, len, len))); #elif !__MonoCS__ Debug.Assert(EcdsaProvider != null); EcdsaProvider.HashAlgorithm = GetCngAlgorithm(sigHash); byte[] sig = EcdsaProvider.SignData(data); int fragLen = sig.Length / 2; var r = Globs.CopyData(sig, 0, fragLen); var s = Globs.CopyData(sig, fragLen, fragLen); return(new SignatureEcdsa(sigHash, r, s)); #endif // !TSS_USE_BCRYPT && !__MonoCS__ } // Should never be here Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm"); return(null); } // SignData()