A USB dongle for one-time passwords

Secret Stick


If you are ready to experiment, an OpenKubus USB stick just might solve your password problems.

By Benedikt Sauter, Michael Hartmann, and Nils Magnus

Ivan Mikhaylov, 123RF

When it comes to authenticating users, most Linux administrators rely on passwords. Of course, this causes no end of problems: If users are allowed to choose their own passwords, they are often too short and too easily guessed. If a random password generator creates the passwords, they are likely to be so complicated that users will forget them, or else the users will write down their passwords then leave the notes out in public places. Secrecy is difficult to ensure in unfamiliar environments where key loggers and shoulder surfers lurk. One-time passwords (OTPs) solve this dilemma: Because one-time passwords become invalid after one use, nobody is likely to worry about whether they are sniffed.

Password generators create lists with huge numbers of passwords and store a copy of the list on the server on which the user needs to authenticate. The idea is that the user carries a second copy of the list. For each authentication, the user and server just use the next password on the list. An example of this technique is the TAN method used by many banks for secure transfers in online banking.

When a user logs in, the system can prompt for, say, the tenth password on the list. Anybody with the password list can look up the matching password and authenticate. The disadvantage of this approach is that it is often impractical. Users need to carry the list around with them at all times; when they log on, they need to grab the list and painstakingly type the password. Of course, this technique also does not prevent the possibility that the list could fall into the wrong hands.

Systems that generate dynamic passwords are more practical. An on-board client application for generating passwords will work fine if you never change locations, but this approach isn't very portable. A better solution is to generate one-time passwords with an external hardware token. Several forms of hardware-based, one-time password tokens exist. (See the article on "One-Time Passwords" in the November 2008 issue for more information [1].)

Many of the hardware-based password tokens are proprietary; however, a universal programming adapter based on the open USBprog hardware platform is available for implementing one-time-password solutions. This platform uses the popular ATmega32 microcontroller - an inexpensive alternative with many free developer applications. A second component, the USBN9604, supports USB access. This variant can be built easily with the addition of a single button (see Figure 1). The PCB, component list, and wiring diagram are available under the GPLv2 license [2].

Figure 1: One variant on the project uses the USBprog adapter with a button. Pressing the button transfers the password.

From the computer's point of view, the stick is a USB keyboard, and many operating systems have driver support for it. When the user presses the button, the stick outputs a password that is generated according to the method shown in Figure 2.

Figure 2: The token references the data block and a serial number to calculate the one-time password, uses AES to encrypt, and performs something similar to Base64 encoding.

The OpenKubus project has developed a second layout that is functionally equivalent to the previous open token. The OpenKubus token fits in an even smaller housing and has far fewer parts (see Figure 3). The microcontroller is an ATmega16U4, an ATmega16 with an integrated USB controller. The good thing about the OpenKubus option is that you can purchase a prebuilt version of the hardware on the web for around EUR 25 [3]. This prebuilt token will allow you to experiment with hardware-based one-time-passwords without having to build your own hardware.

Figure 3: If you are afraid of soldering, you can buy a prebuilt OpenKubus stick in a housing. This version includes the USB driver in its ATmega16U4 microcontroller.

How It Works

The program running on the stick uses a 14-byte data block comprising random digits or a stick ID. The microcontroller prepends a 2-byte serial number. When a user presses the button, the microcontroller concatenates the serial number and the data block and encrypts both using a 256-bit key stored on the stick. An EEPROM on the controller chip stores these three data snippets.

The last step is for OpenKubus to convert the 16 bytes of encrypted one-time password to printable or typeable characters and send them to the USB keyboard driver (see Figure 2). Because the stick does not know which keyboard variant is currently active on the computer it is attached to, it sends the key code for a z to distinguish between German and English language layouts.

Let Me In!

To check these credentials, the other end needs the data block, the AES key, and a serial number. It converts the keyboard input back into the 16 bytes of the one-time password and decrypts by using the symmetric AES key. The first two encrypted objects must have a higher value than the one stored server side - this allows the system to detect replay attacks. If OpenKubus needs to authenticate against more than one device, the servers need to synchronize the serial numbers. Both the server and the stick then increment the serial number. In the current setup, the server will go on strike after 65,536 applications, at which time, the current firmware does a wraparound.

OpenKubus uses AVR-Crypto-Lib as the cryptography library on the stick; the library includes a large collection of cryptographic functions for Atmel microprocessors and takes the meager flash and RAM resources into account. The large number of supported algorithms enables the use of other cryptographic methods if you are prepared to experiment. Other changes, such as a different approach to handling wraparound or a bit shift in the data block driven by the serial number, are also possible.

Setting Up

After putting the hardware together, or opening the package if you order the OpenKubus version, you need to compile the firmware and transfer it to the device. If you bought the latest OpenKubus version (see Figure 4), you can also omit this step because the software is already in place.

Figure 4: The new OpenKubus version relies on an ATmega16U4, which also drives the USB side.

The command

svn checkout http://openkubus.googlecode.com/svn/trunk/ openkubus-read-only

picks up a current snapshot and dumps it on your machine [4]. Additionally, you need the gcc-avr and binutils-avr packages for the AVR-GCC cross compiler [5]. The avrdude package includes tools for transferring firmware. All of these packages are available from the Debian repositories; you might need to build them for other distributions.

Most subdirectories include separate makefiles: The firmware requires the cryptographic functions, and make in the firmware/crypto-lib/ directory builds them. On the other hand, if you will be using the USBprog variant, you need to build the firmware in the firmware/secstick_v1/ directory.

For the second OpenKubus hardware version, change to the firmware/secstick_v2/ directory. Then run avrdude and a programmer such as USBprog to transfer the prebuilt firmware image, openkubus.hex, to the microcontroller's flash memory. As an alternative, an Atmel MkII will help you transfer the software; the USB port is not enabled at this point.

Loaded and Secured

OpenKubus is now ready, but it doesn't know your secrets. The stick-write tool in firmware/create-stick loads the three pieces of information into the EEPROM. A tool for preparing the stick does not exist as of this writing, so some manual work is now required: The -p option expects 48 characters - 32 bytes of AES key, a 14-digit data block, and two octets of the first serial numbers, without any separators.

The tool uses USB to transfer the command-line arguments to the stick without converting them. If you want to transfer binaries, you need to modify the source code. The -l option tells the firmware not to accept any more initial passwords. Of course, you could use the programmer to harden the stick, but this means that it will not accept firmware updates either.

PAM's Wedding

Most Linux distributions use PAM to authenticate users. This means that you can teach programs like login or sshd new authentication methods. OpenKubus includes its own module in the software/PAM/ directory that requires the PAM developer files from libpam0gdev. A call to make install copies it to the /lib/security/ directory and modifies the privileges. After completing the installation, and working as root, configure the modules in /etc/pam.conf or in the /etc/pam.d/ directory. Adding

auth sufficient pam_openkubus.so

to auth-common tells PAM to accept the stick [6] as an alternative in the future.

Verifying Passwords

To verify the authenticity of a password, the PAM module needs to know the stick's secrets. To allow this to happen, the administrator will store a line matching the user password serial_number format in /etc/openkubus-passwd. PAM compares the data with the input from the stick. Make sure the file is only readable by the root user.

If you want to check input from OpenKubus in your own applications without resorting to PAM, the lean OpenKubus library is a useful option that the project offers for many programming languages. The library itself is written in C, but the SWIG wrapper gives Python, Ruby, Java, Perl, or PHP access to its functionality [7]. Right now, the API only includes the following function:

int openkubus_authenticate(const char *pad,const char *pw, int offset, int num);

This function expects the one-time password to check as the first argument and the AES key as the second. The last two arguments are an optional serial number offset (which defaults to 0) and the serial number itself. If successful, the function returns the serial number; if not, it returns a negative value.

The library only checks the password; it does not access a file. Developers who use OpenKubus need to manage the current serial number, the initial password, and the offset themselves. The sample network server in software/server/, which compares one-time passwords with a list, gives you an idea of how to manage these parameters.

Conclusion

The benefits of OpenKubus include portability and the ability to customize hardware without breaking the bank. The drawback is that the stick and all the servers need to synchronize the serial number. If you need to authenticate against multiple servers, you will need a central server. Tools for managing OpenKubus in larger environments with large numbers of users are still rudimentary.

OpenKubus will not protect you against man-in-the-middle attacks [8]. The service you are calling has to demonstrate authenticity separately. However, the project is an exciting platform for any administrator interested in experimenting.

INFO
[1] "One-Time Passwords" by Udo Seidel, Linux Magazine, November 2008, pg. 22
[2] USBprog wiring diagram: http://www.embedded-projects.net/usbprog
[3] Shop for OpenKubus hardware: http://shop.embedded-projects.net
[4] OpenKubus: http://code.google.com/p/openkubus (in German)
[5] Installation notes on AVR-GCC: http://www.nongnu.org/avr-libc/user-manual/install_tools.html
[6] PAM configuration syntax: http://kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-configuration-file.html
[7] Wrapper Generator SWIG: http://www.swig.org/
[8] Man-in-the-middle attacks: http://en.wikipedia.org/wiki/Man-in-the-middle_attack
THE AUTHOR

Benedikt Sauter and Michael Hartmann are both interested in open source and hardware tinkering. The authors both work on customizing embedded devices for the OpenKubus project.