示例#1
0
        internal void init(Mode aes_mode, KeySize aes_key_size, byte[] key)
        {
            _mode = aes_mode;
            switch (aes_key_size)
            {
            case KeySize.Aes128:
                _key_size = 16;
                break;

            case KeySize.Aes192:
                _key_size = 24;
                break;

            case KeySize.Aes256:
                _key_size = 32;
                break;

            default:
                _key_size = 0;
                break;
            }
            _counter.Zeroize();
            _counter_out.Zeroize();
            _keystream_pointer = 0xFFFF;
            // initialize WinCrypt AES-128 key.
            ms_aes_key key_blob = new ms_aes_key();

            key_blob.header.bType    = BlobType.PlainText;
            key_blob.header.bVersion = CurrentBlobVersion;
            key_blob.header.reserved = 0;
            key_blob.header.aiKeyAlg = (uint)aes_key_size;
            key_blob.size            = _key_size;
            Buffer.BlockCopy(key, 0, key_blob.key, 0, (int)key_blob.size);
            int    nativeKeySize;
            IntPtr nativeKey = key_blob.Serialize(out nativeKeySize);

            try {
                bool result = Crypt32.CryptImportKey(_provider.Handle, nativeKey,
                                                     nativeKeySize, IntPtr.Zero, 0, out _key);
            }
            finally { Marshal.FreeCoTaskMem(nativeKey); }
            _mode = aes_mode;
            // WinCrypt cannot do CTR mode, we have to do it manually.
            IntPtr buffer = Marshal.AllocCoTaskMem(sizeof(int));

            try {
                int mode = (int)((aes_mode == Mode.Ctr) ? Mode.Ecb : aes_mode);
                Marshal.WriteInt32(buffer, mode);
                bool result = Crypt32.CryptSetKeyParam(_key, 4 /* KP_MODE*/, buffer, 0);
            }
            finally { Marshal.FreeCoTaskMem(buffer); }
        }