Παρασκευή 7 Αυγούστου 2015

U2F developing

Right now most of the USB problems have been dealt with and we have moved on to the implementation of the U2F functionality.

First of was the implementation of the generation of key handles. A key handle for U2F is a unique tag that the device assigns on a trusty party and it uses that one for subsequent authentication requests. In our approach we don't store the key handle, but we compute from the appID, which stays the same for every trusted party, and we wrap the private device key as a key handle.

A lot of these actions include the use of PolarSSL, which is a library for the ARM architecture which deals with common cryptographic and hashing algorithms. I don't a lot to tell yet about that, as I'm still learning about how to use it, but I'll keep you posted.

Παρασκευή 31 Ιουλίου 2015

USB debugging

Getting the new interface to work has been a difficult task in a sense. For sure it's not the kind of difficulty you 're dealing with with a software coding project, where you have a lot of resources and usually it's somewhere in the logic of the program that you have made a mistake, but you have to have a deep understanding of the low-level operations that are performed by the firmware.

Yet again, debugging is what you need. In my project and with the problems I'm dealing with right now, I needed a USB protocol analyzer. I'm working on Linux, so a lot of the tools that the USB organization is providing aren't any help for me, but I managed to find a program called Wireshark (https://www.wireshark.org/). Wireshark is a network protocol analyzer and can be used, between others, to monitor your USB activity. Take a look at the following screenshot.






I 've filtered out the packets regarding Nitrokey with the filter at the top. This is, of course, particular to your computer and the address that your device was given during enumeration. This screenshot actually lists a lot of the things I've been talking about in my previous posts. As you can see, the host first requests the device descriptor and the device responds to the GET DESCRIPTOR DEVICE request. Then it request the first bytes of the Configuration Descriptor, the device responds and now the host knows the total length of the Configuration Descriptor. So in a new request it asks for the whole Configuration Descriptor.

This is just an example of usb debugging, which unfortunately in my case took hours before I was able to solve it (mainly because I thought some parts of my code were the problem). You see what I did was that I forgot that the wDescriptorLength (you can see that in the highlighted section) is composed of two bytes, one for the high part and one for the low. I thought it was only one byte, so when the host retrieved the wDescriptorLength, it used the next byte (which was supposed to be the size of the Endpoint Descriptor) as the high part, thinking my descriptor length would be 0x0722 instead of 0x0022. But to be honest, even though these kinds of mistakes annoy you, it's a fun procedure to see the actual packets involved and analysing what mistakes have been made :)

Παρασκευή 24 Ιουλίου 2015

U2F HID interface

So coding goes well, we are at a point were we have some decisions to make with my mentor about the actual implementation and still there are some issues in the firmware that are hard to understand. In this post I decided to take some time and continue with the description of my project, and explaining the U2F interface is crucial around this.

As I've said, getting the Nitrokey to work with U2F means that we have to implement a new USB interface. This is an HID interface and is described in the FIDO specifications. In my experience though, if someone wants to understand the U2F HID specification, I would advice them to have a good understanding of basic USB requests and the HID specification.

At first comes the interface descriptor, which for the case of U2F the most significant parts are these

bNumEndpoints             2          One IN­ and one OUT endpoint
bInterfaceClass             0x03     HID
bInterfaceSubClass       0x00     No interface subclass
bInterfaceProtocol        0x00     No interface protocol

The interface has two endpoints, that means a buffer were data would be put to be processed in an OUT request, and a buffer where we will store our response. Each endpoint is 64-byte size, which is the largest size for a USB 2.0 device. Of course sometimes the data that we will receive or the ones that we are going to put will be larger than 64-bytes. To deal with this, there are two types of packages, initialization packages and continuation packages. If the whole messages is larger that 64-bytes, and that actually means (64-7) bytes of payload data, we have to split the response in one initialization package and more continuation packages. The init package holds the U2F command the byte-count, which are quite useful to us. When the whole message is received, then we can process the message and put our response in the IN endpoint.

The structure of these data is described in what is called a Report Descriptor. A report descriptor which bytes (or bits) form a logical entity and describe a particular value, and we assign maximum and minimum values for them. I don't want to get into details here since someone can find a lot of information about the report descriptors with a web search, but I want to state this: The report descriptor is actually a very important part in U2F. The device discovery is made through the FIDO usage page (which is actually 0xf1do in hex :)), which is contained in the report descriptor.

Around this time I'm trying to see how these requests are actually processed in the firmware. This involves a lot of overhead and it's a tough job, but it gets interesting as I move forward. See you around!

Παρασκευή 17 Ιουλίου 2015

Writing a new USB interface (cont)

So far I've told you about what a device descriptor is and more or less what an interface is. Let's examine another example (this I have made entirely out of my imagination, and I'm not really a gamer, so bare with me if you find it out-stretched :)). Suppose we a have a gamepad and a a racing wheel and we can connect these two devices with a common USB tranceiver. The gamepad is fine for most types of games, but for some racing games you would like the host communicating only with the wheel. So let's say there is a switch on the wheel, and when it's turned on the host will completely forget that there is a gamepad. How can we do that, i.e. how can we turn interfaces on and off? That's where a configuration descriptor comes in play.

Following the last post, we have plugged in a USB device to the host and the host has asked for the Device Descriptor through the Endpoint 0 (the control endpoint). We put on the Endpoint 0 a respond request for the device descriptor and we send the respective data. After that the host is asking as for a Configuration Descriptor with a GET CONFIGURATION DESCRIPTOR request. In this configuration descriptor we describe mostly things about our interfaces, how many are there, how many endpoints each interface has and stuff like that. The important thing here is that a device can switch between different configurations. Taking the gamepad example, when we turned on the switch, that could be a signal for the firmware that the user want to only use the wheel interface and forget about the gamepad. We could have written two configurations for the device, one which there is only the interface of the gamepad, and an alternate one where there is only the interface of the wheel. Again, this is only an example, I'm sure that someone could find a better implementation for this.

The host is requesting a configuration descriptor and some of you are thinking "since the host doesn't know yet the exact number of the interfaces (since they are not contained in the device descriptor but in the configuration descriptor which is just asking for), how can the host know how many bytes to expect?" And that's a pretty neat trick for the USB specification. In any GET request the host is putting on the control endpoint, besides others, how many bytes it's requesting. At first the host asks for only a limited amount of bytes from the configuration descriptor. One of them is the whole configuration descriptor size. So it gets a limited amount of bytes, gets informed about the whole size of the configuration descriptor, resets the device and when it's going to ask again for the configuration descriptor, this time it's going to get the whole one. Listed in there are all the interfaces that the device implements in *this* configuration. Nitrokey has already some of them implemented (like a keyboard HID interface and a CCID interface), and for our purposes we need a new HID interface for U2F.

HID actually stands for Human Interface Device. Of course an authentication token is only in some basic sense a human interface device, it only has a button on it which you have to press to authenticate. But the cool thing about the HID interface is that all major operating systems come with a driver pre-installed for HID, it's a simple interface, there is a lot of experience around these devices (think how many years we've been using keyboards and mices), and is communicating through interrupts, which guarantee correct timing and limited data usage. That's why I think FIDO decided to use the HID interface for implementing U2F, and personally I couldn't be more down with their decision.

I'd like to take some time and describe the U2F HID interface, but I guess that's a blog post of its own. Talk to you next week! :)

Παρασκευή 10 Ιουλίου 2015

Writing a new USB interface

As I've stated elsewhere, my GSoC project involves getting the Nitrokey, which is a USB device made for secure, cryptographic operations, to work with the U2F second-factor authentication protocol. The FIDO Alliance, which is the organization behind the U2F Standard, has published the specifications of how the host recognizes a U2F device and how these two communicate with each other. In this post I'm going to explain some basic things I learned about the USB implementation, just enough to be able to follow what changes I have made to the device to be able to work with U2F.

Each USB device has some basic structures, called descriptors, which identify the device at the host during device discovery. At the most basic level, there is the Device Descriptor, which holds some basic information about the device itself. It starts with a byte indicating the length of the descriptor - for the device descriptor it's a a fixed number, but it will come to play for other types of descriptors - and some of the most useful information in the device descriptor would be the Vendor ID and Product ID. Given these two, the host can apply device-specific rules, for example custom rules in /etc/udev/rules.d/ on a Linux machine. Some other information would be the location of some strings indicating the name of the device or the manufacturer. All this talking between the host and the device is made using the Control Endpoint 0. An endpoint is more or less like an assigned buffered by which either the host puts data to transmit (OUT request), or the device sends data to the host (IN request). When it comes to control purposes (and getting the descriptors are in this category), all transactions are made through the Endpoint 0 and have a standard format and vocabulary which is detailed in the USB specification documents.

When the host has sent a GET DEVICE DESCRIPTOR request and has successfully got a GET DEVICE DESCRIPTOR response, then it has to learn about the configuration of the device. To be able to explain what a configuration is, I think I have to talk about interfaces first. A USB interface is a set of device characteristics that constitute a functionality by itself. For example, let's suppose we have a USB wireless desktop on our computer, that includes a mouse and a keyboard. The use of the keyboard is completely separated by the use of the mouse, in fact we can move the pointer as we type with no problem. But the keyboard and mouse are communicating with the host using one USB port, so how can the host tell that some things are keyboard data and others mouse data? That's where the interfaces come to play. We have two different interfaces in this example, one a keyboard interface and one as a mouse interface. You can actually tell that in your hardware options, for example in Windows you will see a different icon for the mouse and a different one for the keyboard. These are two different logical entities and of course we can expect that somehow the host has some information about how each interface is reporting or consuming data.

I think I'll leave the rest for another blog post. Have in mind what a USB interface is though, cause it will be important when I'll describe the configuration of a USB device.

Παρασκευή 3 Ιουλίου 2015

Firmware internals

Since my GSoC project is on putting new functionality on a USB device, changing the device's firmware means understanding how different  levels of code work with each other. On this post I will try to provide some of the knowledge I'm gaining around this, how the systems works.

The device is built around an STM32F103TBU6 micro-controller. This features a 32-bit ARM  Cortex-M3 core with 128kB of Flash Memory and 20kB of SRAM. The manufacturer provides a set of libraries and documentation around them for several different ways that someone may utilize the micro-controller, from memory allocation or control of built-in timers, to USB interface with a host. In that way the STM32 libraries provide the first basic sets of abstraction, which includes, for example, definitions of useful memory locations, register allocation routines, etc. as regards the lowest level, and on top of that there are different levels of software abstractions, like structures and routines, which enable a developer to be able to handle effectively the operation of the micro-controller.

In our case, the USB communication routines were the ones that really matter. The U2F protocol was built around the notion that cryptographic tokens would be USB devices - at least at first - and in the future the standard will include other types of communication, such as NFC. The STM32 libraries provide the basic structures for describing a device to a USB host, listing all the interfaces by which the device is recognized at the host and communicating data between them. Of course, since active development of firmware functionalities involve a lot of low level debugging, getting to know how these libraries work is essential for successful debugging.

A lot of my work on GSoC right now involves these libraries. I guess my next blog post will be about the USB standard and how we are extending the firmware. That's all for now! :)

Παρασκευή 19 Ιουνίου 2015

I quick update about how things are going

Hello,

I meant to post last week, but I couldn't find content for a full blog post (at least for one that, unlike the blunt blog title that I chose out of poor imagination, would be coherent and structured enough. So how are things going?

The first point I'd like to address, which is the most important one IMO, is that things are going smoothly. Sure, there are a lot of obstacles, or to be exact things that seem like obstacles. But once you get the grips of them you see that it is a valuable experience; at least the way I choose to see things is that if you don't overcome obstacles, they will always be ahead of you. To be particular, personally I come from a background that put a lot of emphasis on math and abstract thought (BTW, I'm an electrical and computer engineering student. That will be one of the few personal details I think I'm willing to share publicly, and I hope you'll excuse me on that). For most of my programming years, which to be honest were before my 18s for hobbies and not counting university obligations, the computer had in my mindset infinite resources. Infinite memory, infinite processing power... At least you didn't have to deal with that. Of course, I realized the importance of technical restrictions when I got into the Engineering school, but that was for most of my classes on a theoretical level. But when you are developing on an embedded device, as Nitrokey is, then these restrictions become important. Also, as a USB device (emphasis on the U), you have to be sure to follow the standard when you ought to, and the margin for errors on that is, simply put, non-existent. And this is a whole different developing logic from following an API, in my opinion.

Secondly, cryptography is awesome! And it's nice to stray away from the academic books for once. But unfortunately this is something that would have to be postponed for the time being. Now we are deciding the system architecture, i.e. all the important aspect of how to the code should be organized, how it should function, important give-or-take aspects, preliminary choices on libraries that we might use... that kind of stuff. This is kind of hard, as it requires to have a very good understanding and on a general level. But the promising thing is that you can always feel that day by day, you are tackling the problem more and more.

I will provide more information as we are getting deeper into the coding part. As you can understand things are still fluid right now and I frankly doubt that analyzing choices that we may disapprove in the future would be of any help. So long, and thanks for all the fish.

Παρασκευή 12 Ιουνίου 2015

My first blog post

Hello people,

This is my first blog post. I operate this blog to provide updates on my participation in Google Summer of Code (GSoC). I was accepted as a student participant in FOSSASIA's program for Nitrokey (http://www.nitrokey.com) Briefly, Nitrokey is a USB device that handles public and private cryptographic keys for secure email transmission or data storage; I would deeply encourage you to visit their website for more information. Our mission is to implement the FIDO U2F authentication protocol (https://www.yubico.com/applications/fido/). But what the protocol is, that is a whole blog post by itself and I'll get to it later. :)

You can see the device in the pictures below, and I'll post updates as soon as I have them. This white flat surface that you may have seen on credit cards is the smartcard responsible for the secure cryptographic function. Sounds fun, doesn't it?

So long, and thanks for all the fish.