Skip to content

JavaCard software implementation of HMAC_SHA256 for cards without native HMAC implementations

Notifications You must be signed in to change notification settings

greigdp/Javacard-HMAC_SHA256

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

HMAC_SHA256 Software Implementation on JavaCard

Note: This should be considered a proof-of-concept, not a production-ready implementation.

Motivation

The widely implemented symmetric authentication functions on JavaCard are, for the most-part, relatively weak. While there is no particular weakness in CBC-MAC, if properly implemented, the constraints on it make CBC-MAC difficult to use in real life.

A number of example attacks are shown on Wikipedia, including where the same symmetric key is used both for CBC-MAC and for encryption, or where a variable-length message is being authenticated.

There is therefore a benefit in using a symmetric authenticator function which does not require considerations such as whether or not a message which prefixes another message will ever be created. HMAC functions are ideal for this, since they are based on cryptographic hash functions.

Unfortunately, HMAC functions, while supported in JavaCard 2.2.2, are not widely implemented; only a handful of cards implement any HMAC.

Software Implementation on JavaCard

A limited implementation of HMAC on JavaCard is available in this repository. Note that this is not a full implementation compatible with the reference RFC in every way. In particular, your attention is drawn to the lack of support for keys which are longer than the hash block length (for SHA256 this is 64 bytes), or where the key is shorter than expected.

This is therefore not for use with arbitrary keys - it should only be used where a fixed, 32-byte (256-bit) symmetric key can be securely generated by the smartcard.

Security Note

Note that for ease of verification, the applet enclosed features a function to retrieve the symmetric HMAC key from the device. It should go without saying, but this must be removed for any sensible use beyond learning or playing around. Anyone who gains access to the HMAC key can generate valid signatures of any data, so this key must not be exposed by the smartcard.

Verification Against Reference Implementations

In order to verify the operation of this HMAC_SHA256 implementation, a Python script is enclosed, which will calculate HMAC_SHA256 of a given message, using the same HMAC key. If the Python implementation and smartcard agree, this indicates the implementation operates correctly, at least for that scenario.

Take heed of the warning above, however, about this implementation not having support for variable-length (i.e. user-set) keys. Use this only with data of up to 255 bytes, and a key of 32 bytes (256 bits). This is a suitably long key for HMAC into the future.

Using the Applet

To test using GlobalPlatform,

  1. Install the applet

     $ java -jar gp.jar --default --install <compiled_name.cap>
    
  2. Generate a new HMAC key

     $ java -jar gp.jar --applet 00112233445500 -a 8000000000 -d
    
  3. Retrieve the HMAC key (note that no real-world applet should ever allow this!)

     $ java -jar gp.jar --applet 00112233445500 -a 8002000020 -d
    
  4. Generate an HMAC of a message (upto 255 bytes is possible) - for example, let's do the 5 bytes: {0x01, 0x02, 0x03, 0x04, 0x05}

     $ java -jar gp.jar --applet 00112233445500 -a 8001000005010203040520 -d
    
  5. Place the returned values into the Python script and ensure signature verification succeeds. Ensure the public key, message and signature values are all updated properly.

Generate a new key per step 2 as required, to test for multiple keys

About

JavaCard software implementation of HMAC_SHA256 for cards without native HMAC implementations

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published