diff options
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/crypto/engines/AesWrapPadEngine.cs | 13 | ||||
-rw-r--r-- | crypto/src/crypto/engines/AriaWrapPadEngine.cs | 13 | ||||
-rw-r--r-- | crypto/src/crypto/engines/RFC3394WrapEngine.cs | 119 | ||||
-rw-r--r-- | crypto/src/crypto/engines/Rfc5649WrapEngine.cs | 271 | ||||
-rw-r--r-- | crypto/src/security/GeneratorUtilities.cs | 15 | ||||
-rw-r--r-- | crypto/src/security/ParameterUtilities.cs | 15 | ||||
-rw-r--r-- | crypto/src/security/WrapperUtilities.cs | 17 |
7 files changed, 394 insertions, 69 deletions
diff --git a/crypto/src/crypto/engines/AesWrapPadEngine.cs b/crypto/src/crypto/engines/AesWrapPadEngine.cs new file mode 100644 index 000000000..534dfd128 --- /dev/null +++ b/crypto/src/crypto/engines/AesWrapPadEngine.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class AesWrapPadEngine + : Rfc5649WrapEngine + { + public AesWrapPadEngine() + : base(AesUtilities.CreateEngine()) + { + } + } +} diff --git a/crypto/src/crypto/engines/AriaWrapPadEngine.cs b/crypto/src/crypto/engines/AriaWrapPadEngine.cs new file mode 100644 index 000000000..49bebcd80 --- /dev/null +++ b/crypto/src/crypto/engines/AriaWrapPadEngine.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class AriaWrapPadEngine + : Rfc5649WrapEngine + { + public AriaWrapPadEngine() + : base(new AriaEngine()) + { + } + } +} diff --git a/crypto/src/crypto/engines/RFC3394WrapEngine.cs b/crypto/src/crypto/engines/RFC3394WrapEngine.cs index e1368f25b..5713bb08a 100644 --- a/crypto/src/crypto/engines/RFC3394WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3394WrapEngine.cs @@ -5,23 +5,23 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Engines { - /// <remarks> - /// An implementation of the AES Key Wrapper from the NIST Key Wrap - /// Specification as described in RFC 3394. - /// <p/> - /// For further details see: <a href="http://www.ietf.org/rfc/rfc3394.txt">http://www.ietf.org/rfc/rfc3394.txt</a> - /// and <a href="http://csrc.nist.gov/encryption/kms/key-wrap.pdf">http://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>. - /// </remarks> - public class Rfc3394WrapEngine + /// <summary>An implementation of the AES Key Wrap with Padding specification as described in RFC 3349.</summary> + /// <remarks> + /// For further details see: Schaad, J. and R. Housley, "Advanced Encryption Standard (AES) Key Wrap Algorithm", + /// RFC 3394, DOI 10.17487/RFC3394, September 2002, <https://www.rfc-editor.org/info/rfc3394>, and + /// http://csrc.nist.gov/encryption/kms/key-wrap.pdf. + /// </remarks> + public class Rfc3394WrapEngine : IWrapper { - private readonly IBlockCipher engine; - private readonly bool wrapCipherMode; + private static readonly byte[] DefaultIV = { 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 }; - private KeyParameter param; - private bool forWrapping; + private readonly IBlockCipher m_engine; + private readonly bool m_wrapCipherMode; + private readonly byte[] m_iv = new byte[8]; - private byte[] iv = { 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 }; + private KeyParameter m_key = null; + private bool m_forWrapping = true; public Rfc3394WrapEngine(IBlockCipher engine) : this(engine, false) @@ -30,13 +30,15 @@ namespace Org.BouncyCastle.Crypto.Engines public Rfc3394WrapEngine(IBlockCipher engine, bool useReverseDirection) { - this.engine = engine; - this.wrapCipherMode = !useReverseDirection; + m_engine = engine; + m_wrapCipherMode = !useReverseDirection; } + public virtual string AlgorithmName => m_engine.AlgorithmName; + public virtual void Init(bool forWrapping, ICipherParameters parameters) { - this.forWrapping = forWrapping; + m_forWrapping = forWrapping; if (parameters is ParametersWithRandom withRandom) { @@ -45,17 +47,17 @@ namespace Org.BouncyCastle.Crypto.Engines if (parameters is KeyParameter keyParameter) { - this.param = keyParameter; - } - else if (parameters is ParametersWithIV withIV) + m_key = keyParameter; + Array.Copy(DefaultIV, 0, m_iv, 0, 8); + } + else if (parameters is ParametersWithIV withIV) { byte[] iv = withIV.GetIV(); - if (iv.Length != 8) - throw new ArgumentException("IV length not equal to 8", "parameters"); + throw new ArgumentException("IV length not equal to 8", nameof(parameters)); - this.iv = iv; - this.param = (KeyParameter)withIV.Parameters; + m_key = (KeyParameter)withIV.Parameters; + Array.Copy(iv, 0, m_iv, 0, 8); } else { @@ -63,14 +65,9 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public virtual string AlgorithmName - { - get { return engine.AlgorithmName; } - } - public virtual byte[] Wrap(byte[] input, int inOff, int inLen) { - if (!forWrapping) + if (!m_forWrapping) throw new InvalidOperationException("not set for wrapping"); if (inLen < 8) throw new DataLengthException("wrap data must be at least 8 bytes"); @@ -80,35 +77,33 @@ namespace Org.BouncyCastle.Crypto.Engines if ((n * 8) != inLen) throw new DataLengthException("wrap data must be a multiple of 8 bytes"); - engine.Init(wrapCipherMode, param); + m_engine.Init(m_wrapCipherMode, m_key); - byte[] block = new byte[inLen + iv.Length]; - Array.Copy(iv, 0, block, 0, iv.Length); - Array.Copy(input, inOff, block, iv.Length, inLen); + byte[] block = new byte[inLen + 8]; + Array.Copy(m_iv, 0, block, 0, 8); + Array.Copy(input, inOff, block, 8, inLen); if (n == 1) { - engine.ProcessBlock(block, 0, block, 0); + m_engine.ProcessBlock(block, 0, block, 0); } else { - byte[] buf = new byte[8 + iv.Length]; + byte[] buf = new byte[16]; for (int j = 0; j != 6; j++) { for (int i = 1; i <= n; i++) { - Array.Copy(block, 0, buf, 0, iv.Length); - Array.Copy(block, 8 * i, buf, iv.Length, 8); - engine.ProcessBlock(buf, 0, buf, 0); + Array.Copy(block, 0, buf, 0, 8); + Array.Copy(block, 8 * i, buf, 8, 8); + m_engine.ProcessBlock(buf, 0, buf, 0); - int t = n * j + i; - for (int k = 1; t != 0; k++) + uint t = (uint)(n * j + i); + for (int k = 1; t != 0U; k++) { - byte v = (byte)t; - - buf[iv.Length - k] ^= v; - t = (int) ((uint)t >> 8); + buf[8 - k] ^= (byte)t; + t >>= 8; } Array.Copy(buf, 0, block, 0, 8); @@ -122,7 +117,7 @@ namespace Org.BouncyCastle.Crypto.Engines public virtual byte[] Unwrap(byte[] input, int inOff, int inLen) { - if (forWrapping) + if (m_forWrapping) throw new InvalidOperationException("not set for unwrapping"); if (inLen < 16) throw new InvalidCipherTextException("unwrap data too short"); @@ -132,49 +127,47 @@ namespace Org.BouncyCastle.Crypto.Engines if ((n * 8) != inLen) throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes"); - engine.Init(!wrapCipherMode, param); + m_engine.Init(!m_wrapCipherMode, m_key); - byte[] block = new byte[inLen - iv.Length]; - byte[] a = new byte[iv.Length]; - byte[] buf = new byte[8 + iv.Length]; + byte[] block = new byte[inLen - 8]; + byte[] a = new byte[8]; + byte[] buf = new byte[16]; n = n - 1; if (n == 1) { - engine.ProcessBlock(input, inOff, buf, 0); - Array.Copy(buf, 0, a, 0, iv.Length); - Array.Copy(buf, iv.Length, block, 0, 8); + m_engine.ProcessBlock(input, inOff, buf, 0); + Array.Copy(buf, 0, a, 0, 8); + Array.Copy(buf, 8, block, 0, 8); } else { - Array.Copy(input, inOff, a, 0, iv.Length); - Array.Copy(input, inOff + iv.Length, block, 0, inLen - iv.Length); + Array.Copy(input, inOff, a, 0, 8); + Array.Copy(input, inOff + 8, block, 0, inLen - 8); for (int j = 5; j >= 0; j--) { for (int i = n; i >= 1; i--) { - Array.Copy(a, 0, buf, 0, iv.Length); - Array.Copy(block, 8 * (i - 1), buf, iv.Length, 8); + Array.Copy(a, 0, buf, 0, 8); + Array.Copy(block, 8 * (i - 1), buf, 8, 8); - int t = n * j + i; + uint t = (uint)(n * j + i); for (int k = 1; t != 0; k++) { - byte v = (byte)t; - - buf[iv.Length - k] ^= v; - t = (int) ((uint)t >> 8); + buf[8 - k] ^= (byte)t; + t >>= 8; } - engine.ProcessBlock(buf, 0, buf, 0); + m_engine.ProcessBlock(buf, 0, buf, 0); Array.Copy(buf, 0, a, 0, 8); Array.Copy(buf, 8, block, 8 * (i - 1), 8); } } } - if (!Arrays.FixedTimeEquals(a, iv)) + if (!Arrays.FixedTimeEquals(a, m_iv)) throw new InvalidCipherTextException("checksum failed"); return block; diff --git a/crypto/src/crypto/engines/Rfc5649WrapEngine.cs b/crypto/src/crypto/engines/Rfc5649WrapEngine.cs new file mode 100644 index 000000000..09830c7e8 --- /dev/null +++ b/crypto/src/crypto/engines/Rfc5649WrapEngine.cs @@ -0,0 +1,271 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// <summary>An implementation of the AES Key Wrap with Padding specification as described in RFC 5649.</summary> + /// <remarks> + /// For further details see: Housley, R. and M. Dworkin, "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm", + /// RFC 5649, DOI 10.17487/RFC5649, September 2009, <https://www.rfc-editor.org/info/rfc5649>, and + /// http://csrc.nist.gov/encryption/kms/key-wrap.pdf. + /// </remarks> + public class Rfc5649WrapEngine + : IWrapper + { + // The AIV as defined in the RFC + private static readonly byte[] DefaultIV = { 0xa6, 0x59, 0x59, 0xa6 }; + + private readonly IBlockCipher m_engine; + private readonly byte[] m_preIV = new byte[4]; + + private KeyParameter m_key = null; + private bool m_forWrapping = true; + + public Rfc5649WrapEngine(IBlockCipher engine) + { + m_engine = engine; + } + + public virtual string AlgorithmName => m_engine.AlgorithmName; + + public virtual void Init(bool forWrapping, ICipherParameters parameters) + { + m_forWrapping = forWrapping; + + if (parameters is ParametersWithRandom withRandom) + { + parameters = withRandom.Parameters; + } + + if (parameters is KeyParameter keyParameter) + { + m_key = keyParameter; + Array.Copy(DefaultIV, 0, m_preIV, 0, 4); + } + else if (parameters is ParametersWithIV withIV) + { + byte[] iv = withIV.GetIV(); + if (iv.Length != 4) + throw new ArgumentException("IV length not equal to 4", nameof(parameters)); + + m_key = (KeyParameter)withIV.Parameters; + Array.Copy(iv, 0, m_preIV, 0, 4); + } + else + { + // TODO Throw an exception for bad parameters? + } + } + + public virtual byte[] Wrap(byte[] input, int inOff, int length) + { + if (!m_forWrapping) + throw new InvalidOperationException("not set for wrapping"); + + byte[] iv = new byte[8]; + + // copy in the fixed portion of the AIV + Array.Copy(m_preIV, 0, iv, 0, 4); + // copy in the MLI (size of key to be wrapped) after the AIV + Pack.UInt32_To_BE((uint)length, iv, 4); + + // get the relevant plaintext to be wrapped + byte[] relevantPlaintext = new byte[length]; + Array.Copy(input, inOff, relevantPlaintext, 0, length); + byte[] paddedPlaintext = PadPlaintext(relevantPlaintext); + + if (paddedPlaintext.Length == 8) + { + // if the padded plaintext contains exactly 8 octets, + // then prepend iv and encrypt using AES in ECB mode. + + // prepend the IV to the plaintext + byte[] paddedPlainTextWithIV = new byte[paddedPlaintext.Length + iv.Length]; + Array.Copy(iv, 0, paddedPlainTextWithIV, 0, iv.Length); + Array.Copy(paddedPlaintext, 0, paddedPlainTextWithIV, iv.Length, paddedPlaintext.Length); + + m_engine.Init(true, m_key); + for (int i = 0, blockSize = m_engine.GetBlockSize(); i < paddedPlainTextWithIV.Length; i += blockSize) + { + m_engine.ProcessBlock(paddedPlainTextWithIV, i, paddedPlainTextWithIV, i); + } + + return paddedPlainTextWithIV; + } + else + { + // otherwise, apply the RFC 3394 wrap to + // the padded plaintext with the new IV + Rfc3394WrapEngine wrapper = new Rfc3394WrapEngine(m_engine); + ParametersWithIV paramsWithIV = new ParametersWithIV(m_key, iv); + wrapper.Init(true, paramsWithIV); + return wrapper.Wrap(paddedPlaintext, 0, paddedPlaintext.Length); + } + } + + public virtual byte[] Unwrap(byte[] input, int inOff, int length) + { + if (m_forWrapping) + throw new InvalidOperationException("not set for unwrapping"); + + int n = length / 8; + + if ((n * 8) != length) + throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes"); + + if (n <= 1) + throw new InvalidCipherTextException("unwrap data must be at least 16 bytes"); + + byte[] relevantCiphertext = new byte[length]; + Array.Copy(input, inOff, relevantCiphertext, 0, length); + byte[] decrypted = new byte[length]; + byte[] paddedPlaintext; + + byte[] extractedAIV = new byte[8]; + + if (n == 2) + { + // When there are exactly two 64-bit blocks of ciphertext, + // they are decrypted as a single block using AES in ECB. + m_engine.Init(false, m_key); + for (int i = 0, blockSize = m_engine.GetBlockSize(); i < relevantCiphertext.Length; i += blockSize) + { + m_engine.ProcessBlock(relevantCiphertext, i, decrypted, i); + } + + // extract the AIV + Array.Copy(decrypted, 0, extractedAIV, 0, 8); + paddedPlaintext = new byte[decrypted.Length - 8]; + Array.Copy(decrypted, 8, paddedPlaintext, 0, paddedPlaintext.Length); + } + else + { + // Otherwise, unwrap as per RFC 3394 but don't check IV the same way + decrypted = Rfc3394UnwrapNoIvCheck(input, inOff, length, extractedAIV); + paddedPlaintext = decrypted; + } + + // Decompose the extracted AIV to the fixed portion and the MLI + byte[] extractedHighOrderAIV = new byte[4]; + Array.Copy(extractedAIV, 0, extractedHighOrderAIV, 0, 4); + int mli = (int)Pack.BE_To_UInt32(extractedAIV, 4); + + // Even if a check fails we still continue and check everything + // else in order to avoid certain timing based side-channel attacks. + + // Check the fixed portion of the AIV + bool isValid = Arrays.FixedTimeEquals(extractedHighOrderAIV, m_preIV); + + // Check the MLI against the actual length + int upperBound = paddedPlaintext.Length; + int lowerBound = upperBound - 8; + if (mli <= lowerBound) + { + isValid = false; + } + if (mli > upperBound) + { + isValid = false; + } + + // Check the number of padding zeros + int expectedZeros = upperBound - mli; + if (expectedZeros >= 8 || expectedZeros < 0) + { + // We have to pick a "typical" amount of padding to avoid timing attacks. + isValid = false; + expectedZeros = 4; + } + + byte[] zeros = new byte[expectedZeros]; + byte[] pad = new byte[expectedZeros]; + Array.Copy(paddedPlaintext, paddedPlaintext.Length - expectedZeros, pad, 0, expectedZeros); + if (!Arrays.FixedTimeEquals(pad, zeros)) + { + isValid = false; + } + + if (!isValid) + throw new InvalidCipherTextException("checksum failed"); + + // Extract the plaintext from the padded plaintext + byte[] plaintext = new byte[mli]; + Array.Copy(paddedPlaintext, 0, plaintext, 0, plaintext.Length); + + return plaintext; + } + + /** + * Performs steps 1 and 2 of the unwrap process defined in RFC 3394. + * This code is duplicated from RFC3394WrapEngine because that class + * will throw an error during unwrap because the IV won't match up. + * + * @param in + * @param inOff + * @param inLen + * @return Unwrapped data. + */ + private byte[] Rfc3394UnwrapNoIvCheck(byte[] input, int inOff, int inLen, byte[] extractedAIV) + { + byte[] block = new byte[inLen - 8]; + byte[] buf = new byte[16]; + + Array.Copy(input, inOff, buf, 0, 8); + Array.Copy(input, inOff + 8, block, 0, inLen - 8); + + m_engine.Init(false, m_key); + + int n = inLen / 8; + n = n - 1; + + for (int j = 5; j >= 0; j--) + { + for (int i = n; i >= 1; i--) + { + Array.Copy(block, 8 * (i - 1), buf, 8, 8); + + uint t = (uint)(n * j + i); + for (int k = 1; t != 0U; k++) + { + buf[8 - k] ^= (byte)t; + t >>= 8; + } + + m_engine.ProcessBlock(buf, 0, buf, 0); + + Array.Copy(buf, 8, block, 8 * (i - 1), 8); + } + } + + Array.Copy(buf, 0, extractedAIV, 0, 8); + + return block; + } + + /** + * Pads the plaintext (i.e., the key to be wrapped) + * as per section 4.1 of RFC 5649. + * + * @param plaintext The key being wrapped. + * @return The padded key. + */ + private static byte[] PadPlaintext(byte[] plaintext) + { + int plaintextLength = plaintext.Length; + int numOfZerosToAppend = (8 - (plaintextLength % 8)) % 8; + byte[] paddedPlaintext = new byte[plaintextLength + numOfZerosToAppend]; + Array.Copy(plaintext, 0, paddedPlaintext, 0, plaintextLength); + if (numOfZerosToAppend != 0) + { + // plaintext (i.e., key to be wrapped) does not have + // a multiple of 8 octet blocks so it must be padded + byte[] zeros = new byte[numOfZerosToAppend]; + Array.Copy(zeros, 0, paddedPlaintext, plaintextLength, numOfZerosToAppend); + } + return paddedPlaintext; + } + } +} diff --git a/crypto/src/security/GeneratorUtilities.cs b/crypto/src/security/GeneratorUtilities.cs index e9525b377..c310cf399 100644 --- a/crypto/src/security/GeneratorUtilities.cs +++ b/crypto/src/security/GeneratorUtilities.cs @@ -45,7 +45,8 @@ namespace Org.BouncyCastle.Security NistObjectIdentifiers.IdAes128Ecb, NistObjectIdentifiers.IdAes128Gcm, NistObjectIdentifiers.IdAes128Ofb, - NistObjectIdentifiers.IdAes128Wrap); + NistObjectIdentifiers.IdAes128Wrap, + NistObjectIdentifiers.IdAes128WrapPad); AddKgAlgorithm("AES192", SecurityUtilities.WrongAes192, NistObjectIdentifiers.IdAes192Cbc, @@ -54,7 +55,8 @@ namespace Org.BouncyCastle.Security NistObjectIdentifiers.IdAes192Ecb, NistObjectIdentifiers.IdAes192Gcm, NistObjectIdentifiers.IdAes192Ofb, - NistObjectIdentifiers.IdAes192Wrap); + NistObjectIdentifiers.IdAes192Wrap, + NistObjectIdentifiers.IdAes192WrapPad); AddKgAlgorithm("AES256", SecurityUtilities.WrongAes256, NistObjectIdentifiers.IdAes256Cbc, @@ -63,7 +65,8 @@ namespace Org.BouncyCastle.Security NistObjectIdentifiers.IdAes256Ecb, NistObjectIdentifiers.IdAes256Gcm, NistObjectIdentifiers.IdAes256Ofb, - NistObjectIdentifiers.IdAes256Wrap); + NistObjectIdentifiers.IdAes256Wrap, + NistObjectIdentifiers.IdAes256WrapPad); AddKgAlgorithm("BLOWFISH", "1.3.6.1.4.1.3029.1.2"); AddKgAlgorithm("CAMELLIA", @@ -76,6 +79,8 @@ namespace Org.BouncyCastle.Security NsriObjectIdentifiers.id_aria128_ctr, NsriObjectIdentifiers.id_aria128_ecb, NsriObjectIdentifiers.id_aria128_gcm, + NsriObjectIdentifiers.id_aria128_kw, + NsriObjectIdentifiers.id_aria128_kwp, NsriObjectIdentifiers.id_aria128_ocb2, NsriObjectIdentifiers.id_aria128_ofb); AddKgAlgorithm("ARIA192", @@ -85,6 +90,8 @@ namespace Org.BouncyCastle.Security NsriObjectIdentifiers.id_aria192_ctr, NsriObjectIdentifiers.id_aria192_ecb, NsriObjectIdentifiers.id_aria192_gcm, + NsriObjectIdentifiers.id_aria192_kw, + NsriObjectIdentifiers.id_aria192_kwp, NsriObjectIdentifiers.id_aria192_ocb2, NsriObjectIdentifiers.id_aria192_ofb); AddKgAlgorithm("ARIA256", @@ -94,6 +101,8 @@ namespace Org.BouncyCastle.Security NsriObjectIdentifiers.id_aria256_ctr, NsriObjectIdentifiers.id_aria256_ecb, NsriObjectIdentifiers.id_aria256_gcm, + NsriObjectIdentifiers.id_aria256_kw, + NsriObjectIdentifiers.id_aria256_kwp, NsriObjectIdentifiers.id_aria256_ocb2, NsriObjectIdentifiers.id_aria256_ofb); AddKgAlgorithm("CAMELLIA128", diff --git a/crypto/src/security/ParameterUtilities.cs b/crypto/src/security/ParameterUtilities.cs index c1f4492b3..690195443 100644 --- a/crypto/src/security/ParameterUtilities.cs +++ b/crypto/src/security/ParameterUtilities.cs @@ -36,7 +36,8 @@ namespace Org.BouncyCastle.Security NistObjectIdentifiers.IdAes128Ecb, NistObjectIdentifiers.IdAes128Gcm, NistObjectIdentifiers.IdAes128Ofb, - NistObjectIdentifiers.IdAes128Wrap); + NistObjectIdentifiers.IdAes128Wrap, + NistObjectIdentifiers.IdAes128WrapPad); AddAlgorithm("AES192", SecurityUtilities.WrongAes192, NistObjectIdentifiers.IdAes192Cbc, @@ -45,7 +46,8 @@ namespace Org.BouncyCastle.Security NistObjectIdentifiers.IdAes192Ecb, NistObjectIdentifiers.IdAes192Gcm, NistObjectIdentifiers.IdAes192Ofb, - NistObjectIdentifiers.IdAes192Wrap); + NistObjectIdentifiers.IdAes192Wrap, + NistObjectIdentifiers.IdAes192WrapPad); AddAlgorithm("AES256", SecurityUtilities.WrongAes256, NistObjectIdentifiers.IdAes256Cbc, @@ -54,7 +56,8 @@ namespace Org.BouncyCastle.Security NistObjectIdentifiers.IdAes256Ecb, NistObjectIdentifiers.IdAes256Gcm, NistObjectIdentifiers.IdAes256Ofb, - NistObjectIdentifiers.IdAes256Wrap); + NistObjectIdentifiers.IdAes256Wrap, + NistObjectIdentifiers.IdAes256WrapPad); AddAlgorithm("ARIA"); AddAlgorithm("ARIA128", NsriObjectIdentifiers.id_aria128_cbc, @@ -63,6 +66,8 @@ namespace Org.BouncyCastle.Security NsriObjectIdentifiers.id_aria128_ctr, NsriObjectIdentifiers.id_aria128_ecb, NsriObjectIdentifiers.id_aria128_gcm, + NsriObjectIdentifiers.id_aria128_kw, + NsriObjectIdentifiers.id_aria128_kwp, NsriObjectIdentifiers.id_aria128_ocb2, NsriObjectIdentifiers.id_aria128_ofb); AddAlgorithm("ARIA192", @@ -72,6 +77,8 @@ namespace Org.BouncyCastle.Security NsriObjectIdentifiers.id_aria192_ctr, NsriObjectIdentifiers.id_aria192_ecb, NsriObjectIdentifiers.id_aria192_gcm, + NsriObjectIdentifiers.id_aria192_kw, + NsriObjectIdentifiers.id_aria192_kwp, NsriObjectIdentifiers.id_aria192_ocb2, NsriObjectIdentifiers.id_aria192_ofb); AddAlgorithm("ARIA256", @@ -81,6 +88,8 @@ namespace Org.BouncyCastle.Security NsriObjectIdentifiers.id_aria256_ctr, NsriObjectIdentifiers.id_aria256_ecb, NsriObjectIdentifiers.id_aria256_gcm, + NsriObjectIdentifiers.id_aria256_kw, + NsriObjectIdentifiers.id_aria256_kwp, NsriObjectIdentifiers.id_aria256_ocb2, NsriObjectIdentifiers.id_aria256_ofb); AddAlgorithm("BLOWFISH", diff --git a/crypto/src/security/WrapperUtilities.cs b/crypto/src/security/WrapperUtilities.cs index e7383a054..782259d9c 100644 --- a/crypto/src/security/WrapperUtilities.cs +++ b/crypto/src/security/WrapperUtilities.cs @@ -23,8 +23,10 @@ namespace Org.BouncyCastle.Security { AESRFC3211WRAP, AESWRAP, + AESWRAPPAD, ARIARFC3211WRAP, ARIAWRAP, + ARIAWRAPPAD, CAMELLIARFC3211WRAP, CAMELLIAWRAP, DESRFC3211WRAP, @@ -47,11 +49,22 @@ namespace Org.BouncyCastle.Security Algorithms[NistObjectIdentifiers.IdAes192Wrap.Id] = "AESWRAP"; Algorithms[NistObjectIdentifiers.IdAes256Wrap.Id] = "AESWRAP"; + Algorithms["AESKWP"] = "AESWRAPPAD"; + Algorithms[NistObjectIdentifiers.IdAes128WrapPad.Id] = "AESWRAPPAD"; + Algorithms[NistObjectIdentifiers.IdAes192WrapPad.Id] = "AESWRAPPAD"; + Algorithms[NistObjectIdentifiers.IdAes256WrapPad.Id] = "AESWRAPPAD"; + Algorithms["AESRFC5649WRAP"] = "AESWRAPPAD"; + Algorithms["ARIAKW"] = "ARIAWRAP"; Algorithms[NsriObjectIdentifiers.id_aria128_kw.Id] = "ARIAWRAP"; Algorithms[NsriObjectIdentifiers.id_aria192_kw.Id] = "ARIAWRAP"; Algorithms[NsriObjectIdentifiers.id_aria256_kw.Id] = "ARIAWRAP"; + Algorithms["ARIAKWP"] = "ARIAWRAPPAD"; + Algorithms[NsriObjectIdentifiers.id_aria128_kwp.Id] = "ARIAWRAPPAD"; + Algorithms[NsriObjectIdentifiers.id_aria192_kwp.Id] = "ARIAWRAPPAD"; + Algorithms[NsriObjectIdentifiers.id_aria256_kwp.Id] = "ARIAWRAPPAD"; + Algorithms[NttObjectIdentifiers.IdCamellia128Wrap.Id] = "CAMELLIAWRAP"; Algorithms[NttObjectIdentifiers.IdCamellia192Wrap.Id] = "CAMELLIAWRAP"; Algorithms[NttObjectIdentifiers.IdCamellia256Wrap.Id] = "CAMELLIAWRAP"; @@ -85,10 +98,14 @@ namespace Org.BouncyCastle.Security return new Rfc3211WrapEngine(AesUtilities.CreateEngine()); case WrapAlgorithm.AESWRAP: return new AesWrapEngine(); + case WrapAlgorithm.AESWRAPPAD: + return new AesWrapPadEngine(); case WrapAlgorithm.ARIARFC3211WRAP: return new Rfc3211WrapEngine(new AriaEngine()); case WrapAlgorithm.ARIAWRAP: return new AriaWrapEngine(); + case WrapAlgorithm.ARIAWRAPPAD: + return new AriaWrapPadEngine(); case WrapAlgorithm.CAMELLIARFC3211WRAP: return new Rfc3211WrapEngine(new CamelliaEngine()); case WrapAlgorithm.CAMELLIAWRAP: |