Python CR C расчет для чипа NTAG 424 NF C - PullRequest
4 голосов
/ 16 марта 2020

В настоящее время я работаю с чипами NXP NTAG 424 , которые поддерживают шифрование AES-128.

Этот чип требует вычисления контрольного значения crc32 всякий раз, когда устанавливается новый ключ (см. таблица 11.6.1 / стр. 67). Согласно паспорту, cr c «вычисляется в соответствии со стандартом IEEE Std802.3-2008». В примечании к приложению (6.16.1 / стр. 39) даже приведен пример:

new_key: F3847D627727ED3BC9C4CC050489B966
CRC32(new_key): 789DFADC

Однако, когда я пытаюсь воспроизвести результаты, используя python и библиотеку binascii crc32 результат будет другим:

>>> from binascii import unhexlify, crc32
>>> new_key = unhexlify('F3847D627727ED3BC9C4CC050489B966')
>>> print(hex(crc32(new_key)))
0x23056287     # Not the CRC I was looking for

Этот документ часто меняет порядок байтов, однако команда

>>> print(hex(crc32(new_key[::-1])))
0x9453faa7

также не доставляет радости.

Итак, вопрос в следующем: Что я делаю неправильно? Я попытался обратиться к цитируемому стандарту, но, обладая поверхностными знаниями, я не смог обнаружить никакой разницы между стандартом crc32 и алгоритмом, приведенным в стандарте IEEE.

1 Ответ

2 голосов
/ 17 марта 2020

CR C в примере - это COMPLEMENT 32-битного CR C, который IEEE Std802.3 (или эквивалентно CCITT V.42) определяет, который I Деталь Есть со ссылкой. Это еще один случай использования варианта стандартного CR C в этом теге: как и во всех тегах типа A ISO / IEC 14443, при обнаружении ошибок (до 848 кбит / с) используется вариант 16-битный CR C, который указывает IEEE Std802.3 (или эквивалентно CCITT V.42), с другим начальным значением и без конечного дополнения.

Вот автономный код, который соответствует тестовому вектору вопроса :

# compute the CRC32 for NTAG424
# Ethernet / CCITT V42 CRC32, less final complement
def NTAG424CRC(m):
    c = 0xFFFFFFFF
    for b in m:
         c ^= b;
         for n in range(8):
             c = (c>>1)^(0xEDB88320&-(c&1))
#   c ^= 0xFFFFFFFF  # required by Ethernet / CCITT V42
    return c.to_bytes(4,'little')

# demo, expected value 789dfadc
print(NTAG424CRC(bytearray.fromhex('F3847D627727ED3BC9C4CC050489B966')).hex())

Попробуйте онлайн!

Что я делаю не так?

  • Полагая, что изготовитель добросовестно реализовал свою собственную спецификацию.
  • Ожидая, что вывод binascii.crc32 будет старшим порядковым числом; он имеет порядок байтов и должен быть таковым в телекоммуникациях, чтобы сохранить свойство обнаружения ошибок пакета CRC32. В спецификации binascii.crc32 есть упущение иметь int в качестве вывода, когда при использовании bytearray как его ввод может привести к ошибке endianess почти невозможно.

Мы можем и вероятно следует использовать binascii.crc32, который является нативным и использует предварительно вычисленную таблицу, поэтому намного быстрее (но может быть более восприимчивым к атакам по побочным каналам, связанным с кэшем).

import binascii

# compute the CRC32 for NTAG424 using binascii.crc32
# Ethernet / CCITT V42 CRC32, less final complement
def NTAG424CRC(m):
    return (binascii.crc32(m)&0xFFFFFFFF^0xFFFFFFFF).to_bytes(4,'little')
# &0xFFFFFFFF deals with negative output; it can be removed under Python 3
# ^0xFFFFFFFF undoes the complement rightly done by binascii.crc32

# demo, expected value 789dfadc
print(NTAG424CRC(bytearray.fromhex('F3847D627727ED3BC9C4CC050489B966')).hex())

Попробуйте это онлайн!

...