Write a kext that enables SCSI command passing to a USB device - macos

I have a USB device (actually, a digital camera) that talks the MSC protocol, i.e. it appears as a disk device and can be talked to with SCSI commands. When it's connected to a Mac, the IOBlockStorageDriver takes over and mounts the volume.
Now, my goal is to prevent this from happening, in hopes that I can then talk to the device thru the SCSI interface functions for SCSITaskDeviceInterface, provided in <IOKit/scsi/SCSITaskLib.h>.
Is that possible? The SCSI Architecture Model Device Interface Guide states that the SCSITaskDeviceInterface is only available for types other than $00, $05, $07 and $0E (the MSC device is type 00), but I wonder if that's only because these types are taken over by the Mass Storage driver and therefore are not available. But if I prevent the Mass Storage driver to take over, will these types, such as 00, become available via SCSITaskDeviceInterface?
If that's possible, what must the kext code do to achieve this? E.g, which class should it subclass and which functions must it implement so that it prevents the mass storage driver from taking over while keeping the device visibile as a SCSI device in the io registry?
If that's not possible, could I then instead use the kext to provide a way to offer SCSI-cmd passthrough somehow? I would like to be able to send custom CDBs to this kext from userland, and it should then route them through the SCSI layer to the USB device. Is that possible? Assuming the kext has received a CDB string, how would it locate the SCSI functions for passing the data onward to the USB layer?
I've so far based my unsuccessful tests on Apple's VendorSpecificType00 sample project, which shows how to inject a kext that adds handling custom properties for a SCSI device.
For now, let's ignore upcoming kext deprecations by recent macOS versions (I want to get this working on High Sierra first).

Related

Linux USB Gadget custom configuration

I am using a i.Mx6 Sabre Lite board running Linux Kernel 3.14.18 and board is supposed to act as a USB Device (USB Gadget). One Vendor specific interface need to be added into CDC/NCM Configuration. CDC/NCM Configuration by default has two standard interfaces - Communication & Data. I have added third interface (Vendor specific) to CDC/NCM Configuration. This interface has two Bulk (IN & OUT) Endpoints. I can verify this newly added interface once board is connected to PC using "lsusb".
Problem:
I cannot see the newly added interface getting exposed to user-space on i.Mx Board or PC, like standard NCM interfaces can be seen as usb0 (Ethernet device) on i.Mx Board as well as on PC and I can PING to/from board using usb0.
If I have to hookup this newly added interface with some g_"driver" (just like standard NCM interfaces are hooked to g_ether); then what is the best choice for BULK I/O?
How to make this newly added vendor specific interface available to i.MX6 user space so as to do read/write on it from Linux Application? I came to know about GadgetFS; but any example would be
Hope someone must have tried similar thing in Linux-USB and can guide.
A vendor-specific interface does not use a standard protocol, so it is not possible to use one of the standard drivers. (And bulk is not a protocol, it is a mechanism to implement your own protocol.)
To access such an interface, you have to use the low-level functions from something like libusb.

Do Access points use softMAC or hardMAC?

I am trying to understand the working of wireless in linux. I started with wpa_supplicant, hostapd applications with the help of their documentation and source code.Understood the flow and basic functionalities of :
wpa_supplicant,nl80211(driver interface)
libnl library(socket communication between user space and kernel using netlink protocol)
cfg80211(kernel interface used for communicating with the driver from userspace with the help of nl80211 implementation in user space),mac80211(software media access control layer)
driver(loadable driver ex:ath6kl - atheros driver).
I understood the above software flow and in my exploration I came to know that for providing freedom for developers MAC layer is implemented in software(popular implementation mac80211).
Is this true in all the cases ? If so what are pros and cons of softMAC and hardMAC ? Do cfg80211 interface in kernel directly communicates with the driver ? who and how communication with mac80211 happens ?
Thanks in advance.
The term 'SoftMAC' refers to a wireless network interface device (WNIC) which does not implement the MAC layer in hardware, rather it expects the drivers to implement the MAC layer.
'HardMAC' (also called 'FullMAC') describes a WNIC which implements the MAC layer in hardware.
The advantages of SoftMAC are:
Potentially lower hardware costs
Possibility to upgrade to newer standards by updating the driver only
Possibility to correct faults in the MAC implementation by updating the driver only
An additional advantage (in the Linux kernel at least) is that many different drivers for different types of WNIC can all share the same MAC implementation, provided by the kernel itself.
Despite the advantages, not all WNICs use SoftMAC. The main advantages of HardMAC is that since the MAC functions are implemented in hardware, they contribute less CPU load.
mac80211 is the framework within the Linux kernel for implementing SoftMAC drivers. It implements the cfg80211 callbacks which would otherwise have to be implemented by the driver itself, and also implements the MAC layer functions. As such it goes between cfg80211 and the SoftMAC drivers.
HardMAC drivers have to implement the cfg80211 interfaces fully themselves.
Also to add :-
Hardmac drivers helps in better as compared to SoftMAC, power save and quick connection/disconnection recovery due to MLME implemented in HW. Better power save is because HW/FW need not to wake up host on disconnection and still can connect and recover .

How Application is interacting with hardware in linux?

I am new in Linux and i want to know the internals of drivers and how it is interacting with hardware, so my question is that How the application is interacting with hardware means when the core part will come in picture and what it will do?
When the controller of that driver will come and how it will handle the request generated by the application.
And what is Firmware and when it comes into picture in Linux?
For eg: if i am using usb device like
$ cat /dev/usb0.1
then which is the core of usb(usb_storage.c) and
which is the controller(usb_hub.c)
and how they are related to each other.
Thanks in advance..
Basically linux kernel driver provide interface such as device file node then application can use standard read()/write()/ioctl() to pass parameter to operate hardware. Provide interface in /proc or /sys can be facilities to do that too. Detail implementation how to handle request depends on respective hardware spec.

NFCEE Execution environment : hardware or library module?

I wanted to know what NFC Execution environment means actually. In forum documents it is described as "An environment, either built into the NFCC or connected to the NFCC, where NFC applications are executed. The NFCEE may be included in entities with various form factors, some of which can be removable or replaceable.". But the Device Host(an application microprocessor like OMAP or Snapdragon) is the one which interacts with NFCC, as per my understanding in the mobile environment. Can anyone give me a example of what NFCEE can be - I mean is it another hardware module(if yes, which) or an android library to execute apps? What does "form factor" refer to?
The Execution Environment is in most cases a hardware module.
Newer SIM cards have a pin to connect the SIM to the NFC chip. Inside the SIM an application (payment for example) can run in a secure environment and talk to the NFC chip. Payment goes from a sales terminal through the NFC chip directly into the SIM without ever passing data through the application processor. So there is no easy way for malware to monitor or modify the payment process. That's a simplified view of the secure aspect.
Other execution environments are:
Embedded Secure Elements. These are in a nutshell SIM cards that are in the same package as the NFC controller chip. Your Android Phone most likely has one of these, called the SmartMX chip.
SWP (Single Wire Protocol) enabled SD-Cards. Same thing as a SIM, but in the form factor of an SD card.
The concept doesn't end here. There are for example experiments to move the execution environment to the application processor. For ARM CPUs there is the TrustZone extension which allows to execute code on the main CPU while still beeing secure.
In the Android API Execution Environments do two things:
they allow you to enable or disable the secure element by setting a route. The route configures when the secure element is active (e.g. has access to the NFC chip) and when disabled. Currently there are two routes in use: Route off (turns off the entire EE) and Route_OnWhenScreenOn (EE active when screen is on and unlocked).
For secure elements that are connected exclusively to the NFC chip (embedded secure elements) the Execution Environment also offers a secure way to exchange data from the application processor to the embedded secure element. This is used to install applications within the embedded secure element (among other things).
That's it in a nutshell.

Still some questions about USB

few days ago I asked here about implementing USB. Now, If I may, would like to ask few more questions, about thing I dind´t quite understood.
So, first, If I am right, Windows has device driver for USB interface, for the physical device that sends and receives communication. But what this driver offers to system (user)? I mean, USB protocol is made so its devices are adressed. So you first adress device than send message to it.
But how sophisticted is the device controller (HW) and its driver? Is it so sophisticated that it is a chip you just send device adress and data, and it writes the outcomming data out and incomming data to some internal register to be read, or thru DMA directly to memory?
Or, how its drivers (SW) really work? Does its driver has some advanced functions like send _data to _device? Becouse I somewhat internally hope there is a way to directly send some data thru USB, maybe by calling USB drivers itself? Is there any good article, tutorial you know about to really explain how all this logic works? Thanks.
The USB protocol stack has several layers and is quite complex. You really need to read a good book on USB (e.g. USB Complete) to get an understanding of how it all fits together. The bottom line though is that you want to go as high up the protocol stack as you can, ideally using a system level API (e.g. if it's a USB HID device then just treat it like any other HID device, rather than thinking if it as a USB device - ditto for mass storage devices, etc).

Resources