コード例 #1
0
        private byte[] UnwrapInternal(byte[] wrapped, IKeyWrapTransform decryptor)
        {
            byte[] a = decryptor.A();
            int    halfBlockLength  = decryptor.BlockLength / 2;
            int    wrappedKeyLength = wrapped.Length - a.Length;

            wrapped = (byte[])wrapped.Clone();

            byte[] block = new byte[decryptor.BlockLength];

            // wrapped[0..7] contains the A (IV) of the Key Wrap algorithm,
            // the rest is 'Wrapped Key Data', R[1], ..., R[n]. We do the transform in-place.
            for (long j = _keyWrapIterations - 1; j >= 0; --j)
            {
                for (int i = wrappedKeyLength / halfBlockLength; i >= 1; --i)
                {
                    long t = ((wrappedKeyLength / halfBlockLength) * j) + i;
                    // MSB(B) = A XOR t
                    Array.Copy(wrapped, 0, block, 0, halfBlockLength);
                    switch (_mode)
                    {
                    case KeyWrapMode.Specification:
                        block.Xor(0, t.GetBigEndianBytes(), 0, halfBlockLength);
                        break;

                    case KeyWrapMode.AxCrypt:
                        block.Xor(0, t.GetLittleEndianBytes(), 0, halfBlockLength);
                        break;
                    }
                    // LSB(B) = R[i]
                    Array.Copy(wrapped, i * halfBlockLength, block, halfBlockLength, halfBlockLength);
                    // B = AESD(K, X xor t | R[i]) where t = (n * j) + i
                    byte[] b = decryptor.TransformBlock(block);
                    // A = MSB(B)
                    Array.Copy(b, 0, wrapped, 0, halfBlockLength);
                    // R[i] = LSB(B)
                    Array.Copy(b, halfBlockLength, wrapped, i * halfBlockLength, halfBlockLength);
                }
            }

            if (!wrapped.IsEquivalentTo(0, a, 0, a.Length))
            {
                return(new byte[0]);
            }

            byte[] unwrapped = new byte[wrapped.Length - a.Length];
            Array.Copy(wrapped, a.Length, unwrapped, 0, wrapped.Length - a.Length);
            return(unwrapped);
        }
コード例 #2
0
        private byte[] WrapInternal(byte[] keyMaterial, IKeyWrapTransform encryptor)
        {
            byte[] a = encryptor.A();

            byte[] wrapped = new byte[keyMaterial.Length + a.Length];
            a.CopyTo(wrapped, 0);

            Array.Copy(keyMaterial, 0, wrapped, a.Length, keyMaterial.Length);

            byte[] block           = new byte[encryptor.BlockLength];
            int    halfBlockLength = encryptor.BlockLength / 2;

            // wrapped[0..halfBlockLength-1] contains the A (IV) of the Key Wrap algorithm,
            // the rest is 'Key Data'. We do the transform in-place.
            for (int j = 0; j < _keyWrapIterations; j++)
            {
                for (int i = 1; i <= keyMaterial.Length / halfBlockLength; i++)
                {
                    // B = AESE(K, A | R[i])
                    Array.Copy(wrapped, 0, block, 0, halfBlockLength);
                    Array.Copy(wrapped, i * halfBlockLength, block, halfBlockLength, halfBlockLength);
                    byte[] b = encryptor.TransformBlock(block);
                    // A = MSB64(B) XOR t where t = (n * j) + i
                    long t = ((keyMaterial.Length / halfBlockLength) * j) + i;
                    switch (_mode)
                    {
                    case KeyWrapMode.Specification:
                        b.Xor(0, t.GetBigEndianBytes(), 0, halfBlockLength);
                        break;

                    case KeyWrapMode.AxCrypt:
                        b.Xor(0, t.GetLittleEndianBytes(), 0, halfBlockLength);
                        break;
                    }
                    Array.Copy(b, 0, wrapped, 0, halfBlockLength);
                    // R[i] = LSB64(B)
                    Array.Copy(b, halfBlockLength, wrapped, i * halfBlockLength, halfBlockLength);
                }
            }
            return(wrapped);
        }