Add example to read ST25TB* and legacy SR* cards

This commit is contained in:
Benjamin DELPY 2021-06-09 21:56:50 +02:00 committed by GitHub
parent 1dc9dcb664
commit 7da771a37b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 302 additions and 0 deletions

View File

@ -8,6 +8,7 @@ SET(EXAMPLES-SOURCES
nfc-mfsetuid
nfc-poll
nfc-relay
nfc-st25tb-info
pn53x-diagnose
pn53x-sam
pn53x-tamashell

View File

@ -10,6 +10,7 @@ bin_PROGRAMS = \
nfc-mfsetuid \
nfc-poll \
nfc-relay \
nfc-st25tb-info \
pn53x-diagnose \
pn53x-sam
@ -63,6 +64,9 @@ nfc_mfsetuid_SOURCES = nfc-mfsetuid.c
nfc_mfsetuid_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la
nfc_st25tb_info_SOURCES = nfc-st25tb-info.c
nfc_st25tb_info_LDADD = $(top_builddir)/libnfc/libnfc.la
pn53x_diagnose_SOURCES = pn53x-diagnose.c
pn53x_diagnose_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la
@ -95,6 +99,7 @@ dist_man_MANS = \
nfc-poll.1 \
nfc-relay.1 \
nfc-mfsetuid.1 \
nfc-st25tb-info.1 \
pn53x-diagnose.1 \
pn53x-sam.1 \
pn53x-tamashell.1 \

View File

@ -0,0 +1,50 @@
.Dd June 9, 2021
.Dt NFC-ST25TB-INFO 1 URM
.Sh NAME
.Nm nfc-st25tb-info
.Nd Read ISO-14443-B ST25TB* and legacy SR* cards
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
.Nm
is a demonstration tool that try to dump the content of ISO-14443-B ST25TB* and legacy SR* cards.
.Pp
It includes, in theory, cards from STMicroelectronics, like ST25TB512-AC, ST25TB512-AT, ST25TB02K and ST25TB04K (at this time, not supported by Proxmark3). Legacy STMicroelectronics cards like SRT512, SRI512, or others SR* can also be dumped (supported by Proxmark3).
.Sh IMPORTANT
This example has been developed using PN533 USB hardware as initiator.
.Pp
It was tested with these cards:
.Pp
- ST25TB512-AC - (BE/Brussels/STIB ; AliExpress ones)
.br
- ST25TB512-AT - (FR/Lille/Ilevia ; FR/Reims/Citura)
.br
- SRT512 - legacy - (FR/Bordeaux/TBM)
.br
- SRI512 - legacy - (anonymous vending machine)
.Sh TODO
At this time, neither reading to file, neither loading from file is supported. Dealing with counters logic is dangerous and cannot be undo.
.Sh BUGS
Please report any bugs on the
.Em libnfc
issue tracker at:
.Em https://github.com/nfc-tools/libnfc/issues
.Sh LICENCE
-
.Em libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.br
-
.Em libnfc-utils
and
.Em libnfc-examples
are covered by the BSD 2-Clause license.
.br
-
.Em nfc-st25tb-info
is covered by Creative Commons Attribution 4.0 International (CC BY 4.0).
.Sh AUTHOR
.An Benjamin Delpy Aq benjamin@gentilkiwi.net
.Pp
This manual page was written by Benjamin Delpy.
It is licensed under the terms of the GNU GPL (version 2 or later).

246
examples/nfc-st25tb-info.c Normal file
View File

@ -0,0 +1,246 @@
/*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file nfc-st25tb-info.c
* @brief Read ISO-14443-B ST25TB* and legacy SR* cards
*/
/* Benjamin DELPY `gentilkiwi`
* https://blog.gentilkiwi.com
* benjamin@gentilkiwi.com
* Licence : https://creativecommons.org/licenses/by/4.0/
* Rely on : libnfc - https://github.com/nfc-tools/libnfc
*
* $ gcc -lnfc -o nfc-st25tb-info nfc-st25tb-info.c
* $ ./nfc-st25tb-info
*/
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <nfc/nfc.h>
bool get_info(const nfc_target *pnt, uint8_t *pnbBlock, uint8_t *pbnSystem);
bool get_block_at(nfc_device *pnd, uint8_t block, uint8_t value[4], bool bPrintIt);
void print_hex(const uint8_t *pbtData, const size_t szBytes);
int main(int argc, const char *argv[])
{
nfc_context *context = NULL;
nfc_device *pnd = NULL;
nfc_target nt = {0};
nfc_modulation nm = {NMT_ISO14443B, NBR_106};
int res;
uint8_t i, nbBlock, bnSystem;
(void) argc;
(void) argv;
nfc_init(&context);
if(context)
{
pnd = nfc_open(context, NULL);
if(pnd)
{
res = nfc_initiator_init(pnd);
if(res == NFC_SUCCESS)
{
printf("Reader : %s - via %s\n ...wait for card...\n", nfc_device_get_name(pnd), nfc_device_get_connstring(pnd));
res = nfc_initiator_list_passive_targets(pnd, nm, &nt, 1);
if(res == 0) // we don't really wanted a NMT_ISO14443B
{
nm.nmt = NMT_ISO14443B2SR; // we want a NMT_ISO14443B2SR, but needed to ask for NMT_ISO14443B before
if (nfc_initiator_select_passive_target(pnd, nm, NULL, 0, &nt) > 0)
{
if(get_info(&nt, &nbBlock, &bnSystem))
{
printf("\nData :\n");
for(i = 0; i < nbBlock; i++)
{
get_block_at(pnd, i, NULL, 1);
}
get_block_at(pnd, bnSystem, NULL, 1);
}
}
}
else if(res > 0)
{
printf("ERROR - We got a NMT_ISO14443B ?\n");
}
else printf("ERROR - nfc_initiator_list_passive_targets: %i\n", res);
}
else printf("ERROR - nfc_initiator_init: %i\n", res);
nfc_close(pnd);
}
else printf("ERROR - nfc_open\n");
nfc_exit(context);
}
else printf("ERROR - nfc_init\n");
return 0;
}
bool get_info(const nfc_target *pnt, uint8_t *pnbBlock, uint8_t *pbnSystem)
{
bool bRet = false, bIsLegacy = false;
const uint8_t *p;
uint8_t chipId;
*pnbBlock = 0x10;
*pbnSystem = 0xff;
if(pnt->nm.nmt == NMT_ISO14443B2SR)
{
printf("Target : %s (%s)\nUID : ", str_nfc_modulation_type(pnt->nm.nmt), str_nfc_baud_rate(pnt->nm.nbr));
print_hex(pnt->nti.nsi.abtUID, sizeof(pnt->nti.nsi.abtUID));
printf("\n");
p = pnt->nti.nsi.abtUID;
if(p[7] == 0xd0) // ST25TB* / SR*
{
bRet = true;
chipId = p[5];
printf("Manuf : 0x%02x - %s\nChipId : 0x%02x - ", p[6], (p[6] == 0x02) ? "STMicroelectronics" : "other", chipId);
switch(chipId)
{
case 0x3f: // 00111111
printf("ST25TB02K");
*pnbBlock = 0x40;
break;
case 0x1f: // 00011111
printf("ST25TB04K");
*pnbBlock = 0x80;
break;
case 0x1b: // 00011011
printf("ST25TB512-AC");
break;
case 0x33: // 00110011
printf("ST25TB512-AT");
break;
default:
chipId >>= 2;
printf("legacy ? - 0x%02x - ", chipId);
bIsLegacy = 1;
switch(chipId)
{
case 0x02:
printf("SR176");
*pnbBlock = 0x0e;
*pbnSystem = 0x0f;
break;
case 0x03:
printf("SRIX4K");
*pnbBlock = 0x80;
break;
case 0x04:
printf("SRIX512");
break;
case 0x06:
printf("SRI512");
break;
case 0x07:
printf("SRI4K");
*pnbBlock = 0x80;
break;
case 0x0c:
printf("SRT512");
break;
default:
bIsLegacy = 0;
printf("unknown");
}
}
printf("\nSerial : 0x");
if(bIsLegacy)
{
printf("%1x", p[5] & 0x03);
}
printf("%02x%02x%02x%02x%02x\n|usr blk: %hhu\n|sys blk: %hhu\n", p[4], p[3], p[2], p[1], p[0], *pnbBlock, *pbnSystem);
}
else printf("WARNI - Last byte of UID isn\'t 0xd0, but 0x%02x (not ST25TB / SR series?)\n", p[7]);
}
else printf("ERROR - not a NMT_ISO14443B2SR ?\n");
return bRet;
}
bool get_block_at(nfc_device *pnd, uint8_t block, uint8_t value[4], bool bPrintIt)
{
bool bRet = false;
uint8_t tx[2] = {0x08, block}, rx[4];
int res;
res = nfc_initiator_transceive_bytes(pnd, tx, sizeof(tx), rx, sizeof(rx), 0);
if(res == 4)
{
bRet = true;
if(value)
{
memcpy(value, rx, sizeof(rx));
}
if(bPrintIt)
{
printf("[%02x] ", block);
print_hex(rx, sizeof(rx));
printf("\n");
}
}
else if(res > 0)
{
printf("ERROR - We got %i bytes?\n", res);
}
else printf("ERROR - nfc_initiator_transceive_bytes: %i\n", res);
return bRet;
}
void print_hex(const uint8_t *pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos = 0; szPos < szBytes; szPos++)
{
printf("%02x ", pbtData[szPos]);
}
}