Example #1
1
        public CryptoDevTransform(SymmetricAlgorithm algo, Cipher cipher, bool encryption, byte[] rgbKey, byte[] rgbIV, int bufferBlockSize)
            : base(algo, encryption, rgbKey, rgbIV)
        {
            if (!Helper.IsAvailable (cipher))
                throw new CryptographicException (String.Format ("{0} not available from /dev/crypto", algo));

            // linux does not requires cloning the file descriptor with CRIOGET
            Session sess = new Session ();
            sess.cipher = cipher;
            sess.keylen = (uint) rgbKey.Length;
            fixed (byte* k = &rgbKey [0]) {
                sess.key = (IntPtr) k;
                try {
                    if (Helper.SessionOp (ref sess) < 0)
                        throw new CryptographicException (Marshal.GetLastWin32Error ());
                }
                finally {
                    sess.key = IntPtr.Zero;
                }
            }

            context.ses = sess.ses;
            context.op = encryption ? CryptoOperation.Encrypt : CryptoOperation.Decrypt;
            // CryptoOperation constants differs in OCF (0 is None, ...)
            if (Helper.Mode == KernelMode.Ocf)
                context.op++;

            if (algo.Mode != CipherMode.ECB) {
                save_iv = new byte [BlockSizeByte];
            }

            // change this value if the driver (e.g. mv_cesa) has a limit that
            // it can process in a single shot (e.g. 1936 for AES)
            BufferBlockSize = bufferBlockSize;
        }
Example #2
0
        public HashHelper(Cipher algo)
        {
            if (!Helper.IsAvailable (algo))
                throw new CryptographicException (String.Format ("{0} not available from /dev/crypto", algo));

            // linux does not requires cloning the file descriptor with CRIOGET
            Session sess = new Session ();
            sess.mac = algo;

            if (Helper.SessionOp (ref sess) < 0)
                throw new CryptographicException (Marshal.GetLastWin32Error ());

            context.ses = sess.ses;
            context.op = CryptoOperation.Encrypt;
            // change this value if the driver (e.g. mv_cesa) has a limit that
            // it can process in a single shot (e.g. 1932 for SHA1)
            BufferBlockSize = Int32.MaxValue;
        }
Example #3
0
        public CryptoDevTransform(SymmetricAlgorithm algo, Cipher cipher, bool encryption, byte[] rgbKey, byte[] rgbIV, int bufferBlockSize)
        {
            if (!Helper.IsAvailable (cipher))
                throw new CryptographicException (String.Format ("{0} not available from /dev/crypto", algo));

            if (rgbKey == null)
                throw new CryptographicException ("Invalid (null) key");

            BlockSizeByte = (algo.BlockSize >> 3);

            if (rgbIV == null) {
                rgbIV = KeyBuilder.IV (BlockSizeByte);
            } else {
                // compare the IV length with the "currently selected" block size and *ignore* IV that are too big
                if (rgbIV.Length < BlockSizeByte) {
                    string msg = Locale.GetText ("IV is too small ({0} bytes), it should be {1} bytes long.",
                        rgbIV.Length, BlockSizeByte);
                    throw new CryptographicException (msg);
                }
                rgbIV = (byte[]) rgbIV.Clone ();
            }

            encrypt = encryption;
            padding = algo.Padding;

            // linux does not requires cloning the file descriptor with CRIOGET
            Session sess = new Session ();
            sess.cipher = cipher;
            sess.keylen = (uint) rgbKey.Length;
            fixed (byte* k = &rgbKey [0])
                sess.key = (IntPtr) k;

            if (Helper.SessionOp (ref sess) < 0)
                throw new CryptographicException (Marshal.GetLastWin32Error ());

            context.ses = sess.ses;
            context.op = encryption ? CryptoOperation.Encrypt : CryptoOperation.Decrypt;
            // CryptoOperation constants differs in OCF (0 is None, ...)
            if (Helper.Mode == KernelMode.Ocf)
                context.op++;

            if (algo.Mode != CipherMode.ECB) {
                iv = rgbIV;
                save_iv = new byte [BlockSizeByte];
                fixed (byte* i = &iv [0])
                    context.iv = (IntPtr) i;
            }

            // transform buffer
            workBuff = new byte [BlockSizeByte];
            // change this value if the driver (e.g. mv_cesa) has a limit that
            // it can process in a single shot (e.g. 1936 for AES)
            BufferBlockSize = bufferBlockSize;
        }
Example #4
0
        static bool IsNewCryptoDev()
        {
            bool result;

            // check if this is a new crypto dev module by testing for SHA2_224_HMAC.
            // see discussion here https://github.com/nmav/cryptodev-linux/commit/d87ab5584893d06a21fe7cbf6e052d6757f9aa91#diff-535166266eead3c57bed2059c5006818
            Session session = new Session ();
            session.mac = (Cipher)107; // CRYPTO_SHA2_224_HMAC
            if (IntPtr.Size == 4) {
                result = ioctl32 (fildes, (int)CD_CIOCGSESSION, ref session) == 0;
                ioctl32 (fildes, (int)CD_CIOCFSESSION, ref session);
            } else {
                result = ioctl64 (fildes, CD_CIOCGSESSION, ref session) == 0;
                ioctl64 (fildes, CD_CIOCFSESSION, ref session);
            }
            return result;
        }
Example #5
0
        static bool Is(Cipher algo, KernelMode mode)
        {
            // asking the kernel for availability turns out to be very costly
            long key = (((long) algo << 32) | (long) mode);
            if (availability.Contains (key))
                return true;

            bool result = false;
            Session session = new Session ();
            fixed (byte* k = &null_key [0]) {
                switch (algo) {
                case Cipher.AES_CBC:
                case Cipher.AES_ECB:
                    session.cipher = algo;
                    session.keylen = 32;
                    session.key = (IntPtr)k;
                    break;
                case Cipher.SHA1:
                    // OCF requires a single buffer that include room for the digest at the end. Its not
                    // compatible with how HashAlgorithm works.
                    if (mode == KernelMode.Ocf)
                        return false;

                    session.mac = algo;
                    break;
                // accept both SHA256 and SHA2_256 and use the correct one
                case Cipher.SHA256:
                case Cipher.SHA256_NEW:
                case Cipher.SHA2_256:
                    if (mode == KernelMode.Ocf)
                        return false;

                    if (sha256.HasValue) {
                        session.mac = sha256.Value;
                    } else {
                        if (mode == KernelMode.Ocf)
                            session.mac = Cipher.SHA2_256;
                        else
                            session.mac = IsNewCryptoDev() ? Cipher.SHA256_NEW : Cipher.SHA256;

                        sha256 = session.mac;
                    }
                    break;
                default:
                    return false;
                }

                ulong ciocgsession = mode == KernelMode.CryptoDev ? CD_CIOCGSESSION : OCF_CIOCGSESSION;
                if (IntPtr.Size == 4) {
                    result = ioctl32 (fildes, (int)ciocgsession, ref session) == 0;
                    ioctl32 (fildes, (int)CD_CIOCFSESSION, ref session);
                } else {
                    result = ioctl64 (fildes, ciocgsession, ref session) == 0;
                    ioctl64 (fildes, CD_CIOCFSESSION, ref session);
                }
            }
            if (result) {
                Mode = mode;
                availability.Add (key);
            }
            return result;
        }
Example #6
0
 static extern int ioctl64(int fdc, ulong request, ref Session session);
Example #7
0
 static extern int ioctl32(int fdc, int request, ref Session session);
Example #8
0
        internal static int SessionOp(ref Session session)
        {
            if (session.mac == Cipher.SHA256 || session.mac == Cipher.SHA2_256 || session.mac == Cipher.SHA256_NEW)
                session.mac = sha256.Value;

            if (IntPtr.Size == 4)
                return ioctl32 (fildes, (int) CIOCGSESSION, ref session);
            else
                return ioctl64 (fildes, CIOCGSESSION, ref session);
        }
Example #9
0
        static bool Is(Cipher algo, KernelMode mode)
        {
            // asking the kernel for availability turns out to be very costly
            long key = (((long) algo << 32) | (long) mode);
            if (availability.Contains (key))
                return true;

            bool result = false;
            fixed (byte* k = &null_key [0]) {
                Session session = new Session ();
                switch (algo) {
                case Cipher.AES_CBC:
                case Cipher.AES_ECB:
                    session.cipher = algo;
                    session.keylen = 32;
                    session.key = (IntPtr)k;
                    break;
                case Cipher.SHA1:
                    session.mac = algo;
                    break;
                // accept both SHA256 and SHA2_256 and use the correct one
                case Cipher.SHA256:
                case Cipher.SHA2_256:
                    if (mode == KernelMode.Ocf)
                        session.mac = Cipher.SHA2_256;
                    else
                        session.mac = Cipher.SHA256;
                    break;
                default:
                    return false;
                }

                ulong ciocgsession = mode == KernelMode.CryptoDev ? CD_CIOCGSESSION : OCF_CIOCGSESSION;
                if (IntPtr.Size == 4)
                    result = ioctl32 (fildes, (int) ciocgsession, ref session) == 0;
                else
                    result = ioctl64 (fildes, ciocgsession, ref session) == 0;
            }
            if (result) {
                Mode = mode;
                availability.Add (key);
            }
            return result;
        }
Example #10
0
 internal static int SessionOp(ref Session session)
 {
     if (IntPtr.Size == 4)
         return ioctl32 (fildes, (int) CIOCGSESSION, ref session);
     else
         return ioctl64 (fildes, CIOCGSESSION, ref session);
 }
Example #11
0
        static bool Is(Cipher algo, KernelMode mode)
        {
            Session session = new Session ();
            switch (algo) {
            case Cipher.AES_CBC:
            case Cipher.AES_ECB:
                session.cipher = algo;
                session.keylen = 32;
                fixed (byte* k = &null_key[0])
                    session.key = (IntPtr)k;
                break;
            case Cipher.SHA1:
                session.mac = algo;
                break;
            // accept both SHA256 and SHA2_256 and use the correct one
            case Cipher.SHA256:
            case Cipher.SHA2_256:
                if (mode == KernelMode.Ocf)
                    session.mac = Cipher.SHA2_256;
                else
                    session.mac = Cipher.SHA256;
                break;
            default:
                return false;
            }

            ulong ciocgsession = mode == KernelMode.CryptoDev ? CD_CIOCGSESSION : OCF_CIOCGSESSION;
            bool result;
            if (IntPtr.Size == 4)
                result = ioctl32 (fildes, (int) ciocgsession, ref session) == 0;
            else
                result = ioctl64 (fildes, ciocgsession, ref session) == 0;

            if (result)
                Mode = mode;
            return result;
        }