eToken R2 Open-source Implementation



This project intends to provide open-source support for Aladdin's eToken R2 under Linux and other operating systems by implementing all necessary APIs and tools.

The project focuses on understanding the operation and protocols of the eToken R2, and implementing an SDK for Linux to work with these tokens. The project also aims at creating end-user tools and wrappers.

A link to this project's SourceForge summary page can be found  here.


1 About eToken R2

The (now probably deprecated) eToken R2 was one of the first tokens produced by Aladdin (now SafeNet) around 2002. The device can hold data in one of three security levels
Available to everyone holding the token.
Available to everyone holding the token, and knowing the token's password
Available only to the token itself (and the manufacturer). Isn't available to the token's holder, owner or perpetrator.
On top of these three security levels, the token implements the following:
Disk-on-key style storage
Arbitrary files may be stored on the token, and accessed freely by just plugging it in. It is referred to as 1-factor authentication (what-you-have).
Protected storage
Along public files, private files may be stored. These files may also contain arbitrary data, but access to them will not be granted by the token unless the user has logged into it using a password. This referred to a 2-factor authentication (what-you-have and what-you-know).
Key files
Similarly to public and private files, two types of key files may be created on the token. These 128-bits (120-bit effective) files are write-only, and cannot be read once writtencorrect?. Key files are useful as the token allows you to encrypt and decrypt arbitrary data using these keys, without getting the keys out of the device. Public key-files may be used by anyone holding the token, while private key-files may only be used by logged-in users. Again, these are called 1-factor and 2-factor keys (not to be confused with private and public keys of an asymmetric cipher). In addition, the device supports on-chip key generationverify.
Hardware-wise, it is a simple security device, basically containing two components: An 8-bit micro-controller responsible for USB communication, encryption algorithm implementation and the token's secret data storage, providing the trusted environment for the token; and an external EEPROM, up to 32-kilobytes in size.

The secret token's key is stored on the MCU itself, and is inaccessible, even to the token's owner. It is known only to the manufacturer. It is claimed to be generated off of a true random seed for every token. The token's security is built around this key - having it will compromise all the data on the token, and everything the token gives access to. However, it should be very hard to extract this key from the token, even with unlimited physical access and destructive operations on the chip.

The on-device DES implementation isn't used directly, as 56-keybits isn't secure enough these days. Instead, the hardware utilizes a variant of the DES-X algorithm (see section 3.1), which uses a much stronger 120-bit keys.

The external EEPROM holds the device's storage (files and key-files). It is encrypted, probably using the token's internal key, making it useless to read it directly.

1.1 Filesystem Overview

The eToken supports an hierarchical filesystem structure much like any other filesystem. All files and directories have a 4-letter name representing a 16-bit hexadecimal number composed of four of the letters: 0 through 9 and A through F.

Four types of files can be stored on the token:

Root Entry
Only one exists. It is the base directory, and all other files on the token must be under it (though not directly). The token's root is referenced with the path /3f00.
A directory may lay directly under the root, or under another directory. Directories may be public or private.
File may lay right under the root directory, or under another directory. Files hold arbitrary data.
Key Files
Like files, only used for encryption and decryption.

In addition to arbitrary files and directories the user may store on the token, there are a few built-in files that have special meaning:

Application mapping filewhat is that?
Token caching mode. Either 0 or 1. Indicates (and I guess) whether filesystem changes to the token should be cached, or flushed immediately.
Token's name. User customize-able name for the token.

2 Making it Work under Linux

Support for the eToken R2 under Linux is under development. I am currently implementing the basic protocol level (ifdh) to communicate with the token, with a few user-programs to work with the token on top of that.

Currently, libifdh is capable of the following:

Still needs to be implemented:

2.1 etrtool - Direct token manipulation tool

The quickest way to get you're token working.

etrtool is a command-line tool exposing libifdh capabilities to the user. Its source may be accessed, along with libifdh source on our SourceForge project page.

See the README file for build instructions.

The latest version's man page is available online, too.

2.2 OpenCT Driver

Still under developement. Will provide an OpenCT driver for the eToken R2 to allow use with OpenSC (which will open the eToken R2 to a world of applications such as OpenSSL, OpenSSH, Firefox, Thunderbird, Enigmail, GnuPG etc.)

3 The Gory Details

This section contains documentation of the research being done on the token. It is intended to eToken R2 ifdh developers.

3.1 DES-X Application

Internally, the token implements the DES algorithm. However, to increase security, a variant of the DES-X algorithm is implemented on top of DES, using a 120-bit augmented key (instead of the 56-bit DES key). DES-X is defined as follows:

\begin{displaymath}\mathrm{DESX}(M) = K_2 \oplus \mathrm{DES}_K(M \oplus K_1) \end{displaymath}

Therefore, for a true DES-X application, a 184-bit key is needed (64-bits for $K_1$, 56-bits for $K$ and 64-bits for $K_2$). The eToken uses a shorter, 120-bits key, where $K_1 = K_2$.

From now on, we'll reference an eToken DES-X key a a pair of two keys $\lbrack K,K_x \rbrack$, where $K$ is a 64-bit DES key (56-bits effective, every 8th bit is ignored) and $K_x$ is a 64-bit block corresponding to $K_1$ and $K_2$.

3.2 USB Interface

The eToken R2 is communicated through USB control transfers. Every interaction with the token requires the host to send two control messages: Request and Result.

A basic understanding of USB packets is required for the following sections.

3.2.1 Request Control

The request control directs the token to perform an action with some optional arguments. It may directs it to read a memory address, or to generate a challenge for login.

The host should set the request packet's values as follows:

Table 1: Request Control USB Packet Structure
Request Type 0x40
Request Code Command to perform (see table 3)
Value Command argument used in some commands. Set to 0 if not in use.
Index Not in use (set to 0)
Buffer Command's input data (NULL if none)

This transfer should be followed with a result control, to obtain the token's response.

3.2.2 Result Control

The result control message stimulates the token to give back the result of the previous operation requested from it with the Request Control (see section  3.2.1).

The host should set the request packet's values as follows:

Table 2: Result Control USB Packet Structure
Request Type 0xc0
Request Code Respective request control request code, ORed with 0x80. (MSB high) E.g., If this is a result control for request 0x04, set field to 0x84)
Value Not in use (set to 0)
Index Not in use (set to 0)
Buffer Buffer to store token's response data. Should be at least one byte in length for result code (see below)

After sending this control packet, our buffer should contains the token's result data. You should always check the last byte of this buffer, as it is appended the the expected data by the token. This byte contains the token's success code for the operation. 0 indicates success, and all other values indicate failure.

3.2.3 eToken R2 Request Code Summary

Table 3: eToken Request Codes
Request Code Function Value Field Buffer
0x00 Request login challenge Not in use Not in use
0x01 Submit login response Not in use Response to token's challenge (see section 3.4)
0x03 Log-out Not in use Not in use
0x04 Get configuration word (see section 3.3) Not in use Not in use
0x05 Unknown Unknown Unknown
0x06 Read from memory address Address to read from (Big-endian) Not in use
0x07 Write to memory address Address to write to (Big-endian) Block to write
0x08 Write to key file Not in use Key buffer (see Section 3.5.4)
0x09 Select DESX Key Not in use 8-byte buffer with three address ranges (see Section 3.5.2)
0x0a Key action 0 to decrypt, 1 to encrypt 64-bit block (see section 3.5.3)

3.3 Configuration Word

The first thing you'd probably want to do when you encounter a token connected while enumerating attached USB devices is to read its configuration word. The token's configuration word is essential to know which token is connected, and what can be done with it.

The configuration ``word'' is an 26 bytes long buffer, structured as follows:

Figure 1: Configuration word structure
\bitheader{0,15} \\
\wordbox{1}{Filesystem Address}
16 bytes of unidentified data
Firmware Version
eToken's firmware version
Token ID
Current token's unique ID
Filesystem Address
Address from which to read filesystem (see section 3.6)
To obtain the configuration word, call the token with request code 0x04 (see table 3). Don't forget to allocate 27 bytes for response, and check the last byte as the operation's status code!

3.4 Log-in Challenge-response

When the token is first connected to a computer, it is in the logged-off state. In this state, the user is able to access public files and key-files only. To access private data, the token must be logged-in.

The login process with the token is a simple challenge-response protocol. First, the host requests the token for a challenge, initiating the login process. The host does so using the command 0x00 (see table 3). The token then generates a 64-bit pseudo-unpredictable challenge, $C$. The host then calculates the response as follows:

\begin{displaymath}R = E_P(C) \end{displaymath}

Where: As expected, the response to the challenge is also a 64-bit block. This response is sent to the token using command 0x01 (see table 3). If the last byte of the response buffer is zero, the token is now in the logged-in state.

3.4.1 Session Key

Once logged-in, all private-data read and written to and from the token is encrypted using a session key. The session key $\lbrack K,K_x \rbrack$ is a 120-bit DES-X key as described in 3.1, derived from the response as follows:

K = E_P(R) \\
K_x = E_P(R^{+1})


3.5 Encryption and Decryption using Keys

In order for encrypted data to be portable to the Windows implementation of the eToken SDK, we must comply with its protocol.

3.5.1 Key Files

Key files are stored on the token as 24-byte files. These files aren't readable, they are write-only. As described in Section 3.1, the token's implementation of DESX assumes that $[K_1 = K_2]$, allowing us to store only 16 bytes of key data. However, this is not the case. When addressing a key, we must specify three address ranges, each 8-bytes long (presumably ranges for $[K,K_1,K_2]$). When writing to a key, we specify 24-bytes addresses, but supply only 16-bytes of key material. These three address ranges are always consecutive in memory.

3.5.2 Selecting Key File

To perform a DESX function with a key file, we must first select the current key file with command 0x09.

The token expects to find an 8-byte buffer with this request, structured to point to $[K,K_x]$ as follows:

Figure 2: Set DESX Key Command Buffer Structure
\bitheader{0,15} \\
...endwordgroupr \\

The token should respond with a single byte indicating success.

3.5.3 DESX Operations with Current Key

After notifying the token which key we would like to use (see Section 3.5.2), we send the 0x0a command, to perform actual DESX function. (The Value field indicates whether we're encrypting or decrypting, see Table 3). The token can only operate on one block at a time.

Since DESX is a block cipher, padding must be used. The eToekn R2 employs the padding method suggested in RFC 1423 (Section 1.1):

The input to the DES CBC encryption process shall be padded to a multiple of 8 octets, in the following manner. Let $n$ be the length in octets of the input. Pad the input by appending $8 - (n \bmod 8)$ octets to the end of the message, each having the value $8 - (n \bmod 8)$, the number of octets being added. In hexadecimal, the possible paddings are: 01, 0202, 030303, 04040404, 0505050505, 060606060606, 07070707070707, and 0808080808080808. All input is padded with 1 to 8 octets to produce a multiple of 8 octets in length. The padding can be removed unambiguously after decryption.
IMPORTANT! Since the token can only handle one block at a time, the block-cipher mode in use is up to the implementation. It seems that the Windows SDK implementation has chosen the incredibly inadequate ECB mode (probably because it's the only mode that doesn't require an IV). This insecure behavior must be imitated for our implementation to be able to work with the Windows implementation. I have also introduced into the API an optional cipher mode argument, allowing the use to select a different cipher mode (such as CBC). These outputs, however, are not compatible with Windows SDK outputs and vice-versa.

3.5.4 Writing Key Files

Key files are writable. To write to a key file, you must be logged-in. Key files are written using the 0x08 command. The buffer expected by the token is the same buffer as in the select key command, except 16-bytes of key-data encrypted with the session key (see section 3.4.1) should be appended, like so:
Figure 3: Write DESX Key Command Buffer Structure
\bitheader{0,15} \\
\wordbox{1}{Key fil...
...kippedwords \\

3.6 Filesystem

Please read section 1.1 before reading on.

The eToken should be regarded as a 64-bit block device (corresponding to a DES block size). Aladdin has implemented a simple block allocation table structure indexing the block-to-file allocation.

The filesystem is a list of 64-bit entries, as follows:

Figure 4: Filesystem Structure
\wordbox{1}{Header} \\
...$\vdots$\ \\ [1ex]} \\
\wordbox{1}{Entry~$N$} \\
Notice that the first entry is a header (or signature) entry, which does not hold file information. Instead, it should read:

\begin{displaymath}\begin{array}{ccccccccccc} \mbox{a5} & \mbox{5a} & 00 & 00 & 00 & 00 & 00 &
00 \end{array} \end{displaymath}

Note that entries in the filesystem appear in no particular order, except the root entry 3f00 is always first.

To get the filesystem from the token, invoke the read-from-memory command (see table 3) on the address indicated in the configuration word (see section 3.3). The operation will return the entire filesystem index. Be sure to allocate enough space for all the entries, signature and last status byte in the receive buffer. I found that my 16kb token returns 31 entries in addition to the signature entry.

Each entry should look as follows:

Figure 5: Filesystem Entry Structure
\bitheader{0,15-16,31} \\
\bitbox{16}{Name} & \bitbox{16}{Size} \\
Entry's name.
File size, in bytes (if file or key file)
Read as follows:
Figure 6: Attributes Field Structure
... &
\bitbox{5}{Parent} &
Address of first file's block to be used with read-from-memory command
Whether the entry is a key file
Whether the entry is public

Table 4: Filesystem Attribute Entry Types
Value Type
1 File
2 Directory
3 Key File

Index of parent's folder entry in the filesystem. Index 0 means this entry is right under the root. See figure 4.

List of Figures

List of Tables

Generated by z9u2k at Sat Jan 15 11:44:58 UTC 2011 Get Aladdin eToken R2 Linux Driver at Fast, secure and Free Open Source software downloads