# SCP02

**Sat, Jun 13, 2020 7:42:39 AM**

This is about the GlobalPlatform Secure Channel Protocol 02 (**SCP02**) technicalities.

So that the bytes that goes *into* the card is not readable by anyone that sniffs on the transmission medium, the two communicating entities shall use a secure channel protocol. These two communicating entities we shall named as:

* offcard (*or the laptop*)
* card (*or the Java Card applet inside the smartcard*)

The communication medium is either wired (via USB) or wireless (via NFC). The Global Platform specification defines the requirement of the SCP02. The smartcard uses the Java runtime environment or JCRE as its operating system interface layer on top of which an application shall run, known as an applet. The Global Platform also defines the presence inside the smartcard  some core security applets whose responsibility is to register and manage the user applets. Therefore, user applets shall be installed into the smartcard using the mechanics defined by Global Platform. You cannot go inside the house through the backdoor. &#x20;

Unlike in the desktop JVM world where an instance of `java hello` runs on its own JVM and various classes inside can easily communicate to each other.  There is only **one** JVM running inside the smartcard! But this is a modified JVM so other applets are firewalled from each other. The smartcard is designed to accommodate several applets from multiple organizations just like we have firefox and chrome browsers. We have mspaint and MSWord too.  Therefore, many cooperating or competing applets can co-exists and execute inside one smartcard.&#x20;

The Global Platform defines the SCP02 in a PDF document it describes the necessary cryptographic primitives to be used and other operational sequence so that the offcard and the card can prove each other's identities and establish a secure channel for secure communication. An identity has component keys ENC, MAC and DEK. A proof means possessing same value of a key. Proof is not instantaneously bidirectional.&#x20;

The SCP02 uses symmetric cryptography. This means that both the card and the offcard are already setup to have the same keys, a priori. On how the keys got there, is not part of the protocol. The keys are just there to begin with.&#x20;

The communication of the offcard and the card relationship is one-sided. It is always the offcard that opens the communication and the card shall only reply. In order for both the card and the offcard to truly ascertain that they are communicating to a legitimate entity (not an impostor), the SCP02 protocol is used. Take note that this identity doubt is on both sides. The offcard or laptop cannot be sure who is inside the card because card may look the same, but what about the running applets inside it? The card also cannot be sure who is at the outside world that is sending data to it. Both of them possessed the same key sets (symmetric keys), but neither of them can send this key to prove who they are, because of the below common sense reasons:

* If the offcard **securely** sends its key to an impostor card, then the impostor card will know the key and will pretend to impersonate.&#x20;
* If the offcard sends its key to a real card, then somebody is sniffing on the communication and can read this key.&#x20;

There is just no easy way to introduce each other by giving out an ID like how humans would do to introduce who they are. In the following narrative we shall see how these two entities can be introduced to each other without giving out their keys. I am in awe of this mechanism, as it felt the same when playing chess through the moves alone you can know who is at other side of the board. Identification by computation. This was how `Seraph` identified `Neo` in the movie `The Matrix`

The SCP02 defines the steps that needs to be done so that the offcard and the card can prove each others identities. For digital systems without eyes and ears, this is *not an easing thing to do*. In addition to proving each others identities, the communication channel is also secured. Cryptography is a method to make something unrecognizable. And then, this very same method becomes the means to certainly recognize something. Let us begin:

**I. Card Proves to OffCard**

Take note of the irony in the `Card Proves to OffCard` title. The card cannot initiate the communication to the offcard because the card can only reply. It is the OffCard that initiates the very first communication. But it is the `card` that first proves its identity.&#x20;

The offcard sends 8 random bytes and a `key_index`to the card. I call this the `host_challenge`

```
80500000 0856372B 20A7F122 8C
    ii     ^^^^^^^^^^^^^^^^^^
```

The offcard decides to send`key_index` `00` . The 8 bytes are randomly generated `56372B20A7F122BC`

Starting here is a key concept not many knew or they take for granted. A `key_index` of `00` means the offcard lets the `card` choose which key set to use. The `80 50` is what is called **INITIALIZE\_UPDATE** in the **CLA**, **INS** byte specification.&#x20;

The card receives this. The card now parse the components of this first message:

* 4 bytes command `80 50 00 00`
* 1 byte length
* 8 bytes `host_challenge`

It is now time for the card to parse this received message. First let us describe this particular very special 2 bytes in the card.

The card, as in the spec, maintains an incrementing **two bytes counter** called `sequence counter`. The card generates only 6  random bytes. The 2 bytes from the `sequence counter` is concatinated to the 6 random bytes to form the `card_challenge` = `AAA0 5905AAB0DD27`

The `sequence counter` here is `AA A0` and is concatinated with 6 other random bytes to form the 8 bytes `card_challenge` array.

Because `key_index` is `00`, the card then looks up into its list of keys and the card decides and chooses an index of its own preference. It is expected, that the offcard also possessed the same key set pointed by an index in order to continue SCP02. Otherwise, there will be a **cryptogram** mismatch if key sets under a given index do not match. Or if the index is missing, there will be the `No such key` error. &#x20;

The selected 16 bytes keys (selected via an index) together with the `sequence counter` and using **DES** cryptography with IV of `0's` **SHALL** produces three session keys of 16 bytes each. They are usually named as:

* sessionKey\_ENC  (16 bytes)
* sessionKey\_MAC (16 bytes)
* sessionKey\_DEK  (16 bytes)

Think of these newly generated session keys as ephemeral doppelganger versions of the true ENC, MAC and DEK keys which is always kept secret never goes out. **NEVER**.

Which among the keys of ENC, MAC or DEK to use is also describe in the SCP02 protocol.  It is expected that the offcard shoud be able to arrive at the same values for ENC, MAC and DEK. The **knot** that assures this equivalence between card and offcard are the following:

* sequence counter
* key index
* a common key listing&#x20;

The `sequence counter` is publicly readable. The `key_index` can be sniffed during INITIALIZED\_UPDATE. The **key listing**, however, is never revealed for it holds the keys to the kingdom. It is not revealed even among its inner circle, but is instead computationally verified in the inner circle. Just like how `Seraph` verified `Neo` in `The Matrix`

Cryptography has this magical property wherein you can prove that `a` equals `b` without retrieving the actual values of `a` and `b` . Again, there is something similar in chess with regards to this property. It has to do with proof-of-work. &#x20;

The card concatinates the `host_challenge` and the `card_challenge` arrays to form a 16 byte array we shall name as `hostcard_challenge`.  The card calculates the cryptogram of `hostcard_challenge` using `sessionKey_ENC` . Therefore, the card uses the ENC key to introduce itself to the offcard. You shall later see below how the offcard introduces itself to the card, which varying granularity dependeng on wither the offcard encrypts the message or just tagged it. Let's cut to the chase: *down later explained below, if the offcard's second packet is encrypted then the offcard is introducing itself to the card via possession of ENC and MAC key.*

Below the arrow going right is what offcard sends to card, and the arrow going left is the card's response.

```
==> 
      ??
80 50 00 00 08 56 37 2B 20 A7 F1 22 8C       
<== 
01 02 03 04 05 06 07 08 09 0A 03 02 AA A0 59 05 AA B0 DD 27 D5 F9 5F 90 F4 7B F5 F9 90 00
                              ^^ ^^ ....................... ***********************
```

It is now time for the offcard to parse the card's response.

Ignore the first 10 bytes in the card's response, it is known as *diversification data*. The `03` is the index choosen by the card. I marked with `??` where the offcard pass `00` to emphasize the fact that the offcard lets the card to decide on the index. The `02` means the card uses `SCP02` protocol. It is elegant how the offcard is not assuming or forcing with regards to the protocol, and the card being the low-powered it decides what its protocol is. Using the `03` ,the offcard indexes into its own list of key sets and do the same thing what the card had done to come up with hopefully same values of ENC, MAC and DEK. The offcard constructs the `hostcard_challenge` by concatination of the `host_challenge` and the `card_challenge` that it receive now from the card (those marked as dots above snippet is the `card_challenge`). And then the offcard computes the cryptogram of `hostcard_challenge` and compares result against what the card computed which is in the response those marked as asterisk in the above snippet. If the 8 bytes cryptogram matches, then **the offcard can conclude** that the card and the offcard has matching ENC key. Take note, at this stage the card still has no proof of the legitimacy of the outsider (ie offcard) that is trying to send data to it. The **INITIALIZE\_UPDATE** only proves the card's ENC key value to the offcard. Also take note, that the actual value of the core symmetric keys did not travel in the wire (or air) in this proving business. Even the session keys did not travel over the wire as well, but instead they are computed. The relevant pieces of information that travelled over the wire were the following.&#x20;

The notation `o -> c` is a shorthand for `offcard -> card` and vice versa.

**INITIALIZE\_UPDATE what travelled across the wire unencrypted:**

| Information       | Description                                                                                                                                                                                                                                                  | Direction |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- |
| `host_challenge`  | It is an 8 bytes random array that the offcard generated and becomes a content of the very first message that the offcard sends to the card                                                                                                                  | o -> c    |
| `key_index`       | The index value that the offcard decides to use. If this value is `00`, then the offcard lets the card to decide which index to use                                                                                                                          | o -> c    |
| `card_challenge`  | The first 2 bytes is the card's **sequence counter** and the 6 bytes is randomly generated by the card. The sequence counter increments for every successful SCP02 establishment. So this is a measure of how many offcards the card has talked to securely. | c -> o    |
| `key_index2`      | The index that the card uses for the key set.                                                                                                                                                                                                                | c -> o    |
| `card_cryptogram` | An 8 bytes computation result on the `hostcard_challenge` data using the session key generated from the index                                                                                                                                                | c -> o    |

I'm not including in the list the `diversification data` 10 bytes those bytes are not included in the particular secure channel setup here. I am sure those bytes are important addition to even increase the security, but i only discuss here the core fundamental parts.&#x20;

Both the offcard and the card keep a listing of key sets in such a way that an integer index points to the same key on both. The offcard  or card may have more items in its own copy of the key listing, but the important thing is that whatever index gets used, it must point to the same key set. Take note also, this first stage of contact of the card and the offcard is not in a secure channel so we expect that a sniffer has knowledge of the information listed in **INITIALIZE\_UPDATE** unencrypted what travelled info table above.&#x20;

I forgot to mention late now, but the key listing you can visualize as something like:

| ENC                                | MAC                                | DEC                                |
| ---------------------------------- | ---------------------------------- | ---------------------------------- |
| `63e88d8dd77a7f61afa37d73211c43ab` | `82a3384eeed80b0627f3e3074596dc96` | `0d2e02a8e7187cb1be97185a7781af2e` |
| `68c519fd95926e66c9df4e86ba826ee6` | `ed0567693a84538836e0244ebb819831` | `5ea71cc85ccf2f0b6c4a99cbb1641b85` |
| `e4b8c16d0a660f9e12c17c9ae25cfd2e` | `881871e60411425cc0f62141b0bc9411` | `8c19c2b174baaf3635dd882a849664e8` |

The `key_index` picks a row from this key set table. Each row has 3 columns for ENC, MAC and DEK which are nothing more but just cryptographic keys with specific purpose following the SCP02 protocol. I also forgot to mention there is a special `key_index` whose value is `FF` to mean that, both the offcard and the card shall use the factory default key setting which is `40..4F` well known value for each of ENC, MAC and DEK. I think this factory default specific value is decided by a manufacturer such as **NXP Semiconductors** and not by the Global Platform spe&#x63;**.** Whatever is the value of the default key set, the vendor must tell you about it. Otherwise, you cannot use your newly bought Java Card. ***But here is wisdom***: Once you add your personal key set, the factory default key index signified by `FF` is vanished forever and your newly added key set shall become the keys to the kingdom with that specified `key_index` value.

**II. OffCard Proves to Card**

Secure channel is not yet setup. The offcard now decides the texture of the secure channel (of the card's protocol). By setting these bit fields:

* MAC tag every message sent to card (`00000001`)
* Encrypt every message sent to card   (`00000010`)
* MAC tag card's response (RMAC)       (`00010000`)
* Encrypt card's response (RENC)          (`00100000`)

Contrary to what one expects, a secure channel is not necessarily encrypted. The minimum is that a message has a MAC tag attached to it in order to prove that the message is not modified and it is coming from the legitimate sender. But as written in the SCP02 specification, if the message is encrypted then a mandatory MAC must be attached. Take note, that in theory of cryptography the attaching of MAC in an encrypted message is not a core requirement. You can encrypt without involving MAC. But in the SCP02 protocol, it is written to do it this way. I'm saying this to have a distinction between cryptography concepts versus a security protocol implementation. &#x20;

Up until at this point,  let us described what just happened. First the offcard sends its **first packet** to the card. Next, the card responded and the offcard received this response. No secure channel is setup yet.&#x20;

Now, the offcard is about to send a **second packet**.

Let us take the case where the offcard decides to established an **encrypted** secure channel. The offcard must set two bits corresponding to MAC(1) and ENC(2) bitfields. Or in binary, `00000011` .

The variable that carries this piece of info is the `securityLevel`.&#x20;

The offcard concatinates the `card_challenge` and the `host_challenge` arrays together to form the `cardhost_hallenge` 16 bytes array. The offcard computes the cryptogram of `cardhost_challenge` array using DES and `sessionENC` key with ICV of `0s`. By the way, the hairy details please read in code, but the important thing here is the high level of what is happening. You will notice, that these are the same steps that the card did to the `hostcard_challenge` array. This time, the offcard is doing it to the `cardhost_challenge` array. The two arrays are in reverse concatination **stare very closely don't blink**. However, at this phase is the beginning of deep cryptographic voodoo which is why I am drafting this blog so that I can understand it. You can stare forever a 10 line simple cryptographic application code and never understand it if you don't take the time to understand cryptography. This is not javascript where you type very fast very loud, and then take a sip of coffee feeling like master of the universe.&#x20;

I will skip the minute details, but I will emphasize the semantic portions and procedures that makes sense. The offcard is now about to send a second packet to the card. This second message is still not encrypted. The first message (during **INITIALIZE\_UPDATE**) only proves the card ENC key. The second message (termed as **EXTERNAL\_AUTHENTICATE**) shall prove the offcard's ENC key to the card. In addition, it also carries the offcard's intended security texture. The offcard computes the MAC of the data packet using the `sessionMAC` key and a *chained*  **Initialization Vector** which starts at `0s` but gets updated to a new value, the details of which I shall for now blissfully ignore so as to preserve my sense of humor.&#x20;

&#x20;I repeat, the second message that the offcard send to the card is still not encrypted.&#x20;

The card now receives the second message. The card now parse the components of this second message:&#x20;

* 4 bytes command `84 82 03 00`
* 1 byte length
* 8 bytes cryptogram
* 8 bytes MAC tag

The last 8 bytes MAC tag attached in this message is a calculation of the first 13 bytes. At the time of writing, it is impossible to compute the MAC tag that includes the MAC tag. If you can do it in any given arbitrary data then you must be from the future. So, yes the MAC is distinct separate from the piece of data it refers to.&#x20;

The card performs its own MAC calculation of this 13 bytes and it must match the MAC tag attached in the message. Remember, this MAC calculation uses the `sessionKeyMAC` and a chained Initialization Vector which starts at `0's` and gets updated, the details of which I try to blissfully ignore for now to hold unto my sense of well-being. But we can begin to see here, that the value of the **IV** takes on different succeeding values based on input data and these values at any moment must match both in the card and in the offcard. I think of IV as some sort of cryptographic umbilical cord of the SCP02 session.  Take for example, I made some tinkerings, by calling a method inside the applet that resulted to an update of the IV of the card and this broke the session on the immediate next offcard transmission giving me `69 82` response status. It is easy to dismiss this error and usually we redo the session handshake (ie  `/atr`) to setup secure channel again and consider it a glitz. I did not consider it a glitz and I resolve with all my might to reproduce the conditions until I found the root cause. It was the Initialization Vector getting out-of-sync.

Here is some things to note of. During INITIALIZE\_UPDATE, the card proves its identity/ENC to the offcard.  This proof only proves to the offcard that the card has same ENC key. Take note, a proof is not instantaneously bidirectional. It occurs in discreet stages. First, the offcard knows that the card is legit. But the card still does not know anything about the offcard. Next, during the second message the card now nows that the offcard's ~~ENC~~ MAC is legit. Now the legitimacy of identity is via 3 keys ENC, MAC and DEK. In the EXTERNAL\_AUTHENTICATE, the offcard proves its ~~ENC~~ MAC key to the card. So in EXTERNAL\_AUTHENTICATE, both entities are certain that ~~they share the same ENC key~~ that:

* The offcard is certain that the card has the ENC key
* The card is certain that the offcard has the MAC key

&#x20;~~Furthermore, a successful EXTERNAL\_AUTHENTICATE also proves that both have the same MAC key.~~   Crossing out but retaining this partially incorrect statement because the proof of MAC key is when MAC tagging occurs. The card's response are not tagged if the offcard did not set the RMAC bitfield.&#x20;

Here is the second communication:

```
==> 
84 82 03 00 10 68 1B 22 16 D3 F8 7E 45 6C 34 3F 11 E1 48 DE 0F 
               ^^^^^^^^^^^^^^^^^^^^^^^ ***********************
<== 
90 00 
```

&#x20;Everything is in the clear and nothing is encrypted. I marked the `host_cryptogram` in `^^` caret. I marked the MAC tag in `**` asterisk. At the close of EXTERNAL\_AUTHENTICATE phase, the card simply response with `90 00` ok status code.

**It is curious,** that the card haven\`t proven yet to the offcard that it has the MAC key. Well, there is no need because in this scenario so far the card never attaches a MAC tag in its response data. Why? Because, the offcard chooses the texture of the secure channel and it only sets the two bitfields for MAC and ENC. As a result, every response of the card has no MAC attached to it. Every response of the card is also not encrypted. At this current texture, It is the data from offcard to card that gets encrypted. But the response from card to offcard travels in plain. (The term texture is my own naming convention to mean a particular mode or setting i call it out of spontaneity, texture.)&#x20;

Things to note:

* Possession of ENC key  is used by card to introduce itself
* Possession of MAC key is used by offcard to introduce itself in the case where the second message is not encrypted
* Possession of ENC and MAC key is used by offcard to introduce itself in the case where the second message is encrypted

The chained IV is per session and its next hopping value is influenced by:

* MAC key and generated session\_MAC key
* data

I think of the chained IV as like the Bluetooth FHSS.&#x20;
