Anatomy of a MAC Command
Many of ID TECH’s customers are interested in point-to-point encryption (P2PE), and as part of their quest to achieve compliance with PCI’s stringent P2PE rules, customers often consider SRED (Secure Reading and Exchange of Data) payment devices. Such devices not only encrypt data at the point of capture (as all of ID TECH’s devices are capable of doing) but also incorporate tamper detection, automatic data zeroization in the event of tamper, and other specialized security
Chief among the “other specialized security features” is something known as MAC authentication of commands.
In cryptography, a message authentication code (MAC) is a short code used to allow the receiver of a message to authenticate the message—in other words, confirm that the message came from a trusted sender. The MAC value protects both a message’s data integrity as well as its authenticity, by combining the message with a secret known to both the sender and the receiver. The message is sent in the clear, but also, the message-plus-MAC (which contains the secret, encrypted) is sent. Anyone with the secret can tell if the message (and its extra MAC content) came from somebody else with access to the same secret.
In ID TECH’s SRED-based card readers, certain sensitive commands are MAC-protected, which means the device won’t execute the command unless the command comes with a MAC hash that can be verified (using a key already stored in the device). The sender of the command must craft the MAC hash using the same key the device will use to validate it.
An example might make this clearer.
An example might make this clearer.
Suppose you want to set the date and time on an ID TECH Augusta S card reader, which is an SRED device. The “Set Date and Time” command is considered sensitive, because an unauthorized party shouldn’t be allowed to back-date (or otherwise alter) transactions. (Other “sensitive” commands include, for example, commands that add or remove cards from a white list, or that modify the device’s Certificate Revocation List.)
Ordinarily, you would set the date and time of a non-SRED Augusta using the firmware command of 78 53 01 50, followed by the payload length (0x08), then the date/time length (0x06), then the six bytes of date and time, as YY MM DD HH MM SS, followed by the “MAC length,” which (for a non-SRED device) is zero. In Augusta S, the foregoing formula is the same, except that the payload length is 0x26 and the “MAC length” is 0x1E, because 30 extra bytes of “MAC payload” get tacked onto the end of everything.
Of course, with Augusta, the entire command needs to be formatted in ID TECH’s NGA protocol, which is a matter of putting STX (0x02) and two little-endian length bytes on the front of the command structure, and LRC, checksum, and ETX (0x03) on the end of the command structure. The final MAC version of the whole command looks like this (with command bytes in yellow):
02 2B 00 78 53 01 50 26 06 17 11 10 09 15 00 1E 10 00 4E C7 DF CF 04 D3 3C C6 EC 6F 50 92 00 86 A1 DD 0A 00 62 99 49 00 00 00 00 00 00 02 EB F9 03
Let’s break it down, section by section:
02 is STX.
2B 00 is the (little-endian) length of the whole structure, less the LRC/checksum/ETX trailer.
78 53 01 50 is the Set Date and Time firmware command.
26 (hex) means 38 bytes of payload follow.
06 means the date/time consists of 6 bytes, namely.
17 11 10 09 15 00 — 2017 November 10, 09:15:00 am.
1E means 30 bytes of MAC payload follow.
10 00 is a little-endian length value of 16 (because all ID TECH MAC hashes are 16 bytes long).
4E C7 DF CF 04 D3 3C C6 EC 6F 50 92 00 86 A1 DD is the 16-byte MAC hash, or “HMAC”.
0A 00 is a little-endian length of 10, for the KSN that follows.
62 99 49 00 00 00 00 00 00 02 is the MAC KSN.
EB is the Longitudinal Redundancy Check value.
F9 is the 8-bit checksum of everything from 78 to the final KSN byte (of 02).
03 is ETX (end of transmission).
There’s nothing particularly difficult about constructing this command. The non-self-explanatory parts are the KSN, and the HMAC (the hash itself).
The MAC KSN (Key Serial Number) is something you have to query the device for, at the time you need it. If you’re familiar with ANSI X9.24-1 (the Derived Unique Key Per Transaction standard), you know that the KSN is a 10-byte value in which the bottom 21 bits constitute a counter that increments after every usage. What you might not have realized is that if a device contains multiple DUKPT keys (for Data, MAC, and PIN, say), each one will have its own dedicated KSN that increments out of sync with the others. The KSN is a public value, though, and you can query the MAC KSN, in ID TECH’s Augusta, with a (complete, formatted) command of 02090078463e040005010000000603, at any time.
The KSN is important, because it is part of the calculation of the MAC key, which is unique per usage (hence not subject to replay attacks). For more information on KSNs and DUKPT key derivation, see my earlier two-part post on that subject.
Now comes the geeky part.
HMAC (see RFC 2104) is an industry-accepted way of creating MAC hashes using:
— a 128-bit one-time key
— an arbitrary message payload
— SHA-256 hashing
The key in question is derived, dynamically, using the MAC KSN and the device’s IPEK (which in turn derives from a BDK), according to standard DUKPT rules. The rules call for a certain way of deriving a MAC key (as opposed to a data key or PIN key). It’s all described in my earlier two-part post
The fearsome HMAC hash is calculated according to the following super-scary-looking recipe:
H( (K’ ⊕ opad) ‖ H( (K’ ⊕ ipad) ‖ m) )
Don’t be put off by this. It’s actually quite understandable. The value K is the 128-bit key. K’ (k-prime) means that same key, zero-padded to a total length of 64 bytes.
The ipad (inner pad) is just the constant 36363636… repeated to a length of 64 bytes.
K’ ⊕ ipad means to combine the zero-padded key with the ipad value, using exclusive-OR (aka XOR), which is a bitwise arithmetic operation beloved by computer science geeks.
K’ ⊕ ipad) ‖ m means to append the message (m) to the value obtained above. Just add the bytes onto the end. (The length will be greater than 64 bytes now. Don’t worry about it.)
H( (K’ ⊕ ipad) ‖ m) means to apply your hash function (in this case, SHA-256) to the entire value in parentheses.
When you’re done with that step, you’ll append the result to K’ ⊕ opad, where opad (the outer pad) is a constant consisting of 5C5C5C5C… repeated to a length of 64 bytes. Then you’ll hash the whole thing yet again.
In case you’re wondering, ipad and opad values were chosen (by the original authors of this algorithm) arbitrarily, but in such a way as to maximize the Hamming distance (or bitwise differences) between the front and back halves of the hash. The hash is done in halves, in nested fashion, to prevent various forms of spoofing.
To help you with the creation of HMAC values, ID TECH has posted an HTML form online here, in which you can enter KSN and BDK (root key) values, derive your MAC key, and use HMAC to create a 32-byte MAC hash (via SHA-256). Be sure to try the “Generate HMAC (with verbose output)” option from the dropdown menu at the top of the form. You’ll get a very handy verbose output trace that explains, in no uncertain terms, what each piece of the HMAC puzzle looks like.
If you use our online tool to generate a MAC key using a KSN of 62 99 49 00 00 00 00 00 00 02 and a root key (BDK) of 0123456789ABCDEFFEDCBA9876543210, which is the ANSI standard test key, your MAC key should have a value of 3E4A480ACE8B239B9539E6053EAB03D9. If you apply the HMAC algorithm to a payload of 78 53 01 50 26 06 17 11 10 09 15 00 1E 10 00 using that key, you should end up with a 32-byte HMAC hash, of which the first 16 bytes are 4EC7DFCF04D33CC6EC6F50920086A1DD. (ID TECH uses only the first 16 bytes.) This is the magic “fingerprint” that will get added to the Set Date and Time command. The card reader will look at the cleartext payload bytes, and use its own KSN and internal key derivation code, to come up with the same HMAC value that you included in your command, verifying that the command must have come from a source that knows the magic BDK (0123456789ABCDEFFEDCBA9876543210); hence, a trusted source.