Шина данных в смарт картах

Смарт-карты. Часть 1. Принципы работы

Все мы пользуемся разными видами смарт-карт в повседневной жизни. Наиболее яркими примерами смарт-карт являются: SIM-карты, кредитные карты, электронные документы и т.д.

По сути, смарт-карта — это оптимизированный для криптографии микроконтроллер с повышенным уровнем безопасности. Что это означает? В отличие от стандартного микроконтроллера доступ к памяти смарт-карты строго контролируется процессором. Таким образом, чтение данных с карты их написание на ней регулируются ПО самой карты. Более того, производители чипов предпринимают меры по предотвращению несанкционированного доступа (копирования всей памяти, перепрограммирования) к карте на электронном и физическом уровне.

Применение смарт-карты

Смарт-карта используется в тех случаях, когда необходимо удостоверить подлинность ее обладателя. Примером тому служит SIM-карта. Ее главной ролью является доказать оператору, что телефон, подключившийся к сети, принадлежит конкретному абоненту. После подобной проверки оператор сможет направлять коммуникацию с номера и на номер абонента именно тому телефону, а также регистрировать платежный баланс абонента.

Работа смарт-карты

Карты не работают автономно, а только в связке с так называемым терминалом (телефон, банкомат, иной проводной или беспроводной электронный читатель). Читатель обеспечивает карту электричеством и посылает команды. Карта никогда не инициирует коммуникацию, а всегда обязательно отвечает на любые посланные ей терминалом команды. В случае отсутствия ответа карта будет считаться «MUTED», т.е. не работающей. В подобной ситуации терминал либо никак не реагирует на ошибку, либо пытается восстановить общение с картой после осуществления RESET.

На логическом уровне коммуникация между терминалом и картой происходит в формате APDU, описанном стандартом ISO7816-4. Что касается физического уровня, то выше упомянутое общение регулируется не каким-то одним определенным стандартом, а их множеством. К примеру, существуют стандарты для контактного (ISO7816-3 T=0 и T=1, USB и т.д.) и бесконтактного (ISO14443, NFC/SWP) общения.

Карты Native и Javacard

Некоторые смарт-карты выходят в производство с уже заранее установленными на них и не подлежащими изменению, дополнению, либо удалению одной или более программами, предназначенными для исполнения конкретных функций (SIM и USIM, EMV и т.д.). Подобные карты, носящие название Native, являются привлекательными благодаря их низкой цене (при оптовых закупках) и относительной простоте используемого для их программирования кода, что уменьшает вероятность проблем с безопасностью карты. Однако наиболее интересными, на мой взгляд, картами являются карты на основе JavaCard и Global Platform, в которых ОС карты — это платформа, на которой можно установить различные приложения. Приложения, написанные для JavaCard, с использованием стандартных API, можно будет загрузить на все карты, поддерживающие совместимую версию платформы, вне зависимости от производителя карты. Что касается Global Platform, то это набор спецификаций, регулирующий безопасную администрацию карты, в том числе установку, блокировку либо удаление тех или иных приложений, а также управление жизненным циклом (Life Cycle) карты.

Маленькое примечание по поводу администрации карты. Пользователь карты, как правило, не является владельцем и администратором карты. К примеру, администратором SIM-Карты является оператор мобильной связи, а не абонент. Только оператор имеет право устанавливать или удалять приложения на/с карты. Тем не менее, существует также возможность приобрести «пустые» карты для собственной разработки приложений.

Таким образом, в данной части своей статьи я коснулся базиса работы смарт-карты, как на внешнем, так и на внутреннем уровне, а также дал краткое определение понятия смарт-карты. Следующие части статьи я хотел бы посвятить:

Источник

STM32. Подключаем смарт-карты стандарта ISO7816

Сразу оговорюсь, что речь идет о процессоре с аппаратной поддержкой ISO7816 (например, STM32F4xx), написание программного эмулятора — это то еще маньячество, которое имеет место либо если очень сильно «прижало», либо если слишком много свободного времени.

ВЫВОДЫ И СХЕМА ВКЛЮЧЕНИЯ

Так подключают карточки настоящие хацкеры:

b6533dc2d5df462b87e7cef3ce3ee9e4

ИНТЕРФЕЙС

Интерфейс является синхронным режимом USART-драйвера, это значит, что передачу каждого бита информации мы синхронизируем частотой на выводе CLK, но здесь есть одно важное отличие от прочих синхронных интерфейсов (вроде того же SPI): для тактирования одного бита информации нужен не один импульс на CLK, а 372 импульса (это магическое число прописано в 3 части ISO7816, и носит название ETU (Elementary Time Unit)), т.е., один бит данных тактируется каждым 372-м (в идеальном случае) фронтом. Сама частота должна лежать в пределах от 1 до 5 МГц.

Теперь разберемся с линией данных (I/O). Как я уже сказал, это обычный UART со следующими параметрами:

НАСТРОЙКА ДРАЙВЕРА

Здесь сразу кину кусок кода инициализации, написанный на Standard Peripheral Library:

Настройку выводов я опустил, чтобы не загромождать кодом, но здесь есть один важный момент, вывод I/O должен быть настроен как Open-Drain, поскольку стандартом предусмотрена возможность нахождения линии в Z-состоянии, когда карточка сама решает, куда ее подтягивать.

Здесь я хотел бы заострить внимание на двух моментах (предделитель и скорость обмена). Дело здесь в чем? С одной стороны нужно задать скорость 9600, а с другой — частоту, кратную системной.

Пожалуй, в большинстве случаев, если не требуется сверхнизкое потребление, системная частота выбирается максимальной (в моем случае это 168 МГц), модуль USART, который я использую, тактируется от шины APB2, максимальная частота которой составляет 84 МГц, значит выбранная нами частота должна попадать в интервал от 1 до 5 МГц и быть кратной 84 МГц, но для скорости 9600 частота будет 9600 * 372 = 3,5712 МГц. Как же тут быть? Разработчики стандарта этот момент предусмотрели и заложили возможное отклонение от номинальных значений вплоть до 20%, т.о., мы можем спокойно округлить частоту, допустим, до 3,5 МГц и выбрать скорость 3500000 / 372 = 9409, расхождение здесь составит менее 2%, что вполне допустимо. Значение предделителя мы должны поделить на 2, поскольку оно задается с шагом 2 (т.е. значение 1 соответствует делению на 2, 2 — на 4, 3 — на 6, и т.д.). У нас получается (84 / 3,5) / 2 = 12:

С настройкой драйвера, я думаю, все понятно, посему перейдем к процессу инициализации обмена с карточкой.

СТАРТ

Чтобы запустить карточку нужно выполнить «холодный» сброс. Он представляет собой следующую последовательность:

156d0b134afc476aa63162536a51a036

Все просто, выполняем сброс, ждем отклика. Если первый бит отклика не пришел в течение 40000 циклов (t3), необходимо выставить на RST низкий уровень и деактивировать I/O и CLK.

Что представляет собой этот отклик? ATR (Answer-to-Reset) представляет собой следующую структуру (размер каждого поля составляет 1 байт):

9. TCKбайт контрольной суммы. Вычисляется сложением по модулю 2 (xor) всех предшествующих байт (присутствует только в протоколе T1)

Обмен в режиме «переговоров» представляет собой процесс, называемый PTS (Protocol Type Selection). Процесс этот состоит в отправке устройством сопряжения последовательности, которая говорит карте о том, что оно готово применить новые настройки. В свою очередь, карта должна ответить той же последовательностью, после чего и карта и устройство сопряжения могут начинать работать с новыми настройками. О том, какие настройки применить, нам говорит байт TA1 кадра ATR. Параметры Fi и Di это не сами значения, а номера в таблице. По таблице мы можем найти соответствующие этим номерам значения F (Clock rate conversion factor) и D (Bit rate adjustment factor):

Читайте также:  Форд мондео 1998 замена прокладки гбц

Таблица Fi-F.

FI 0000 0001 0010 0011 0100 0101 0110 0111
F internal clk 372 558 744 1116 1488 1860 RFU
FI 1000 1001 1010 1011 1100 1101 1110 1111
F RFU 512 768 1024 1536 2048 RFU RFU

Таблица Di-D.

DI 0000 0001 0010 0011 0100 0101 0110 0111
D RFU 1 2 4 8 16 RFU RFU
DI 1000 1001 1010 1011 1100 1101 1110 1111
D RFU RFU 1/2 1/4 1/8 1/16 1/32 1/64

*RFU — зарезервировано для будущего использования

Частное от деления F и D — это новое значение ETU, т.е. мы сможем выбрать любую частоту и скорость, но принимая во внимание, что соотношение между ними должно быть равно частному F / D.

Теперь подробнее о самом кадре PTS:

Все просто, формируем последовательность, отправляем, ждем ответа, сравниваем, если совпало, перестраиваем скорость на Fclk / (F / D).

Если карточка не поддерживает режим «переговоров», просто продолжаем работу.

ПРИМЕР

Для закрепления материала попробуем разобрать простенький пример. Это обычная Билайновская симка. Вот ATR, который она выкидывает:

Кадр PTS, в этом случае, будет выглядеть следующим образом:

ЗАКЛЮЧЕНИЕ

В своей статье я опустил некоторые подробности, связанные, например, программированием смарт-карт, а также не стал рассматривать протоколы канального и прикладного уровней, но на это есть несколько причин. Во-первых, каждый из этих пунктов тянет на отдельную статью, если не больше, а во-вторых, информации по протоколу APDU в интернете, на мой взгляд, предостаточно.

Ну что, я очень надеюсь, что мой труд не останется без внимания, или, по крайней мере, удовлетворит любопытство страждущих. Так или иначе, спасибо всем, кто осилил, буду рад ответить на вопросы, да и получить пару другую пинков за косяки. Напоследок очень советую всем прочитать замечательный цикл статей о криптографических Java-картах. Всем добра!

Источник

Смарт-карты. Часть 2. APDU

После общей информации, описанной в первой части, сегодня поговорим об APDU в формате, описанном в стандарте ISO7816-4.

APDU (application protocol data unit) — это формат общения карты и терминала. Терминал посылает Command APDU (C-APDU), а карта отвечает с Response APDU (R-APDU).

C-APDU

Формат C-APDU таков:

Header Body
CLA INS P1 P2 [Lc field] [Data field] [Le field]

Каждый элемент заголовка (header) сохранен на одном байте и является обязательным. К заголовку вернемся чуть позже, сейчас поговорим о body команды.

Элементы body следующие:

Lc и Le, если присутствуют, могут занимать 1 (Short Length) или 3 байта (Extended Length) каждый. При Short Length кодируются значения от 1 до 256. Длина данных на 256 байтов записывается как «00». При Extended Length кодируются значения от 1 до 65536. Первый байт всегда «00» и остальные 2 байта — номер в формате Big Endian. Когда Lc или Le — «00 00 00», то длина данных — 65536 байтов.

В зависимости от присутствия или отсутствия элементы body команды можно разделить на 4 категории:

Элемент Значение
CLA Class байт. Содержит метаданные команды (логический канал, Secure Messaging и т.д.).
INS Instruction байт. Код инструкции. Это шестнадцатеричное число, старший ниббл которого не может быть 6 или 9. При этом младший ниббл всегда является четным числом.
P1 Первый параметр команды. Если он не нужен, то его значение «00».
P2 Второй параметр команды. Если он не нужен, то его значение также «00».

Так как серия моих статей нацелена на рассмотрение в подробностях Global Platform, то значение CLA я буду описывать в контексте Global Platform.

b5 в стандарте ISO7816-4 обозначает Command Chaining. В Global Platform не используется.

R-APDU

Формат R-APDU таков:

Body Trailer
[Data field] SW1 SW2

Body присутствует при успешном исполнении (с замечаниями или без них) команд из категории Case 2 и Case 4. Его содержание зависит от конкретной команды. Trailer есть всегда и содержит так называемый Status Word, то есть код результата, положительного или отрицательного. Статус может быть одним из следующих:

SW1SW2 Значение
Успешное исполнение
9000 ОК.
61ХХ ОК, но есть еще ХХ байтов данных.
Исполнение завершилось с замечаниями
62ХХ SW2 уточняет причины замечания. Постоянная память не была изменена.
63ХХ SW2 уточняет причины замечания. Постоянная память была изменена.
Ошибки при исполнении команды
6400 Команда не была исполнена. Постоянная память не была изменена.
65ХХ Команда не была исполнена. Постоянная была изменена.
66ХХ Команда не была исполнена по причинам безопасности.
Ошибки, связанные с форматом команды
6700 Неправильная длина команды.
6881 Карта не поддерживает указанный логический канал.
6882 Карта не поддерживает указанный вид Secure Messaging.
69XX Команда не разрешена.
6AХХ Неправильные параметры команды.
6B00 Неправильные параметры команды.
6CXX Неправильный Le.
6D00 Неизвестный INS.
6E00 Неизвестный CLA.
6F00 Ошибка без описания.

Ошибки из серии 69ХХ и 6АХХ часто используются в Global Platform и будут описаны в подробностях в частях статьи, посвященных Global Platform.

Статусы из серии 61ХХ и 6CXX требуют особенного внимания. Код 61ХХ возможен, когда карта исполнила команду из категории Case 2 или Case 4 и послала неполный ответ. В этом случае, SW2 кодирует длину остатка ответа («00» = 256). В ответ терминал может отправить команду GET RESPONSE для того, чтобы получить оставшиеся данные. Эта процедура может повторяться несколько раз, до тех пор, пока карта не отправит полный ответ. Настоящий Status Word — это статус, содержащийся в последнем ответе на команду GET RESPONSE. Подобная ситуация встречается преимущественно, когда APDU передается через протокол ISO7816-3 T=0 ввиду особенности передачи команд из категории Case 4 (об этом поговорим чуть позже). Код 6CXX встречается, когда указанный Le не соответствует действительной длине ответа. Стоит отметить, что при этом карта не посылает никаких данных в R-APDU, а требует, чтобы терминал повторил команду с Le равным числу, закодированному в SW2.

Особенности передачи команд в категории Case 4 через протокол Т=0

Протокол T=0 очень распространен, так как он используется в SIMках. Его особенность заключается в том, что header всегда состоит из 5 байтов: CLA, INS, P1, P2, P3. P3 может быть использован для кодировки Lc либо Le. Получается, что он, будет лишним для команд Case 1, подходит для команд Case 2 и Case 3, но недостаточен для команд Case 4, где нужны как Lc, так и Le. Как можно решить эту проблему?

Следующим образом. Команды Case 4 передаются с P3=Lc, как будто это команда Case 3. Тогда карта, при успешном исполнении команды, отвечает без данных, но со статусом 61ХХ. В свою очередь терминал посылает команду GET RESPONSE (из категории Case 2), а затем карта посылает настоящий ответ.

GET RESPONSE

Элемент Значение
CLA как предыдущая команда, но без Secure Messaging и бит8 = 0 (хотя карты принимают и бит8 = 1)
INS C0
P1 00
P2 00
Lc
Data
Le XX (обычно SW2 предыдущего ответа)
Читайте также:  Съемник для шаровых опор уаз

Примеры общения с картой

Наконец-то, мы подошли к самой интересной части статьи — примеры.

GET DATA (Card Production Life Cycle)

C-APDU => 80 CA 9F 7F 00
R-APDU 80 CA 9F 7F 2D
R-APDU 80 F2 40 00 08 4F 06 31 32 33 34 35 36 09
R-APDU 80 F2 40 00 08 4F 06 31 32 33 34 35 36
R-APDU => 61 09
C-APDU => 00 C0 00 00 09
R-APDU

Источник

Смарт-карты для самых маленьких

fc3d13176ac41844094c50b4b418b801Поскольку статья вводная и обзорная, то рассматриваться будет простейшая разновидность смарт-карт — SIM-карты, полагаю, что таких карт на планете сейчас больше всего.
По сегодняшним меркам стандарт SIM выглядит архаично, но зато он идеален для первого знакомства с миром смарт-карт, усвоение принципов, которые заложены в основу этого стандарта, облегчит дальнейшее погружение в тему.
Если Вы «карточник», то вряд ли узнаете для себя что-то новое, разве что какие-нибудь не очень понятные моменты разложатся по полочкам, а может быть Вы разложете по полочкам то, что недопонял автор (но, напоминаю, держимся в рамках SIM!).

Смарт-карта является программно-аппаратным комплексом, по сути — миниатюрным компьютером, в состав которого входят, как минимум:

Часто, но не всегда, в состав карты входит и Java VM. ОС, как таковая, конечному пользователю не видна.

A0 A4 00 00 02 3F00

Для того, чтобы воспользоваться «услугами» этой инструкции, нужно иметь в виду, что она должна быть вызвана сразу после той команды, результат которой требуется запросить. При вызове любой инструкции, отличной от GET RESPONSE, контекст предыдущей команды будет утрачен.
Если какая-либо инструкция позволяет использовать после своего вызова GET RESPONSE, то она в SW2 возвращает объем данных в байтах, который вернет команда GET RESPONSE.
Одним из ярких применений GET RESPONSE является ее использование после команды SELECT — оно дает возможность получить полезную информацию о выбранном объекте файловой системы.

Подсистема хранения данных

Типы файлов

API смарт-карт предусматривает манипуляции с тремя типами файлов:

Файл, состоящий из фиксированного количества записей, причем все записи одинаковой длины, длина записи задается при создании файла.
Записей не может быть больше 255 шт., каждая запись не может быть длинее 255 байт.
Средство работы — пара READ RECORD/UPDATE RECORD.
Можно использовать как абсолютную (по номеру записи) так и относительную адресацию (следующая/предыдущая, но без цикличности).
Пример использования — записная книжка на SIM-карте.

В целом — то же, что и Linear Fixed, но со следующей дополнительной функциональностью:
При чтении: замкнутость — при использовании относительной адресации, переходя с последней на следующую запись попадаем на первую, переходя с первой на предыдущую запись, попадаем на последнюю.
При записи: допустима только относительная адресация с обращением только к предыдущей записи. Есть даже специальная команда, только для циклических файлов, которая обновляет самую старую запись файла (после этого она становится самой новой) — INCREASE.
Первая запись всегда хранит самые новые данные, а последняя — самые старые.
Пример использования — список ранее набранных номеров. Вообще, файлы данного типа используются гораздо реже, чем файлы других типов.

Разграничение доступа

Конечно же, то, что я здесь описал, не является реальной файловой системой — как правило, за этой абстракцией, на уровне ОС, спрятана знакомая всем FAT.

В завершение я просто обязан привести пример использования данного API в реальной жизни.
Думаю, многие уже догадались (или знали?), что самым известным и массовым устройством, использующим этот API постоянно и интенсивно, является обыкновенный мобильный терминал.

PS:
В следующей статье планирую рассказать о том, как можно применить полученные сейчас знания, работая с картой программно.

Источник

SmartCard I2C Protocol. Обмен APDU командами через I2C интерфейс

Введение

Некоторое время назад я принимал участие в разработке устройства, в котором было необходимо реализовать российскую криптографию. Так как в дальнейшем предполагалось это решение сертифицировать, то к реализации криптографии выдвигались определенные требования. И как один из вариантов упрощения реализации этих требований, рассматривалась возможность встроить в устройство считыватель смарткарт или установить смарткарточный чип, в котором уже были реализованы многие необходимые сценарии работы с ключевой информацией.

К сожалению, тогда подобное решение не подошло по некоторым причинам, хотя если бы удалось использовать уже готовую российскую аппаратную криптографию, то это должно было значительно ускорить разработку и последующую сертификацию конечного изделия. А причины невозможности использования USB токенов или смарткарты были весьма банальны: устройство должно было быть довольно компактным (небольшой модуль для M2M или IoT устройств), эксплуатироваться преимущественно в необслуживаемом режиме и работать в широком температурном диапазоне.

В этой статье я хочу рассказать о возможном решении подобного кейса с использованием чипа A7001, который подключается к системе через I2C интерфейс.

Проблемы реализации криптографии в ПАК

Мне не хочется подробно останавливаться на проблемах сертификации криптографии. Кто с этим работает, тот и так в курсе, а остальным это вроде как и не нужно. Но про несколько важных моментов сказать все-таки стоит.

В теории особых проблем с криптографией быть не должно. Ведь достаточно взять одну из криптографических библиотек, например, OpenSSL, или любую другую из множества существующих.

Проблемы начинаются, когда это решение требуется сертифицировать. И чисто программная реализация криптографии в прошивке превращает устройство в полноценный СКЗИ, требующий пристального изучения в испытательной лаборатории. Ведь разрабатывая решение с использованием криптографии, рано или поздно придется задумываться над такими вещами как ключевая схема, хранение ключей, генерация случайных чисел и прочие тонкие материи.

Существует элегантный метод реализации сертифицированных российских криптографических алгоритмов для некоторых решений, который позволяет немного упростить процесс создания конечных устройств и сократить сроки их разработки и последующей сертификации. Достаточно встроить в устройство смарт-карту или смарт-карточный чип, используя его как некий «корень доверия», и таким образом, решить существенное количество болезненных вопросов, требующих длительных исследований и подтверждения в испытательных лабораториях.

e2iq6i49c7ber2rkbgu6sv8fl3u

Смарткарточный микроконтроллер с I2C интерфейсом

Для написания данной статьи я использовал чип A7001, который подключается к конечному устройству по шине I2C, имеющейся практически в любом устройстве. Чип был предоставлен компанией Аладдин РД, в который уже установлена прошивка с поддержкой российской криптографии.

Микроконтроллер A7001AG (Secure authentication microcontroller) выпускается компанией NXP. Согласно datasheet`у на микросхему, A7001AG — это защищенный от несанкционированного доступа микроконтроллер на базе классической архитектуры 80C51 с криптографическим сопроцессором.

В режиме энергосбережения микроконтроллер потребляет 50 μA. Поддерживает напряжение питания в диапазоне от 1.62В до 5.5В и может эксплуатироваться при температурах от −25°C до +85°C.

Для взаимодействия с внешними устройствами используется интерфейс I2C slave со скоростью работы до 100 kbit/s.

Микроконтроллер выпускается в нескольких вариантах корпусов. У меня оказался в формате HVQFN32. Это пластиковый корпус размерами 5х5х0,85 мм с 32 контактами и шагом вывод 0,5 мм.

Внешний вид корпуса:

trbo5rlj2 q0v

Хост система для подключение чипа A7001

В качестве макета хост системы с интерфейсом I2C была взята плата ESP32 WiFi Kit 32 компании Heltec. Она стоит менее 1000 рублей, имеет все необходимые проводные и беспроводные интерфейсы, есть разъем для подключения литиевого аккумулятора со схемой зарядки, а так же OLED дисплей 0,96 дюйма.

Читайте также:  Трещит стартер в чем проблема

ufkqlihfpi9w0692rq8junv0ybo

Практически идеальная система для прототипирования различных IoT- и M2M-устройств, с которой я давно хотел поиграться.

Плату можно программировать как в родной среде разработки, так и в IDE Arduino. Примеров для работы с ней можно найти множество. Для простоты я остановился на стандартной для Arduino IDE.

Принципиальная схема

Принципиальная схема подключения чипа A7001 приведена на рисунке. Она немного отличается от рекомендованной в datasheet’е. По описанию производителя на выводе 22 (сигнал сброса RST_N) должен присутствовать высокий потенциал, но по такой схеме микросхема не завелась. В результате «научного тыка» работоспособность была достигнута подключением резистора подтяжки R4 к отрицательному проводнику питания.

UPDATE: Как подсказали в комментариях, схема соответствует даташиту, тогда как меня смутило описание вывода

udl3nd7nz2ck8gtwkb3dhdudzqy

Схема собрана на небольшой макетной плате. Питание и сигналы I2C подключены четырьмя соединительными проводами, а сам модуль ESP32 подключается к компьютеру через USB для получения питания всей схемы и заливки прошивки.

dexzw1kvlnoixvk0ko 9svuvkbg

Smart Card I2C Protocol

Когда я первый раз услышал про подключение смарт-карточных микроконтроллеров по шине I2C, мне объяснили, что физический уровень смарт-карточного интерфейса (ГОСТ Р ИСО/МЭК 7816-3-2013) заменен на I2C (SMBus), а все остальное работает как обычные смарт-карты по стандарту ГОСТ Р ИСО/МЭК 7816-4-2013 с использованием APDU команд.

Оказалось, все не совсем так, а точнее совсем не так. Взаимодействие с микроконтроллером на высоком уровне действительно идет с использованием обычных APDU команд, но не обошлось без некоторых «но».

Программная часть

Поиск библиотеки с реализацией протокола Smart Card I2C Protocol результатов не принесли. Поэтому пришлось разбираться в спецификации и делать реализацию основных функций из того, что было под рукой.

Для работы с портом I2C я использовал стандартную библиотеку Wire. Сразу скажу, что данная библиотека не подходит для полноценной реализации протокола Smart Card I2C Protocol, т.к. не позволяет управлять ACK и NACK при передаче и чтении отдельных байтов, что требуется для реализации корректного приема данных переменной длинны от смарт-карты.

Да и обычные примеры кода Wire заработали не с первого раза, но после некоторой пляски с бубном клавиатурой, нескольких литров кофе, гугления в яндексе и яндексения в гугле решение было найдено.

Судя по документации на библиотеку, такая конструкция не отпускает шину I2C после вызова endTransmission. Но оказалось, что у используемого мной модуля на базе ESP32 передача данных физически происходит не во время вызова endTransmission(false), как написано в документации на библиотеку Wire, а во время вызова requestFrom(true), тогда как перед этим данные только ставятся в очередь на передачу.

При наличии подобных ограничений, пришлось делать некоторые «костыли», но мне очень хотелось запустить чип A7001 без переписывания стандартных библиотек. Из-за этого осталось не реализована обработка ошибок протокола, а также не удалось сделать прием данных переменной длины (т.е. всегда требуется указывать точное количество байт для чтения).

Подобные ограничения не допустимы в реальной системе, но не существенны для демонстрации использования APDU команд при работе по шине I2C. Поэтому, если при обмене данных через I2C порт возникает ошибка протокола обмена, тогда тумблер питания – наше все.
Другими словами, если во время повторения этих экспериментов все работало и вдруг перестало, прежде чем искать ошибку в коде, выключите и включите питание. С большой долей вероятности это может устранить возникшую проблему.

Примеры кода для работы с чипом A7001

В примерах я использую несколько вспомогательных функций:

vect_dump — вывести в отладочных порт дамп данных в HEX формате;
sci2c_exchange — передать по I2C массив данных и считать заданное количество ответных байт;
sci2c_status — считать статус ответа микросхемы и при необходимости вывести в отладочный порт её состояние;
sci2c_apdu_send — послать APDU команду;
sci2c_apdu_recv — прочитать ответ на APDU команду.

Инициализация микросхемы

Согласно описанию Smart Card I2C Protocol, перед началом работы с чипом следует выполнить последовательно три команды: Перезагрузка (Cold или Soft Reset), Чтение ATR (Read Answer to Reset) и Настройка параметров обмена (Master Device exchanges Parameter). И только после этого микросхема готова принимать APDU команды.

Soft Reset

Тут все просто, посылаем команду перезагрузки и ждем положенное время:

Read Answer to Reset

С чтением ATR немного сложнее, т.к. нужно не только послать команду, но и считывать ответные данные. Согласно описанию протокола, максимальный размер возвращаемых данных CDBATS,MAX(Command Data Bytes, Answer To Reset, MAXimum) может быть 29 байт.

Считанные данные ATR: 1E 00 00 00 B8 03 11 01 05 B9 02 01 01 BA 01 01 BB 0D 41 37 30 30 31 43 47 20 32 34 32 52 31

Где 1E — размер возвращаемых данных (29 байт + 1 байт PCB) и 00 — PCB (Protocol Control Byte), который должен быть равен 0 и, судя по всему, в данном примере данные считались не совсем корректно (должен быть один байт PCB, а тут их три).

Далее идут данные, закодированные в TLV формате:

B8hLow level data object, размер 3 байта (11h 01h 05h);
B9hProtocol binding data object, размером 2 байта (01h 01h);
BAhHigher layer data object, размером 1 байт (01h);
BBhOperating system data object, 13 байт (41 37 30 30 31 43 47 20 32 34 32 52 31).

Расшифровка считанной конфигурации микросхемы
Low level data object: 11h — старшая и младшая версии поддерживаемого протокола.

Error Detection Codes: 01h — поддержка обнаружения ошибок и контроля целостности передаваемых данных с помощью LRC (Longitudinal Redundancy Code).

Frame waiting integer (FWI): 05h — максимальная задержка между двумя командами. Диапазон значений может быть от от 10 мс до 5120мс, по умолчанию 5120мс. Значение вычисляется по формуле T = 10ms x 2^FWI. Что в данном случае дает нам задержку 320 мс (10мс x 2^5).

Protocol binding data object — состоит из двух значений, 01h 01h, которые кодируют поддерживаемый протокол и протокол по умолчанию. Данные значения означают поддержку протокола APDU [ГОСТ Р ИСО/МЭК 7816-3-2013], и, как не трудно догадаться, этот же протокол установлен по умолчанию.

Higher layer data object — число 01h означает поддержку короткого и расширенного формата APDU.

Operating system data object — это идентификатор размером до 15 байт, как определено в стандарте [ГОСТ Р ИСО/МЭК 7816-4-2013]. В нашем случае это строка «A7001CG 242R1».

Master Device exchanges Parameter

Последней командой для инициализации настройка параметров обмена:

Возвращенное значение: CCh — (11001100b) согласно datasheet’у, 4 и 5 биты должны быть побитовым отрицанием битов 2 и 3 (NNb codes the bitwise negated CDBIMS,MAX) и, согласно закодированному значению, микросхема поддерживает максимально возможный размер команд 252 байт CDBIMS,MAX (Command Data Bytes Integer, Master to Slave, MAXimum) value.

Согласно описанию протокола, после выполнения этих трех команд и именно в таком порядке, микросхема готова выполнять обычные APDU команды (хотя у меня вроде бы работало и без настройки параметров обмена, т.е. достаточно было сделать Soft Reset и прочитать ATR).

Выполнение APDU команд

Каждый цикл выполнения APDU команд состоит из следующих шагов:

Примеры реализации этих функций можно посмотреть в коде, а ниже приведены только APDU команды и ответные данные.

Источник

Оцените статью
Adblock
detector