How to use Bulk transfer in USB communication C# - c#

I have little bit problem with USB communication. I can connect to USB device but I cannot write any data to USB device.
This is my code to write data to USB device:
public byte[] GetUID = { 0xFF, 0xCA, 0x00, 0x00, 0x00 };
public byte[] SCardConnect = { 0x68, 0x92, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00 };
public bool WriteBulk(byte[] str)
{
//ErrorCode ec = ErrorCode.None;
if (IsConnected == false)
return false;
else Console.WriteLine("connected");
/*endpointWriter = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep02, EndpointType.Bulk);
int bytesWritten = length;
ec = endpointWriter.Write(protocol, 5000, out bytesWritten);
if (ec != ErrorCode.None) return false;
else return true;*/
UsbSetupPacket packet = new UsbSetupPacket((byte)UsbRequestType.TypeVendor, 0x04, 0, 0, (short)str.Length);
int lengthTransfered;
return MyUsbDevice.ControlTransfer(ref packet, str, str.Length, out lengthTransfered);
}
public bool checkUID()
{
return WriteBulk(GetUID);
}
public bool checkSCardConnect()
{
return WriteBulk(SCardConnect);
}
When I use checkUID() or checkSCardConnect(), it always returns false. Is there any other procedure to write using USB Communication?

Related

Store a known AES key with CngKey by name for later use

I want to store a known AES key (retrieved offline) by entering it into the application once, saving it to Cng for storage, then reference it only by name on subsequent use.
I want to save the key in the Key Storage Provider so my application won't load it into memory.
I can create (generate) a AES key (that I can retreive and create an instance of AesCng with) like this:
CngProvider keyStorageProvider = CngProvider.MicrosoftSoftwareKeyStorageProvider;
CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters()
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey
};
var name = "mykey";
var algo = new CngAlgorithm("AES");
var created = CngKey.Create(algo, name, keyCreationParameters);
But how can I add my already known AES symmetric key and just reference it by name the next time I run my application to run encryption/decryption using Cng?
Using CngKey.Import won't let me specify a name and I think I've tried all overloads but all yield some kind of error.
UPDATE:
This is a complete working example when creating a key.
// Calling code
byte[] key = //<from external input>;
byte[] data = new byte[] { 0xA, 0xB, 0xC, 0xD };
crypto.StoreKey("appkey", key);
var encryptedData = crypto.EncryptWithStoredKey("appkey", data);
// Implementation
public void StoreKey(string name, byte[] key)
{
CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters()
{
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey
};
var algo = new CngAlgorithm("AES");
// Question: How can I import the byte[] key with name "appkey" instead of generating a new key here?
CngKey.Create(algo, name, keyCreationParameters);
}
public byte[] EncryptWithStoredKey(string name, byte[] data)
{
using (var cng = new AesCng(name))
using (var encryptor = cng.CreateEncryptor())
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
}
}
It's... not nice. But it's technically doable. Reusing some of the import definitions from X509Certificate2.Import with NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG:
private static unsafe CngKey ImportPersistedAesKey(string keyName, byte[] key)
{
switch (key.Length * 8)
{
case 128:
case 192:
case 256:
break;
default:
throw new ArgumentOutOfRangeException(nameof(key));
}
byte[] blob = new byte[s_cipherKeyBlobPrefix.Length + key.Length];
Buffer.BlockCopy(s_cipherKeyBlobPrefix, 0, blob, 0, s_cipherKeyBlobPrefix.Length);
blob[12] = (byte)(12 /* sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) */ + key.Length);
blob[32] = (byte)key.Length;
Buffer.BlockCopy(key, 0, blob, s_cipherKeyBlobPrefix.Length, key.Length);
fixed (char* keyNamePtr = keyName)
fixed (byte* blobPtr = blob)
{
NativeMethods.NCrypt.NCryptBuffer nameBuf;
nameBuf.BufferType = NativeMethods.NCrypt.BufferType.PkcsName;
nameBuf.cbBuffer = (keyName.Length + 1) * 2;
nameBuf.pvBuffer = (IntPtr)keyNamePtr;
NativeMethods.NCrypt.NCryptBufferDesc bufferDesc;
bufferDesc.ulVersion = 0;
bufferDesc.cBuffers = 1;
bufferDesc.pBuffers = (IntPtr)(&nameBuf);
int ret = NativeMethods.NCrypt.NCryptOpenStorageProvider(
out SafeNCryptProviderHandle hProv,
CngProvider.MicrosoftSoftwareKeyStorageProvider.Provider,
0);
using (hProv)
{
if (ret != 0)
{
throw new Win32Exception(ret);
}
ret = NativeMethods.NCrypt.NCryptImportKey(
hProv,
IntPtr.Zero,
"CipherKeyBlob",
ref bufferDesc,
out SafeNCryptKeyHandle hKey,
(IntPtr)blobPtr,
blob.Length,
NativeMethods.NCrypt.NCryptImportFlags.NCRYPT_OVERWRITE_KEY_FLAG);
using (hKey)
{
if (ret != 0)
{
throw new Win32Exception(ret);
}
return CngKey.Open(hKey, CngKeyHandleOpenOptions.None);
}
}
}
}
private static byte[] s_cipherKeyBlobPrefix = {
// NCRYPT_KEY_BLOB_HEADER.cbSize (16)
0x10, 0x00, 0x00, 0x00,
// NCRYPT_KEY_BLOB_HEADER.dwMagic (NCRYPT_CIPHER_KEY_BLOB_MAGIC (0x52485043))
0x43, 0x50, 0x48, 0x52,
// NCRYPT_KEY_BLOB_HEADER.cbAlgName (8)
0x08, 0x00, 0x00, 0x00,
// NCRYPT_KEY_BLOB_HEADER.cbKeyData (to be determined)
0x00, 0x00, 0x00, 0x00,
// UTF16-LE "AES\0"
0x41, 0x00, 0x45, 0x00, 0x53, 0x00, 0x00, 0x00,
// BCRYPT_KEY_DATA_BLOB_HEADER.dwMagic (BCRYPT_KEY_DATA_BLOB_MAGIC (0x4D42444B))
0x4B, 0x44, 0x42, 0x4D,
// BCRYPT_KEY_DATA_BLOB_HEADER.dwVersion (1)
0x01, 0x00, 0x00, 0x00,
// BCRYPT_KEY_DATA_BLOB_HEADER.cbKeyData (to be determined)
0x00, 0x00, 0x00, 0x00
};
internal static class NativeMethods
{
internal static class NCrypt
{
[StructLayout(LayoutKind.Sequential)]
internal struct NCryptBufferDesc
{
public int ulVersion;
public int cBuffers;
public IntPtr pBuffers;
}
[StructLayout(LayoutKind.Sequential)]
internal struct NCryptBuffer
{
public int cbBuffer;
public BufferType BufferType;
public IntPtr pvBuffer;
}
internal enum BufferType
{
PkcsName = 45,
}
[DllImport("ncrypt.dll", CharSet = CharSet.Unicode)]
internal static extern int NCryptOpenStorageProvider(
out SafeNCryptProviderHandle phProvider,
string pszProviderName,
int dwFlags);
internal enum NCryptImportFlags
{
None = 0,
NCRYPT_MACHINE_KEY_FLAG = 0x00000020,
NCRYPT_OVERWRITE_KEY_FLAG = 0x00000080,
NCRYPT_DO_NOT_FINALIZE_FLAG = 0x00000400,
}
[DllImport("ncrypt.dll", CharSet = CharSet.Unicode)]
internal static extern int NCryptImportKey(
SafeNCryptProviderHandle hProvider,
IntPtr hImportKey,
string pszBlobType,
ref NCryptBufferDesc pParameterList,
out SafeNCryptKeyHandle phKey,
IntPtr pbData,
int cbData,
NCryptImportFlags dwFlags);
[DllImport("ncrypt.dll", CharSet = CharSet.Unicode)]
internal static extern int NCryptFinalizeKey(SafeNCryptKeyHandle hKey, int dwFlags);
}
}
The expected flow is that you should be able to create a key and then use NCryptSetKeyProperty to set the NCRYPT_CIPHER_KEY_BLOB property for the NCRYPT_CIPHER_KEY_BLOB payload (from the .NET perspective that'd be you call CngKey.Create with creation parameters and specify it as a creation property). But it looks like CNG didn't wire that up for persisted symmetric keys, so you have to use the complicated form of NCryptImportKey directly.

C# Modbus frame splitting and storing procedures

The Premise
I am continually polling custom modbus frames from an embedded device with my c# wpf application at a low interval. At the moment the bytes in the frame i receive are located at the same position every time(e.g. frame[15]+frame[16] = 0x0532 = errorcode2).
The Questions
Are there smart procedures (other than simply hardcoding the bytestorage) I could use to go from frame receiving to splitting/parsing?
What data structures would be preferrable to enable frames to be processed dynamically further down the line?
Method 1:
You can define an explicitly laid out struct in C# and marshal the data to it like is done in the code below. However, you will have problems with the data due to endian ordering if you are not running on big endian hardware (Modbus data is sent in big endian). This also won't handle variable length Modbus packets (i.e. Read Input Registers). NOTE: It is assumed that the frame has already been CRC checked so there is no need to declare and read it.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MyPacket
{
public Byte Address; // Byte 0
public Byte FunctionCode; // Byte 1
public Byte ByteField; // Byte 2
public UInt32 UInt32Field; // Bytes 3-6
public UInt64 UInt64Field; // Byte 7-14
public UInt16 ErrorCode; // Bytes 15-16
}
public static bool TryParse<T>(byte[] array, out T packet) where T : struct
{
try
{
var size = Marshal.SizeOf(typeof(T));
var p = Marshal.AllocHGlobal(size);
Marshal.Copy(array, 0, p, size);
packet = (T)Marshal.PtrToStructure(p, typeof(T));
Marshal.FreeHGlobal(p);
return true;
}
catch
{
packet = default(T);
return false;
}
}
static int Main(string[] args)
{
// Create a sample frame
byte[] bytes = new byte[] { 0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
MyPacket packet;
if (TryParse<MyPacket>(bytes, out packet))
{
// Process packet here...
}
return 0;
}
Method 2:
What I think is a better solution is to define a class for each function type that you use and read each field individually as shown in the code below. NOTE: It is assumed that the frame has already been CRC checked so there is no need to declare and read it.
// VERY SIMPLE BigEndianReader class
public class BigEndianReader
{
private Stream _stream;
public BigEndianReader(Stream stream)
{
if (stream == null) throw new ArgumentNullException(nameof(stream));
if (!stream.CanRead) throw new ArgumentException(nameof(stream));
_stream = stream;
}
public byte ReadByte()
{
int b = _stream.ReadByte();
if (b < 0) throw new EndOfStreamException();
return (byte)b;
}
public UInt16 ReadUInt16()
{
UInt16 v = 0;
for (int i = 0; i < sizeof(UInt16); i++){v <<= 8;v |= ReadByte();}
return v;
}
public UInt32 ReadUInt32()
{
UInt32 v = 0;
for (int i = 0; i < sizeof(UInt32); i++){v <<= 8;v |= ReadByte();}
return v;
}
public UInt64 ReadUInt64()
{
UInt64 v = 0;
for (int i = 0; i < sizeof(UInt64); i++) { v <<= 8; v |= ReadByte(); }
return v;
}
}
class MyPacket
{
public Byte Address { get; private set; }
public Byte FunctionCode { get; private set; }
public Byte ByteField { get; private set; }
public UInt32 UInt32Field { get; private set; }
public UInt64 UInt64Field { get; private set; }
public UInt16 ErrorCode { get; private set; }
public static bool TryParse(byte[] bytes, out MyPacket result)
{
result = null;
try
{
BigEndianReader r = new BigEndianReader(new MemoryStream(bytes));
MyPacket p = new MyPacket();
p.Address = r.ReadByte();
p.FunctionCode = r.ReadByte();
p.ByteField = r.ReadByte();
p.UInt32Field = r.ReadUInt32();
p.UInt64Field = r.ReadUInt64();
p.ErrorCode = r.ReadUInt16();
result = p;
return true;
}
catch
{
return false;
}
}
}
static int Main(string[] args)
{
// Create a sample frame
byte[] bytes = new byte[] { 0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 };
MyPacket packet;
if (MyPacket.TryParse(bytes, out packet))
{
// Process packet here...
}
//==================================================================
Console.Write("(press any key to exit)");
Console.ReadKey(true);
return 0;
}

Find a sequence of bytes and return the start position

I have a large file, I need to search in it for a sequence of 7 bytes and return the position of that sequence in that files. I can't post any code because so far I was not able to write any decent code. Can anyone please point me in the right direction? Maybe is there a function that I don't know the existence of?
Example
Given a file like that:
I want to find the position of F8 1E 13 B9 E4 28 88 which in this case is at 0x21
Here's a nice extension method to do it:
public static class ByteArrayExtensions
{
public static int IndexOf(this byte[] sequence, byte[] pattern)
{
var patternLength = pattern.Length;
var matchCount = 0;
for (var i = 0; i < sequence.Length; i++)
{
if (sequence[i] == pattern[matchCount])
{
matchCount++;
if (matchCount == patternLength)
{
return i - patternLength + 1;
}
}
else
{
matchCount = 0;
}
}
return -1;
}
}
Then you can find it as follows:
var bytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x010 };
var index = bytes.IndexOf(new byte[] { 0x03, 0x04, 0x05 });

C# parse bytes to struct sequential

I try parse a byte array to struct but it doesnt work with Sequential. The values are wrong in the Sequential struct but it work correct with Explicit struct? I need sequential the byte array have no fix length. The DwLength field is the size of Data field.
Values
MessageType 128 (Sequential 128)
DwLength 20 (Sequential 33554432)
Slot 0 (Sequential 0)
Seq 0 (Sequential 0)
Status 2 (Sequential 59)
Error 0 (Sequential 143)
ChainParameter 0 (Sequential 128)
Test Code
var bytes = new byte[] { 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x3B, 0x8F, 0x80, 0x01, 0x80, 0x4F, 0x0C, 0xA0, 0x00, 0x00, 0x03, 0x06, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x68 };
var result1 = GetStruct<RdrToPcDataBlock1>(bytes);
var result2 = GetStruct<RdrToPcDataBlock2>(bytes);
struct RdrToPcDataBlock Sequential
[StructLayout(LayoutKind.Sequential)]
public struct RdrToPcDataBlock1
{
public byte MessageType;
public int DwLength;
public byte Slot;
public byte Seq;
public byte Status;
public byte Error;
public byte ChainParameter;
[MarshalAs(UnmanagedType.ByValArray)]
public byte[] Data;
}
struct RdrToPcDataBlock Explicit
[StructLayout(LayoutKind.Explicit)]
public struct RdrToPcDataBlock2
{
[FieldOffset(0)]
public byte MessageType;
[FieldOffset(1)]
public int DwLength;
[FieldOffset(5)]
public byte Slot;
[FieldOffset(6)]
public byte Seq;
[FieldOffset(7)]
public byte Status;
[FieldOffset(8)]
public byte Error;
[FieldOffset(9)]
public byte ChainParameter;
[FieldOffset(10)]
public byte Data;
}
GetStruct
public T GetStruct<T>(byte[] bytes)
{
try
{
var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var item = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return item;
}
catch
{
return default(T);
}
}
When you do [StructLayout(LayoutKind.Sequential)] that is the same as doing [StructLayout(LayoutKind.Sequential, Pack=0)] which will use the default packing for the bitness of the process (4 for 32 bit and 8 for 64 bit). To get the behavior your want you need to explicitly say you don't want any padding by setting [StructLayout(LayoutKind.Sequential, Pack=1)]
UPDATE: You still are going to run in to problems with your variable length byte array. See the comment by Jean-Bernard Pellerin
You will have to use a custom marshaller. Otherwise you can't deal with variable length arrays. Here's an example: https://stackoverflow.com/a/38884095/103959

can I get ProcessBytes to return an exact amount?

am using BouncyCastel to make a CfbBlockCipher so here is the codes.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Common.Encryption
{
public class BlowfishCryptographer
{
private bool forEncryption;
private IBufferedCipher cipher;
public BlowfishCryptographer(bool forEncryption)
{
this.forEncryption = forEncryption;
cipher = new BufferedBlockCipher(new CfbBlockCipher(new BlowfishEngine(), 64));
cipher.Init(forEncryption, new ParametersWithIV(new KeyParameter(Encoding.ASCII.GetBytes("DR654dt34trg4UI6")), new byte[8]));
}
public void ReInit(byte[] IV,BigInteger pubkey)
{
cipher.Init(forEncryption, new ParametersWithIV(new KeyParameter(pubkey.ToByteArrayUnsigned()),IV));
}
public byte[] DoFinal()
{
return cipher.DoFinal();
}
public byte[] DoFinal(byte[] buffer)
{
return cipher.DoFinal(buffer);
}
public byte[] DoFinal(byte[] buffer, int startIndex, int len)
{
return cipher.DoFinal(buffer, startIndex, len);
}
public byte[] ProcessBytes(byte[] buffer)
{
return cipher.ProcessBytes(buffer);
}
public byte[] ProcessBytes(byte[] buffer, int startIndex, int len)
{
return cipher.ProcessBytes(buffer, startIndex, len);
}
public void Reset()
{
cipher.Reset();
}
}
}
so...
byte[] buf = new byte[] { 0x83, 0x00, 0xEE, 0x03, 0x26, 0x6D, 0x14, 0x00, 0xF1, 0x65, 0x27, 0x00, 0x19, 0x02, 0xD8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xD7, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
if i said ProcessBytes(buf, 0, 17) it will only return 16, i also tried DoFinal() but it's not doing it's job!!!
is that up to IBufferedCipher should i use IStreamCipher or something else to get the exact amount of what am dec/enc-ing? And i believe CfbBlockCipher is broken somehow or am doing something worng here.
I don't know what you consider not doing the job here. You need to call ProcessBytes multiple times and finish with DoFinal(). It's normal that ProcessBytes() only returns 16 bytes because that is x times the block size. The cipher does not know if you've finished feeding it bytes, so it cannot calculate another block until you call DoFinal(). Of course, you need to append the output of the ProcessBytes() and DoFinal() calls to get the end result...

Categories

Resources