diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-09-16 16:21:56 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-09-16 16:21:56 +0700 |
commit | ba3292784635dc3f06070e4c99c01ed630818940 (patch) | |
tree | 7a4c19ad7d721c4c5a9c1e8924fc0a6bc2c199ea /crypto/src | |
parent | Reduce single-bit extractions from scalars (diff) | |
download | BouncyCastle.NET-ed25519-ba3292784635dc3f06070e4c99c01ed630818940.tar.xz |
Fixed Rfc3211WrapEngine processing of messages over 127 bytes.
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/crypto/engines/RFC3211WrapEngine.cs | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/crypto/src/crypto/engines/RFC3211WrapEngine.cs b/crypto/src/crypto/engines/RFC3211WrapEngine.cs index 4e3af5227..86480145c 100644 --- a/crypto/src/crypto/engines/RFC3211WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3211WrapEngine.cs @@ -32,10 +32,10 @@ namespace Org.BouncyCastle.Crypto.Engines if (param is ParametersWithRandom) { - ParametersWithRandom p = (ParametersWithRandom) param; + ParametersWithRandom p = (ParametersWithRandom)param; - this.rand = p.Random; - this.param = (ParametersWithIV) p.Parameters; + this.rand = p.Random; + this.param = p.Parameters as ParametersWithIV; } else { @@ -44,9 +44,12 @@ namespace Org.BouncyCastle.Crypto.Engines rand = new SecureRandom(); } - this.param = (ParametersWithIV) param; - } - } + this.param = param as ParametersWithIV; + } + + if (null == this.param) + throw new ArgumentException("RFC3211Wrap requires an IV", "param"); + } public virtual string AlgorithmName { @@ -59,11 +62,11 @@ namespace Org.BouncyCastle.Crypto.Engines int inLen) { if (!forWrapping) - { throw new InvalidOperationException("not set for wrapping"); - } + if (inLen > 255 || inLen < 0) + throw new ArgumentException("input must be from 0 to 255 bytes", "inLen"); - engine.Init(true, param); + engine.Init(true, param); int blockSize = engine.GetBlockSize(); byte[] cekBlock; @@ -78,15 +81,16 @@ namespace Org.BouncyCastle.Crypto.Engines } cekBlock[0] = (byte)inLen; - cekBlock[1] = (byte)~inBytes[inOff]; - cekBlock[2] = (byte)~inBytes[inOff + 1]; - cekBlock[3] = (byte)~inBytes[inOff + 2]; Array.Copy(inBytes, inOff, cekBlock, 4, inLen); rand.NextBytes(cekBlock, inLen + 4, cekBlock.Length - inLen - 4); - for (int i = 0; i < cekBlock.Length; i += blockSize) + cekBlock[1] = (byte)~cekBlock[4]; + cekBlock[2] = (byte)~cekBlock[4 + 1]; + cekBlock[3] = (byte)~cekBlock[4 + 2]; + + for (int i = 0; i < cekBlock.Length; i += blockSize) { engine.ProcessBlock(cekBlock, i, cekBlock, i); } @@ -142,27 +146,34 @@ namespace Org.BouncyCastle.Crypto.Engines engine.ProcessBlock(cekBlock, i, cekBlock, i); } - if ((cekBlock[0] & 0xff) > cekBlock.Length - 4) - { - throw new InvalidCipherTextException("wrapped key corrupted"); - } + bool invalidLength = (int)cekBlock[0] > (cekBlock.Length - 4); - byte[] key = new byte[cekBlock[0] & 0xff]; + byte[] key; + if (invalidLength) + { + key = new byte[cekBlock.Length - 4]; + } + else + { + key = new byte[cekBlock[0]]; + } - Array.Copy(cekBlock, 4, key, 0, cekBlock[0]); + Array.Copy(cekBlock, 4, key, 0, key.Length); // Note: Using constant time comparison int nonEqual = 0; for (int i = 0; i != 3; i++) { byte check = (byte)~cekBlock[1 + i]; - nonEqual |= (check ^ key[i]); - } + nonEqual |= (check ^ cekBlock[4 + i]); + } + + Array.Clear(cekBlock, 0, cekBlock.Length); - if (nonEqual != 0) - throw new InvalidCipherTextException("wrapped key fails checksum"); + if (nonEqual != 0 | invalidLength) + throw new InvalidCipherTextException("wrapped key corrupted"); - return key; + return key; } } } |