New version of PySCard: 2.2.0

I just released a new version of pyscard. PySCard is a python module adding smart cards support (PC/SC) to Python.

The PySCard project is available at:

A big thank to Kurt McKee for all his contributions in this release.

Changes:

2.2.0 (October 2024)

  • patches from Ludovic Rousseau
    • PCSCCardRequest

      • handle KeyboardInterrupt in waitforcard() & waitforcardevent()

      • use a local PC/SC context to avoid locks

    • smartcard.util.padd(): do NOT modify the input parameter

    • CardMonitoring: a timeout exception IS expected

    • Fix pydoctor documentation

    • wx: fix module and examples

    • Minor changes

  • patches from Kurt McKee
    • Remove Python 2 conditional code

    • Eliminate Windows Vista and Windows 7 conditionals

    • Test and improve the synchronization code

    • Test and update the Observer.py code

    • Remove ClassLoader.py

    • Migrate a src/ layout

    • Migrate test/* from unittest to pytest

    • Add missing GSM 03.38 symbols for decoding

    • Support only Python 3.9 and higher

    • Remove the Python 2.x-only Pyro dependency

    • Migrate CI to use the official Coveralls action

    • Standardize local and CI testing to use tox

    • Build wheels in CI for all supported Python versions

    • Build the docs as a part of the test suite

    • Begin to add type annotations to the package

    • Deprecate the HexListToBinString, BinStringToHexList, hl2bs, and bs2hl utility functions

    • Support "64" as an ATR baud rate adjustment integer (ISO 7816-3 2006)

macOS Sequoia and smart cards status

I will compare this version to the previous one, Sonoma, I presented in macOS Sonoma and smart cards status.

/images/2024/10/macOS-Sequoia.jpg

CCID

% grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
        <key>CFBundleShortVersionString</key>
        <string>1.5.1</string>

My CCID driver has not been updated in macOS since Sonoma. It is still version 1.5.1.

The CCID version 1.5.2 was released in January 2023 but that version was not included by Apple in macOS Sonoma. That was a bit surprising when Sonoma was released in 2023. It is now worrying.

The current/latest version is 1.6.1 released in July 2024. I guess Apple provides my CCID driver as a backup only. They do not plan to invest much time and update to the latest version.

Updated CCID driver

If you need a CCID driver more recent than the version 1.5.1 provided by Apple you can contact me.

Apple Open Source

The Open Source components included in macOS are listed at <https://opensource.apple.com/releases/>

The Open Source components of Sequoia 15.0 are already available.

The component SmartcardCCID-55036 points to the GitHub project apple-oss-distributions/SmartcardCCID. The patch for version 55036 released on September 24th, 2024 for Sequoia compared to version 55033 released on September 22th, 2023 for Sonoma is limited to changes in the way the software is patched by Apple. You can see the difference at SmartcardCCID-55036.

I note that this project on GitHub has 2 forks <https://github.com/apple-oss-distributions/SmartcardCCID/forks>:

Apple CCID driver

As with Sonoma, the driver used by default for CCID smart card readers is a driver written by Apple.

See the chapter "Reader name dynamically generated" from macOS Sonoma and smart cards status to know how I know that. It is related to the reader name reported by PC/SC, for example by pcsctest installed by default on macOS.

If I compare the Info.plist of the usbsmartcardreaderd.slotd with the latest macOS Sonoma I get:

% diff -u /Volumes/Sonoma/System/Library/CryptoTokenKit/usbsmartcardreaderd.slotd//Contents/Info.plist /System/Library/CryptoTokenKit/usbsmartcardreaderd.slotd//Contents/Info.plist
--- /Volumes/Macintosh HD/System/Library/CryptoTokenKit/usbsmartcardreaderd.slotd//Contents/Info.plist      2024-09-05 11:17:41
+++ /System/Library/CryptoTokenKit/usbsmartcardreaderd.slotd//Contents/Info.plist   2024-10-01 06:10:49
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
    <key>BuildMachineOSBuild</key>
-   <string>22A380019</string>
+   <string>22A380021</string>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleExecutable</key>
@@ -27,21 +27,21 @@
    <key>DTCompiler</key>
    <string>[com.apple](http://com.apple).compilers.llvm.clang.1_0</string>
    <key>DTPlatformBuild</key>
-   <string></string>
+   <string>24A318</string>
    <key>DTPlatformName</key>
    <string>macosx</string>
    <key>DTPlatformVersion</key>
-   <string>14.7</string>
+   <string>15.0</string>
    <key>DTSDKBuild</key>
-   <string>23G1000s</string>
+   <string>24A318</string>
    <key>DTSDKName</key>
-   <string>macosx14.7.internal</string>
+   <string>macosx15.0.internal</string>
    <key>DTXcode</key>
-   <string>1500</string>
+   <string>1600</string>
    <key>DTXcodeBuild</key>
-   <string>15E6079e</string>
+   <string>16A6170g</string>
    <key>LSMinimumSystemVersion</key>
-   <string>14.7</string>
+   <string>15.0</string>
    <key>NSHumanReadableCopyright</key>
    <string>Copyright © 2020 Apple. All rights reserved.</string>
 </dict>

Not very interesting nor informative.

Known bugs

The page listing the bugs I found in Sonoma is available at macOS Sonoma and smart cards: known bugs.

I have not been notified by Apple that a bug has been fixed in Sequoia. So I guess the bugs are still present.

I discovered a new problem with Apple driver: the error returned by SCardConnect() call is "Card is unresponsive."

    % pcsctest
    MUSCLE PC/SC Lite Test Program
    Testing SCardEstablishContext    : Command successful.
    Testing SCardGetStatusChange
    Please insert a working reader   : Command successful.
    Testing SCardListReaders         : Command successful.
    Reader 01: Gemplus USB SmartCard Reader
    Enter the reader number          : 1
    Waiting for card insertion
                                     : Command successful.
    Testing SCardConnect             : Card is unresponsive.

I get this result even if the card is correctly powered. The reader LED is fixed, indicating the card is powered.

I was able to sometimes get the card ATR. Very strange to have such a simple bug unnoticed by QA.

After enabling my CCID driver (see Enable my CCID driver), of course, the problem is fixed.

Conclusion

If you have a smart card issue on macOS Sequoia, my first suggestion is to switch from the Apple driver to my CCID driver and check again.

New version of PyKCS11: 1.5.17

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

See PyKCS11 introduction or PyKCS11’s documentation.

The project is registered at Pypi: https://pypi.org/project/PyKCS11/

Changes:

1.5.17 - October 2024, Ludovic Rousseau

  • Add AES in counter mode support (CKM_AES_CTR)

  • Add simple derivation mechanisms support (CMK_CONCATENATE_*)

  • Fix reference counting in PyKCS11Lib.load()

  • remove python 2 support from ckbytelist

  • minor improvements

New version of PySCard: 2.1.0

I just released a new version of pyscard. PySCard is a python module adding smart cards support (PC/SC) to Python.

The PySCard project is available at:

Changes:

2.1.0 (September 2024)

  • PCSCCardRequest: fix active polling (was a 0.1 sec loop)

  • Fix use of undefined variable hresult in exceptions

  • Fix print() use in pyscard user’s guide

  • Fix deprecation warnings

  • Minor changes

New version of pcsc-tools: 1.7.2

I just released a new version of pcsc-tools, a suite of tools for PC/SC.

Changes:

1.7.2 - 10 August 2024, Ludovic ROUSSEAU

  • 191 new ATRs

  • provide meson configuration file

  • improve pcsc_scan Windows support

    • Use Ctrl-C also on Windows

    • Windows can also use option -n

    • better output on Windows dumb terminals

  • minor fixes and improvements

Improved SCardGetStatusChange() for "\\?PnP?\Notification" special reader

SCardGetStatusChange() works fine to detect a change in one of the listed readers. It is also possible to detect when a reader has been added or removed using the special reader name "\\?PnP?\Notification". See How to use SCardGetStatusChange()?.

One old problem is:

how to detect that a reader has been added between two calls to SCardGetStatusChange()?

Even if you call SCardGetStatusChange() just after the previous SCardGetStatusChange() returned you may still suffer from a race condition and miss a reader event.

In pcsc-lite version 2.3.0 I implemented a solution for that use case.

SCardGetStatusChange() will now use the high word (high 16-bits) of the .dwEventState field for the special reader "\\?PnP?\Notification" to store the number of reader events (since the start of the pcscd daemon).

Pseudo code algorithm

The suggested way to fix the problem is to use something like that:

  1. initial call to SCardGetStatusChange()

  2. get the initial value from .dwEventState

  3. copy this value in .dwCurrentState

  4. second call to SCardGetStatusChange()

If a reader has been added before the second SCardGetStatusChange() call then SCardGetStatusChange() will return immediately.

Sample code

File sample.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include <winscard.h>

#define CHECK(f, rv, panic) \
 printf(f "(): 0x%08lX, %s\n", rv, pcsc_stringify_error(rv)); \
 if ((SCARD_S_SUCCESS != rv) && panic) \
 { \
  return -1; \
 }

#define PANIC true
#define DONT_PANIC false

#define MAX_READERS 16

int main(void)
{
    LONG rv;
    SCARDCONTEXT hContext;
    LPTSTR mszReaders;
    DWORD dwReaders = 0;
    char *ptr, *readers[MAX_READERS] = {};
    int nb_readers;
    SCARD_READERSTATE rgReaderStates[MAX_READERS];

    rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    CHECK("SCardEstablishContext", rv, PANIC)

    rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
    CHECK("SCardListReaders", rv, DONT_PANIC)

    mszReaders = calloc(dwReaders, sizeof(char));
    rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
    CHECK("SCardListReaders", rv, DONT_PANIC)
    printf("Found readers:\n");
    nb_readers = 0;
    for (ptr=mszReaders; *ptr; ptr += strlen(ptr) +1)
    {
        printf(" %s\n", ptr);
        readers[nb_readers++] = ptr;
    }
    printf("Found %d readers\n", nb_readers);

    /* add the special reader */
    readers[nb_readers++] = "\\\\?PnP?\\Notification";

    /* get the initial states */
    for (int i=0; i<nb_readers; i++)
    {
        rgReaderStates[i].szReader = readers[i];
        rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE;
    }
    rv = SCardGetStatusChange(hContext, 0, rgReaderStates, nb_readers);
    CHECK("SCardGetStatusChange", rv, DONT_PANIC)

    /* set the current state */
    for (int i=0; i<nb_readers; i++)
    {
        rgReaderStates[i].dwCurrentState = rgReaderStates[i].dwEventState;
        printf("reader: %s, events #: %d\n",
            readers[i], rgReaderStates[i].dwEventState >> 16);
        printf("reader: %s, events state 0x%04X\n",
            readers[i], rgReaderStates[i].dwEventState & 0xFFFF);
    }

    /* wait for a change */
    rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, nb_readers);
    CHECK("SCardGetStatusChange", rv, PANIC)

    /* new state */
    for (int i=0; i<nb_readers; i++)
    {
        printf("reader: %s, events #: %d\n",
            readers[i], rgReaderStates[i].dwEventState >> 16);
        printf("reader: %s, events state 0x%04X\n",
            readers[i], rgReaderStates[i].dwEventState & 0xFFFF);
    }

    free(mszReaders);

    rv = SCardReleaseContext(hContext);
    CHECK("SCardReleaseContext", rv, PANIC)

    return 0;
}

File Makefile:

# Linux
PCSC_CFLAGS := $(shell pkg-config --cflags libpcsclite)
LDLIBS := $(shell pkg-config --libs libpcsclite)

CFLAGS = $(PCSC_CFLAGS) -g

sample: sample.c

clean:
    rm -f sample

Connect a reader

We start the sample code with no reader connected:

 SCardEstablishContext(): 0x00000000, Command successful.
 SCardListReaders(): 0x8010002E, Cannot find a smart card reader.
 SCardListReaders(): 0x8010002E, Cannot find a smart card reader.
 Found readers:
 Found 0 readers
 SCardGetStatusChange(): 0x8010000A, Command timeout.
 reader: \\?PnP?\Notification, events #: 33
 reader: \\?PnP?\Notification, events state 0x0000

 >>> connection of a new reader here

 SCardGetStatusChange(): 0x00000000, Command successful.
 reader: \\?PnP?\Notification, events #: 34
 reader: \\?PnP?\Notification, events state 0x0002
 SCardReleaseContext(): 0x00000000, Command successful.

State value 0x0002 is SCARD_STATE_CHANGED.

The first SCardGetStatusChange() returns a reader events of 33. After I connect a reader the number goes to 34.

Disconnect a reader

We restart the sample code with the reader connected:

 SCardEstablishContext(): 0x00000000, Command successful.
 SCardListReaders(): 0x00000000, Command successful.
 SCardListReaders(): 0x00000000, Command successful.
 Found readers:
  Gemalto PC Twin Reader 00 00
 Found 1 readers
 SCardGetStatusChange(): 0x00000000, Command successful.
 reader: Gemalto PC Twin Reader 00 00, events #: 0
 reader: Gemalto PC Twin Reader 00 00, events state 0x0012
 reader: \\?PnP?\Notification, events #: 34
 reader: \\?PnP?\Notification, events state 0x0000

 >>> removal of the reader here

 SCardGetStatusChange(): 0x00000000, Command successful.
 reader: Gemalto PC Twin Reader 00 00, events #: 0
 reader: Gemalto PC Twin Reader 00 00, events state 0x000E
 reader: \\?PnP?\Notification, events #: 35
 reader: \\?PnP?\Notification, events state 0x0002
 SCardReleaseContext(): 0x00000000, Command successful.

The reader "Gemalto PC Twin Reader 00 00" has been removed. Its state value 0x000E contains the bits:

  • SCARD_STATE_UNKNOWN

  • SCARD_STATE_UNAVAILABLE

  • SCARD_STATE_CHANGED

Connect a second reader

We restart the sample code with the reader connected:

 SCardEstablishContext(): 0x00000000, Command successful.
 SCardListReaders(): 0x00000000, Command successful.
 SCardListReaders(): 0x00000000, Command successful.
 Found readers:
  Gemalto PC Twin Reader 00 00
 Found 1 readers
 SCardGetStatusChange(): 0x00000000, Command successful.
 reader: Gemalto PC Twin Reader 00 00, events #: 0
 reader: Gemalto PC Twin Reader 00 00, events state 0x0012
 reader: \\?PnP?\Notification, events #: 36
 reader: \\?PnP?\Notification, events state 0x0000

 >>> connection of a second reader

 SCardGetStatusChange(): 0x00000000, Command successful.
 reader: Gemalto PC Twin Reader 00 00, events #: 0
 reader: Gemalto PC Twin Reader 00 00, events state 0x0010
 reader: \\?PnP?\Notification, events #: 37
 reader: \\?PnP?\Notification, events state 0x0002
 SCardReleaseContext(): 0x00000000, Command successful.

The Gemalto reader event state is 0x0010 = SCARD_STATE_EMPTY because it does not contains a smart card. It does not have the bit SCARD_STATE_CHANGED set because it's state has not changed.

The PnP reader state is 0x0002 = SCARD_STATE_CHANGED because a new reader was connected.

Remarks

Timeout

It is important to use a timeout of 0 (parameter dwTimeout) in the first call to SCardGetStatusChange() to make the function returns immediately.

Unitary Test

If you want to know if your implementation of PC/SC includes the fix or not (or test on Windows or macOS) you can use the program CardGetStatusChange_PnP_Events.py included in pcsc-lite UnitaryTests/SCardGetStatusChange/ directory.

Windows

Microsoft implemented a similar mechanism. But instead of using the number of reader events it uses the number of connected readers.

So between the 2 calls to SCardGetStatusChange() if one reader is added and one reader is removed you may not be notified.

macOS

Apple does not support the special reader "\\?PnP?\Notification". See OS X El Capitan missing feature: SCardGetStatusChange() and "\\?PnP?\Notification".

So there is no way it supports the mechanism presented here.

Backward compatibility

To not break existing codes the new SCardGetStatusChange() beahavior is enabled only if the number of reader events in .dwCurrentState is not zero.

That is also one reason why you should use a dwTimeout value of 0 for the first call.

.dwEventState for normal readers

The high 16-bits of .dwEventState for the normal readers is also used. It contains the number of card events for this particular reader.

This is an old behavior that is documented in the API documentation:

dwEventState also contains a number of events in the upper 16 bits (dwEventState & 0xFFFF0000). This number of events is incremented for each card insertion or removal in the specified reader. This can be used to detect a card removal/insertion between two calls to SCardGetStatusChange()

Conclusion

I was aware of this race issue with SCardGetStatusChange() since a long time (at least 2018. Thanks Maksim). But I got a new motivation boost after an issue was reported SCardGetStatusChange: Race condition when attaching multiple readers at the same time.

It is now the job of applications programmers to use this new feature in their codes.

If you find a regression in your application because of this change please open an issue.

New version of pcsc-lite: 2.3.0

I just released a new version of pcsc-lite 2.3.0.

pcsc-lite is a Free Software implementation of the PC/SC (or WinSCard) API for Unix systems.

Changes:

2.3.0: Ludovic Rousseau

3 August 2024

  • SCardGetStatusChange(): add the number of reader events

  • Add Appstream metainfo announcing HW support

  • meson: specify minimum meson version to use

  • fix formats under musl libc

  • Send libpcsclite.so logs to stderr instead of stdout

  • Some other minor improvements

CCID driver and Multiple Enabled Profiles (MEP)

Some smartphones can handle 2 SIM cards. The smartphones now use eSIM (embedded SIM) instead of rSIM (removable SIM). It is still useful to have 2 subscriber configurations so the same eSIM should support two (or more) USIM applications.

Specification

From:

RSP Technical Specification
Version 3.0
19th October 2022
https://www.gsma.com/esim/resources/sgp-22-v3-0/

Chapter 2.12 Multiple Enabled Profiles, page 77:

This specification defines optional support of Multiple Enabled (MEP), where several Profiles can be in Enabled state. This enables a Device with more than one baseband to use more than one Profile at the same time for providing connectivity to different networks.

The multiplexing of the APDU streams to those Profiles on a single physical interface is specified in ETSI TS 102 221 (Smart Cards; UICC-Terminal interface; Release 17). This specification uses the term "eSIM Port" for what ETSI TS 102 221 calls a logical SE interface (LSI).

[...]

Several options for different features are defined for MEP:

  • APDU multiplexing can use any of the mechanisms defined in ETSI TS 102 221 [6], e.g.:

    • eSIM Port selection via the APDU MANAGE LSI (select LSI) when the transmission protocol T=0 or T=1 is used.

    • eSIM Port selection via the NAD byte when the transmission protocol T=1 is used.

Implementation

Reda ZAITI, from Thales, implemented the second mechanism: eSIM Port selection via the NAD byte. The original patch is simple: Add possibility to set/get NAD on T=1 for MEP.

This feature can be used to test eSIM chips using a standard smart card reader. The CCID driver must manage the T=1 protocol so only TPDU readers can be used.

The PC/SC workgroup does not define anything regarding MEP. So it was implemented using SCardControl() and the control code SCARD_CTL_CODE(3600).

Sample code

A sample code GetSetNAD.py is provided:

#! /usr/bin/env python3

"""
#   GetSetNAD.py: get/set NAD value
#   Copyright (C) 2022  Ludovic Rousseau
"""

#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, see <http://www.gnu.org/licenses/>.

from smartcard.System import readers
from smartcard.pcsc.PCSCPart10 import SCARD_LEAVE_CARD, SCARD_CTL_CODE
from smartcard import Exceptions
from smartcard.util import toHexString


def get_nad(cardConnection):
    print("Get NAD")

    get_NAD = [0x3F, 0, 0]
    print(" command:", toHexString(get_NAD))
    res = cardConnection.control(SCARD_CTL_CODE(3600), get_NAD)
    print("  result:", toHexString(res))
    status = res[3]
    if status == 0:
        print("Success")
        nad = res[4]
        print("NAD:", nad)
    else:
        print("Failed!")


def set_nad(cardConnection, nad):
    print("Set NAD")

    set_NAD = [0x3E, 0, 1, nad]
    print(" command:", toHexString(set_NAD))
    res = cardConnection.control(SCARD_CTL_CODE(3600), set_NAD)
    print("  result:", toHexString(res))
    status = res[3]
    if status == 0:
        print("Success")
    else:
        print("Failed!")


if __name__ == "__main__":
    import sys

    reader_idx = 0
    if len(sys.argv) > 1:
        reader_idx = int(sys.argv[1])

    reader = readers()[reader_idx]
    print("Reader:", reader)

    cardConnection = reader.createConnection()
    cardConnection.connect(disposition=SCARD_LEAVE_CARD)

    get_nad(cardConnection)
    set_nad(cardConnection, 42)
    get_nad(cardConnection)

Output

 ./GetSetNAD.py 1
Reader: Gemalto PC Twin Reader 01 00
Get NAD
 command: 3F 00 00
  result: 3F 00 02 00 00
Success
NAD: 0
Set NAD
 command: 3E 00 01 2A
  result: 3E 00 01 00
Success
Get NAD
 command: 3F 00 00
  result: 3F 00 02 00 2A
Success
NAD: 42

Here the NAD is changed from the default value 0 to 42.

To enable the feature in the CCID driver you need to define ENABLE_MULTIPLE_ENABLED_PROFILES in the source code and rebuild + reinstall the driver.

It is NOT enabled by default because:

  • very few people will need it

  • it is too easy to create a Denial Of Service using the SCardControl() code and update the NAD value

Example of denial of service

Just after running the GetSetNAD.py program you can try to send an APDU to the smart card:

$ echo "00 00 00 00" | scriptor -r "Gemalto PC Twin Reader 01 00"
Using given card reader: Gemalto PC Twin Reader 01 00
Using T=1 protocol
Reading commands from STDIN
> 00 00 00 00
Can't get info: Transaction failed.

From pcscd logs you get:

00000004 [140363545183936] APDU: 00 00 00 00
00000005 [140363545183936] ../src/ifdhandler.c:1360:IFDHTransmitToICC() usb:08e6/3437:libudev:0:/dev/bus/usb/001/008 (lun: 10000)
00000004 [140363545183936] ../src/commands.c:2289:CmdXfrBlockTPDU_T1() T=1: 4 and 65548 bytes
00000004 [140363545183936] ../src/openct/proto-t1.c:599:t1_build() more bit: 0
00000005 [140363545183936] sending: 2A 40 04 00 00 00 00 6E
00000006 [140363545183936] -> 000001 6F 08 00 00 00 00 20 00 00 00 2A 40 04 00 00 00 00 6E
00002295 [140363545183936] <- 000001 80 04 00 00 00 00 20 00 00 00 00 92 00 92
00000016 [140363545183936] received: 00 92 00 92
00000004 [140363545183936] ../src/openct/proto-t1.c:242:t1_transceive() R-BLOCK required
00000004 [140363545183936] sending: 2A 92 00 B8
00000005 [140363545183936] -> 000001 6F 04 00 00 00 00 21 00 00 00 2A 92 00 B8
00002016 [140363545183936] <- 000001 80 04 00 00 00 00 21 00 00 00 00 92 00 92
00000012 [140363545183936] received: 00 92 00 92
00000004 [140363545183936] ../src/openct/proto-t1.c:242:t1_transceive() R-BLOCK required
00000003 [140363545183936] ../src/openct/proto-t1.c:250:t1_transceive() Rule 7.2
00000002 [140363545183936] sending: 2A 92 00 B8
00000005 [140363545183936] -> 000001 6F 04 00 00 00 00 22 00 00 00 2A 92 00 B8
01555310 [140363545183936] <- 000001 80 00 00 00 00 00 22 40 FE 00
00000020 [140363545183936] ../src/commands.c:1564:CCID_Receive Card absent or mute
00000006 [140363545183936] ../src/openct/proto-t1.c:234:t1_transceive() fatal: transmit/receive failed
00000004 [140363545183936] SW:
00000004 [140363545183936] ../src/ifdwrapper.c:543:IFDTransmit() Card not transacted: 612
00000003 [140363545183936] ../src/winscard.c:1622:SCardTransmit() Card not transacted: rv=SCARD_E_NOT_TRANSACTED
00000003 [140363545183936] ../src/winscard.c:1650:SCardTransmit() UnrefReader() count was: 2
00000005 [140363545183936] ../src/winscard_svc.c:719:ContextThread() TRANSMIT for client 15, rv=SCARD_E_NOT_TRANSACTED

You can see the NAD (node address byte) value (42 or 0x2A) in the first byte of the T=1 block sent by the driver to the reader. My smart card does not like this NAD value (it is not an eSIM with MEP support) and requests an R-Block before becoming mute.

Conclusion

Very few people will use this feature. I guess only developers of eSIM and testers/evaluators of eSIM will need this.

My driver is Free Software and was modified to add the feature. This is the beauty of Free Software.