diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-01-31 17:57:10 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-01-31 17:57:10 +0700 |
commit | 2ccd54b85c8157c146b96a751b8c2c08483d345e (patch) | |
tree | 4e30dc4ca5a34dcefa52e7c6e7cedd24eb99c90f | |
parent | Port of X25519/X448 field updates from bc-java (diff) | |
download | BouncyCastle.NET-ed25519-2ccd54b85c8157c146b96a751b8c2c08483d345e.tar.xz |
EdDSA: guard against pub key mismatch
-rw-r--r-- | crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs | 34 | ||||
-rw-r--r-- | crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs | 34 | ||||
-rw-r--r-- | crypto/src/crypto/signers/Ed25519Signer.cs | 10 | ||||
-rw-r--r-- | crypto/src/crypto/signers/Ed25519ctxSigner.cs | 10 | ||||
-rw-r--r-- | crypto/src/crypto/signers/Ed25519phSigner.cs | 6 | ||||
-rw-r--r-- | crypto/src/crypto/signers/Ed448Signer.cs | 10 | ||||
-rw-r--r-- | crypto/src/crypto/signers/Ed448phSigner.cs | 6 |
7 files changed, 62 insertions, 48 deletions
diff --git a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs index 8046a0b1b..531bca0e9 100644 --- a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs @@ -16,6 +16,8 @@ namespace Org.BouncyCastle.Crypto.Parameters private readonly byte[] data = new byte[KeySize]; + private Ed25519PublicKeyParameters cachedPublicKey; + public Ed25519PrivateKeyParameters(SecureRandom random) : base(true) { @@ -47,23 +49,33 @@ namespace Org.BouncyCastle.Crypto.Parameters public Ed25519PublicKeyParameters GeneratePublicKey() { - byte[] publicKey = new byte[Ed25519.PublicKeySize]; - Ed25519.GeneratePublicKey(data, 0, publicKey, 0); - return new Ed25519PublicKeyParameters(publicKey, 0); + lock (data) + { + if (null == cachedPublicKey) + { + byte[] publicKey = new byte[Ed25519.PublicKeySize]; + Ed25519.GeneratePublicKey(data, 0, publicKey, 0); + cachedPublicKey = new Ed25519PublicKeyParameters(publicKey, 0); + } + + return cachedPublicKey; + } } + [Obsolete("Use overload that doesn't take a public key")] public void Sign(Ed25519.Algorithm algorithm, Ed25519PublicKeyParameters publicKey, byte[] ctx, byte[] msg, int msgOff, int msgLen, byte[] sig, int sigOff) { + Sign(algorithm, ctx, msg, msgOff, msgLen, sig, sigOff); + } + + public void Sign(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, + byte[] sig, int sigOff) + { + Ed25519PublicKeyParameters publicKey = GeneratePublicKey(); + byte[] pk = new byte[Ed25519.PublicKeySize]; - if (null == publicKey) - { - Ed25519.GeneratePublicKey(data, 0, pk, 0); - } - else - { - publicKey.Encode(pk, 0); - } + publicKey.Encode(pk, 0); switch (algorithm) { diff --git a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs index f2fc4d533..1b38143fa 100644 --- a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs @@ -16,6 +16,8 @@ namespace Org.BouncyCastle.Crypto.Parameters private readonly byte[] data = new byte[KeySize]; + private Ed448PublicKeyParameters cachedPublicKey; + public Ed448PrivateKeyParameters(SecureRandom random) : base(true) { @@ -47,23 +49,33 @@ namespace Org.BouncyCastle.Crypto.Parameters public Ed448PublicKeyParameters GeneratePublicKey() { - byte[] publicKey = new byte[Ed448.PublicKeySize]; - Ed448.GeneratePublicKey(data, 0, publicKey, 0); - return new Ed448PublicKeyParameters(publicKey, 0); + lock (data) + { + if (null == cachedPublicKey) + { + byte[] publicKey = new byte[Ed448.PublicKeySize]; + Ed448.GeneratePublicKey(data, 0, publicKey, 0); + cachedPublicKey = new Ed448PublicKeyParameters(publicKey, 0); + } + + return cachedPublicKey; + } } + [Obsolete("Use overload that doesn't take a public key")] public void Sign(Ed448.Algorithm algorithm, Ed448PublicKeyParameters publicKey, byte[] ctx, byte[] msg, int msgOff, int msgLen, byte[] sig, int sigOff) { + Sign(algorithm, ctx, msg, msgOff, msgLen, sig, sigOff); + } + + public void Sign(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, + byte[] sig, int sigOff) + { + Ed448PublicKeyParameters publicKey = GeneratePublicKey(); + byte[] pk = new byte[Ed448.PublicKeySize]; - if (null == publicKey) - { - Ed448.GeneratePublicKey(data, 0, pk, 0); - } - else - { - publicKey.Encode(pk, 0); - } + publicKey.Encode(pk, 0); switch (algorithm) { diff --git a/crypto/src/crypto/signers/Ed25519Signer.cs b/crypto/src/crypto/signers/Ed25519Signer.cs index a916601e6..e58d14ea4 100644 --- a/crypto/src/crypto/signers/Ed25519Signer.cs +++ b/crypto/src/crypto/signers/Ed25519Signer.cs @@ -32,10 +32,8 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters? - this.privateKey = (Ed25519PrivateKeyParameters)parameters; - this.publicKey = privateKey.GeneratePublicKey(); + this.publicKey = null; } else { @@ -61,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Signers if (!forSigning || null == privateKey) throw new InvalidOperationException("Ed25519Signer not initialised for signature generation."); - return buffer.GenerateSignature(privateKey, publicKey); + return buffer.GenerateSignature(privateKey); } public virtual bool VerifySignature(byte[] signature) @@ -79,7 +77,7 @@ namespace Org.BouncyCastle.Crypto.Signers private class Buffer : MemoryStream { - internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey, Ed25519PublicKeyParameters publicKey) + internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey) { lock (this) { @@ -91,7 +89,7 @@ namespace Org.BouncyCastle.Crypto.Signers int count = (int)Position; #endif byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize]; - privateKey.Sign(Ed25519.Algorithm.Ed25519, publicKey, null, buf, 0, count, signature, 0); + privateKey.Sign(Ed25519.Algorithm.Ed25519, null, buf, 0, count, signature, 0); Reset(); return signature; } diff --git a/crypto/src/crypto/signers/Ed25519ctxSigner.cs b/crypto/src/crypto/signers/Ed25519ctxSigner.cs index ab7201b62..2b5296e96 100644 --- a/crypto/src/crypto/signers/Ed25519ctxSigner.cs +++ b/crypto/src/crypto/signers/Ed25519ctxSigner.cs @@ -34,10 +34,8 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters? - this.privateKey = (Ed25519PrivateKeyParameters)parameters; - this.publicKey = privateKey.GeneratePublicKey(); + this.publicKey = null; } else { @@ -63,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Signers if (!forSigning || null == privateKey) throw new InvalidOperationException("Ed25519ctxSigner not initialised for signature generation."); - return buffer.GenerateSignature(privateKey, publicKey, context); + return buffer.GenerateSignature(privateKey, context); } public virtual bool VerifySignature(byte[] signature) @@ -81,7 +79,7 @@ namespace Org.BouncyCastle.Crypto.Signers private class Buffer : MemoryStream { - internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey, Ed25519PublicKeyParameters publicKey, byte[] ctx) + internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey, byte[] ctx) { lock (this) { @@ -93,7 +91,7 @@ namespace Org.BouncyCastle.Crypto.Signers int count = (int)Position; #endif byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize]; - privateKey.Sign(Ed25519.Algorithm.Ed25519ctx, publicKey, ctx, buf, 0, count, signature, 0); + privateKey.Sign(Ed25519.Algorithm.Ed25519ctx, ctx, buf, 0, count, signature, 0); Reset(); return signature; } diff --git a/crypto/src/crypto/signers/Ed25519phSigner.cs b/crypto/src/crypto/signers/Ed25519phSigner.cs index 2538b16f5..cb3c3080a 100644 --- a/crypto/src/crypto/signers/Ed25519phSigner.cs +++ b/crypto/src/crypto/signers/Ed25519phSigner.cs @@ -33,10 +33,8 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - // TODO Allow AsymmetricCipherKeyPair to be a CipherParameters? - this.privateKey = (Ed25519PrivateKeyParameters)parameters; - this.publicKey = privateKey.GeneratePublicKey(); + this.publicKey = null; } else { @@ -67,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Signers throw new InvalidOperationException("Prehash digest failed"); byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize]; - privateKey.Sign(Ed25519.Algorithm.Ed25519ph, publicKey, context, msg, 0, Ed25519.PrehashSize, signature, 0); + privateKey.Sign(Ed25519.Algorithm.Ed25519ph, context, msg, 0, Ed25519.PrehashSize, signature, 0); return signature; } diff --git a/crypto/src/crypto/signers/Ed448Signer.cs b/crypto/src/crypto/signers/Ed448Signer.cs index b0563d544..9d1495f2e 100644 --- a/crypto/src/crypto/signers/Ed448Signer.cs +++ b/crypto/src/crypto/signers/Ed448Signer.cs @@ -34,10 +34,8 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters? - this.privateKey = (Ed448PrivateKeyParameters)parameters; - this.publicKey = privateKey.GeneratePublicKey(); + this.publicKey = null; } else { @@ -63,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Signers if (!forSigning || null == privateKey) throw new InvalidOperationException("Ed448Signer not initialised for signature generation."); - return buffer.GenerateSignature(privateKey, publicKey, context); + return buffer.GenerateSignature(privateKey, context); } public virtual bool VerifySignature(byte[] signature) @@ -81,7 +79,7 @@ namespace Org.BouncyCastle.Crypto.Signers private class Buffer : MemoryStream { - internal byte[] GenerateSignature(Ed448PrivateKeyParameters privateKey, Ed448PublicKeyParameters publicKey, byte[] ctx) + internal byte[] GenerateSignature(Ed448PrivateKeyParameters privateKey, byte[] ctx) { lock (this) { @@ -93,7 +91,7 @@ namespace Org.BouncyCastle.Crypto.Signers int count = (int)Position; #endif byte[] signature = new byte[Ed448PrivateKeyParameters.SignatureSize]; - privateKey.Sign(Ed448.Algorithm.Ed448, publicKey, ctx, buf, 0, count, signature, 0); + privateKey.Sign(Ed448.Algorithm.Ed448, ctx, buf, 0, count, signature, 0); Reset(); return signature; } diff --git a/crypto/src/crypto/signers/Ed448phSigner.cs b/crypto/src/crypto/signers/Ed448phSigner.cs index d656c1392..f01b6bfd4 100644 --- a/crypto/src/crypto/signers/Ed448phSigner.cs +++ b/crypto/src/crypto/signers/Ed448phSigner.cs @@ -33,10 +33,8 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - // TODO Allow AsymmetricCipherKeyPair to be a CipherParameters? - this.privateKey = (Ed448PrivateKeyParameters)parameters; - this.publicKey = privateKey.GeneratePublicKey(); + this.publicKey = null; } else { @@ -67,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Signers throw new InvalidOperationException("Prehash digest failed"); byte[] signature = new byte[Ed448PrivateKeyParameters.SignatureSize]; - privateKey.Sign(Ed448.Algorithm.Ed448ph, publicKey, context, msg, 0, Ed448.PrehashSize, signature, 0); + privateKey.Sign(Ed448.Algorithm.Ed448ph, context, msg, 0, Ed448.PrehashSize, signature, 0); return signature; } |