From ba3292784635dc3f06070e4c99c01ed630818940 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sun, 16 Sep 2018 16:21:56 +0700 Subject: Fixed Rfc3211WrapEngine processing of messages over 127 bytes. --- crypto/Readme.html | 9 ++++ crypto/src/crypto/engines/RFC3211WrapEngine.cs | 59 +++++++++++++++----------- crypto/test/src/crypto/test/RFC3211WrapTest.cs | 2 +- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/crypto/Readme.html b/crypto/Readme.html index 72e97516f..1d1b74f1c 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html @@ -30,6 +30,8 @@
  • Notes:
      +
    1. + Release 1.8.4
    2. Release 1.8.3
    3. @@ -294,6 +296,13 @@ We state, where EC MQV has not otherwise been disabled or removed:

      Notes:

      +

      Release 1.8.4, TBD

      + +
      Defects Fixed
      +
        +
      • Rfc3211WrapEngine would not properly handle messages longer than 127 bytes. This has been fixed.
      • +
      +

      Release 1.8.3, Saturday August 11, 2018

      IMPORTANT
      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; } } } diff --git a/crypto/test/src/crypto/test/RFC3211WrapTest.cs b/crypto/test/src/crypto/test/RFC3211WrapTest.cs index bdef7c999..91dea34dd 100644 --- a/crypto/test/src/crypto/test/RFC3211WrapTest.cs +++ b/crypto/test/src/crypto/test/RFC3211WrapTest.cs @@ -115,7 +115,7 @@ namespace Org.BouncyCastle.Crypto.Tests } catch (InvalidCipherTextException e) { - if (!e.Message.Equals("wrapped key fails checksum")) + if (!e.Message.Equals("wrapped key corrupted")) { Fail("wrong exception"); } -- cgit 1.4.1