From e68ae59c5e3d0c50b7a3f38a34bf4cef9f72cc4a Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Tue, 24 Aug 2010 10:51:58 +0000 Subject: [PATCH] Rename mad_application_(read|write) to mifare_application_(read|write). Fixes issue 40. --- NEWS | 2 +- examples/mifare-classic-write-ndef.c | 4 +- libfreefare/Makefile.am | 4 +- libfreefare/freefare.h | 4 +- libfreefare/mad.3 | 49 ++----------- libfreefare/mad.c | 102 +-------------------------- libfreefare/mifare_application.3 | 44 +++++++++++- libfreefare/mifare_application.c | 100 ++++++++++++++++++++++++++ libfreefare/mifare_classic.c | 2 + test/test_mifare_classic_mad.c | 16 ++--- 10 files changed, 165 insertions(+), 162 deletions(-) diff --git a/NEWS b/NEWS index ec08539..e46218c 100644 --- a/NEWS +++ b/NEWS @@ -10,4 +10,4 @@ Changes between 0.1.0 and x.x.x [xx XXX xxxx] *) New API functions mifare_classic_block_sector(), mifare_classic_sector_first_block(), mifare_classic_sector_block_count() and mifare_classic_sector_last_block(). - *) New API functions mad_application_read(), mad_application_write(). + *) New API functions mifare_application_read(), mifare_application_write(). diff --git a/examples/mifare-classic-write-ndef.c b/examples/mifare-classic-write-ndef.c index a233a09..7c9f051 100644 --- a/examples/mifare-classic-write-ndef.c +++ b/examples/mifare-classic-write-ndef.c @@ -282,8 +282,8 @@ main(int argc, char *argv[]) s++; } - if ((ssize_t) encoded_size != mad_application_write (tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) { - perror ("mad_application_write"); + if ((ssize_t) encoded_size != mifare_application_write (tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) { + perror ("mifare_application_write"); error = EXIT_FAILURE; goto error; } diff --git a/libfreefare/Makefile.am b/libfreefare/Makefile.am index cad9520..f371abf 100644 --- a/libfreefare/Makefile.am +++ b/libfreefare/Makefile.am @@ -46,8 +46,6 @@ linkedman = \ freefare.3 freefare_get_tag_type.3 \ freefare.3 freefare_get_tag_uid.3 \ freefare.3 freefare_get_tags.3 \ - mad.3 mad_application_read.3 \ - mad.3 mad_application_write.3 \ mad.3 mad_free.3 \ mad.3 mad_get_aid.3 \ mad.3 mad_get_card_publisher_sector.3 \ @@ -61,6 +59,8 @@ linkedman = \ mifare_application.3 mifare_application_alloc.3 \ mifare_application.3 mifare_application_find.3 \ mifare_application.3 mifare_application_free.3 \ + mifare_application.3 mifare_application_read.3 \ + mifare_application.3 mifare_application_write.3 \ mifare_classic.3 mifare_classic_authenticate.3 \ mifare_classic.3 mifare_classic_connect.3 \ mifare_classic.3 mifare_classic_decrement.3 \ diff --git a/libfreefare/freefare.h b/libfreefare/freefare.h index 4d571bc..0014faf 100644 --- a/libfreefare/freefare.h +++ b/libfreefare/freefare.h @@ -155,10 +155,10 @@ int mad_get_aid (Mad mad, const MifareClassicSectorNumber sector, MadAid *aid) int mad_set_aid (Mad mad, const MifareClassicSectorNumber sector, MadAid aid); bool mad_sector_reserved (const MifareClassicSectorNumber sector); void mad_free (Mad mad); -ssize_t mad_application_read (MifareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); -ssize_t mad_application_write (MifareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); MifareClassicSectorNumber *mifare_application_alloc (Mad mad, const MadAid aid, const size_t size); +ssize_t mifare_application_read (MifareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); +ssize_t mifare_application_write (MifareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); void mifare_application_free (Mad mad, const MadAid aid); MifareClassicSectorNumber *mifare_application_find (Mad mad, const MadAid aid); diff --git a/libfreefare/mad.3 b/libfreefare/mad.3 index 4f5c378..3d6506b 100644 --- a/libfreefare/mad.3 +++ b/libfreefare/mad.3 @@ -35,8 +35,6 @@ .Nm mad_get_aid , .Nm mad_set_aid , .Nm mad_free , -.Nm mad_application_read , -.Nm mad_application_write .Nd "Mifare Application Directory (MAD) Manipulation Functions" .\" _ _ _ .\" | | (_) |__ _ __ __ _ _ __ _ _ @@ -74,10 +72,6 @@ Mifare card manipulation library (libfreefare, \-lfreefare) .Fn mad_set_aid "Mad mad" "MifareClassicSectorNumber sector" "MadAid aid" .Ft void .Fn mad_free "Mad mad" -.Ft ssize_t -.Fn mad_application_read "MifareTag tag" "Mad mad" "MadAid aid" "void *buf" "size_t nbytes" "MifareClassicKey key" "MifareClassicKeyType key_type" -.Ft ssize_t -.Fn mad_application_write "MifareTag tag" "Mad mad" "MadAid aid" "const void *buf" "size_t nbytes" "MifareClassicKey key" "MifareClassicKeyType key_type" .\" ____ _ _ _ .\" | _ \ ___ ___ ___ _ __(_)_ __ | |_(_) ___ _ __ .\" | | | |/ _ \/ __|/ __| '__| | '_ \| __| |/ _ \| '_ \ @@ -147,48 +141,13 @@ functions. These functions fill-in or read the Application Identifier, .Vt aid for the given .Vt sector . -.Pp -The -.Fn mad_application_read -reads at most -.Vt nbytes -of the application identified by -.Vt aid -in the -.Vt mad -on the -.Vt tag -and copy them into -.Vt buf. -The function returns the amount of data it copied, or -1 on error. -.Pp -The -.Fn mad_application_write -functions writes at most -.Vt nbytes -of -.Vt buf -in the application identified by -.Vt aid -on the -.Vt mad -of the -.Vt tag -and returns the quantity of data written, or -1 on error. -.\" ___ _ _ _ _ _ -.\" |_ _|_ __ ___ _ __ | | ___ _ __ ___ ___ _ __ | |_ __ _| |_(_) ___ _ __ _ __ ___ | |_ ___ ___ +.\" ___ _ _ _ _ _ +.\" |_ _|_ __ ___ _ __ | | ___ _ __ ___ ___ _ __ | |_ __ _| |_(_) ___ _ __ _ __ ___ | |_ ___ ___ .\" | || '_ ` _ \| '_ \| |/ _ \ '_ ` _ \ / _ \ '_ \| __/ _` | __| |/ _ \| '_ \ | '_ \ / _ \| __/ _ \/ __| .\" | || | | | | | |_) | | __/ | | | | | __/ | | | || (_| | |_| | (_) | | | | | | | | (_) | || __/\__ \ .\" |___|_| |_| |_| .__/|_|\___|_| |_| |_|\___|_| |_|\__\__,_|\__|_|\___/|_| |_| |_| |_|\___/ \__\___||___/ -.\" |_| -.Sh IMPLEMENTATION NOTES -The -.Vt nbytes -argument of -.Fn mad_application_read -and -.Fn mad_application_write -does not need to be aligned on blocks not sectors. +.\" |_| +.\".Sh IMPLEMENTATION NOTES .\" ____ _ _ .\" | _ \ ___| |_ _ _ _ __ _ __ __ ____ _| |_ _ ___ ___ .\" | |_) / _ \ __| | | | '__| '_ \ \ \ / / _` | | | | |/ _ \/ __| diff --git a/libfreefare/mad.c b/libfreefare/mad.c index f81cb13..2c5b227 100644 --- a/libfreefare/mad.c +++ b/libfreefare/mad.c @@ -33,15 +33,13 @@ #include -#include #include +#include #include #include #include -#include "freefare_internal.h" - /* * The documentation says the preset is 0xE3 but the bits have to be mirrored: * 0xe3 = 1110 0011 <=> 1100 0111 = 0xc7 @@ -463,101 +461,3 @@ mad_free (Mad mad) { free (mad); } - -ssize_t -mad_application_read (MifareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type) -{ - ssize_t res = 0; - - MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid); - MifareClassicSectorNumber *s = sectors; - - if (!sectors) - return errno = EBADF, -1; - - while (*s && nbytes && (res >= 0)) { - MifareClassicBlockNumber first_block = mifare_classic_sector_first_block (*s); - MifareClassicBlockNumber last_block = mifare_classic_sector_last_block (*s); - - MifareClassicBlockNumber b = first_block; - MifareClassicBlock block; - - if (mifare_classic_authenticate (tag, first_block, key, key_type) < 0) { - res = -1; - break; - } - - while ((b < last_block) && nbytes) { - size_t n = MIN (nbytes, 16); - - if (mifare_classic_read (tag, b, &block) < 0) { - res = -1; - break; - } - memcpy ((uint8_t *)buf + res, &block, n); - - nbytes -= n; - res += n; - - b++; - } - - s++; - } - - free (sectors); - return res; -} - -ssize_t -mad_application_write (MifareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type) -{ - ssize_t res = 0; - - MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid); - MifareClassicSectorNumber *s = sectors; - - if (!sectors) - return errno = EBADF, -1; - - while (*s && nbytes && (res >= 0)) { - MifareClassicBlockNumber first_block = mifare_classic_sector_first_block (*s); - MifareClassicBlockNumber last_block = mifare_classic_sector_last_block (*s); - - MifareClassicBlockNumber b = first_block; - MifareClassicBlock block; - - if (mifare_classic_authenticate (tag, first_block, key, key_type) < 0) { - res = -1; - break; - } - - while ((b < last_block) && nbytes) { - size_t n = MIN (nbytes, 16); - // Avoid overwriting existing data with uninitialized memory. - if (n < 16) { - if (mifare_classic_read (tag, b, &block) < 0) { - res = -1; - break; - } - } - - memcpy (&block, (uint8_t *)buf + res, n); - if (mifare_classic_write (tag, b, block) < 0) { - res = -1; - break; - } - - nbytes -= n; - res += n; - - b++; - } - - s++; - } - - free (sectors); - return res; - -} diff --git a/libfreefare/mifare_application.3 b/libfreefare/mifare_application.3 index 1f06e31..e3bde23 100644 --- a/libfreefare/mifare_application.3 +++ b/libfreefare/mifare_application.3 @@ -26,8 +26,10 @@ .\" .Sh NAME .Nm mifare_application_alloc , +.Nm mifare_application_find , .Nm mifare_application_free , -.Nm mifare_application_find +.Nm mifare_application_read , +.Nm mifare_application_write .Nd Mifare Applications Manipulation Functions .\" _ _ _ .\" | | (_) |__ _ __ __ _ _ __ _ _ @@ -51,6 +53,10 @@ Mifare card manipulation library (libfreefare, \-lfreefare) .Fn mifare_application_free "Mad mad" "MadAid aid" .Ft "MifareClassicSectorNumber *" .Fn mifare_application_find "Mad mad" "MadAid aid" +.Ft ssize_t +.Fn mifare_application_read "MifareTag tag" "Mad mad" "MadAid aid" "void *buf" "size_t nbytes" "MifareClassicKey key" "MifareClassicKeyType key_type" +.Ft ssize_t +.Fn mifare_application_write "MifareTag tag" "Mad mad" "MadAid aid" "const void *buf" "size_t nbytes" "MifareClassicKey key" "MifareClassicKeyType key_type" .\" ____ _ _ _ .\" | _ \ ___ ___ ___ _ __(_)_ __ | |_(_) ___ _ __ .\" | | | |/ _ \/ __|/ __| '__| | '_ \| __| |/ _ \| '_ \ @@ -82,6 +88,34 @@ An application can be removed from a .Vt mad using .Fn mifare_application_free . +.Pp +The +.Fn mifare_application_read +reads at most +.Vt nbytes +of the application identified by +.Vt aid +in the +.Vt mad +on the +.Vt tag +and copy them into +.Vt buf. +The function returns the amount of data it copied, or -1 on error. +.Pp +The +.Fn mifare_application_write +functions writes at most +.Vt nbytes +of +.Vt buf +in the application identified by +.Vt aid +on the +.Vt mad +of the +.Vt tag +and returns the quantity of data written, or -1 on error. .\" ___ _ _ _ _ _ .\" |_ _|_ __ ___ _ __ | | ___ _ __ ___ ___ _ __ | |_ __ _| |_(_) ___ _ __ _ __ ___ | |_ ___ ___ .\" | || '_ ` _ \| '_ \| |/ _ \ '_ ` _ \ / _ \ '_ \| __/ _` | __| |/ _ \| '_ \ | '_ \ / _ \| __/ _ \/ __| @@ -94,6 +128,14 @@ The function will try to avoid wasting space and might not allocate sectors sequentially if a large amount of space is requested and the target has sectors of different size. +.Pp +The +.Vt nbytes +argument of +.Fn mifare_application_read +and +.Fn mifare_application_write +does not need to be aligned on blocks not sectors. .\" ____ _ _ .\" | _ \ ___| |_ _ _ _ __ _ __ __ ____ _| |_ _ ___ ___ .\" | |_) / _ \ __| | | | '__| '_ \ \ \ / / _` | | | | |/ _ \/ __| diff --git a/libfreefare/mifare_application.c b/libfreefare/mifare_application.c index 1ed2237..50e905f 100644 --- a/libfreefare/mifare_application.c +++ b/libfreefare/mifare_application.c @@ -25,9 +25,12 @@ */ #include "config.h" +#include +#include #include #include +#include "freefare_internal.h" #define FIRST_SECTOR 1 @@ -203,3 +206,100 @@ mifare_application_find (Mad mad, MadAid aid) return res; } +ssize_t +mifare_application_read (MifareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type) +{ + ssize_t res = 0; + + MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid); + MifareClassicSectorNumber *s = sectors; + + if (!sectors) + return errno = EBADF, -1; + + while (*s && nbytes && (res >= 0)) { + MifareClassicBlockNumber first_block = mifare_classic_sector_first_block (*s); + MifareClassicBlockNumber last_block = mifare_classic_sector_last_block (*s); + + MifareClassicBlockNumber b = first_block; + MifareClassicBlock block; + + if (mifare_classic_authenticate (tag, first_block, key, key_type) < 0) { + res = -1; + break; + } + + while ((b < last_block) && nbytes) { + size_t n = MIN (nbytes, 16); + + if (mifare_classic_read (tag, b, &block) < 0) { + res = -1; + break; + } + memcpy ((uint8_t *)buf + res, &block, n); + + nbytes -= n; + res += n; + + b++; + } + + s++; + } + + free (sectors); + return res; +} + +ssize_t +mifare_application_write (MifareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type) +{ + ssize_t res = 0; + + MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid); + MifareClassicSectorNumber *s = sectors; + + if (!sectors) + return errno = EBADF, -1; + + while (*s && nbytes && (res >= 0)) { + MifareClassicBlockNumber first_block = mifare_classic_sector_first_block (*s); + MifareClassicBlockNumber last_block = mifare_classic_sector_last_block (*s); + + MifareClassicBlockNumber b = first_block; + MifareClassicBlock block; + + if (mifare_classic_authenticate (tag, first_block, key, key_type) < 0) { + res = -1; + break; + } + + while ((b < last_block) && nbytes) { + size_t n = MIN (nbytes, 16); + // Avoid overwriting existing data with uninitialized memory. + if (n < 16) { + if (mifare_classic_read (tag, b, &block) < 0) { + res = -1; + break; + } + } + + memcpy (&block, (uint8_t *)buf + res, n); + if (mifare_classic_write (tag, b, block) < 0) { + res = -1; + break; + } + + nbytes -= n; + res += n; + + b++; + } + + s++; + } + + free (sectors); + return res; + +} diff --git a/libfreefare/mifare_classic.c b/libfreefare/mifare_classic.c index afd3f36..416c743 100644 --- a/libfreefare/mifare_classic.c +++ b/libfreefare/mifare_classic.c @@ -84,6 +84,7 @@ errno = 0; \ DEBUG_XFER (msg, __##msg##_n, "===> "); \ if (!(nfc_initiator_transceive_dep_bytes (tag->device, msg, __##msg##_n, res, &__##res##_n))) { \ + nfc_perror (tag->device, __FUNCTION__); \ if (disconnect) \ tag->active = false; \ return errno = EIO, -1; \ @@ -91,6 +92,7 @@ DEBUG_XFER (res, __##res##_n, "<=== "); \ } while (0) + /* Public Key A value of NFC Forum sectors */ const MifareClassicKey mifare_classic_nfcforum_public_key_a = { 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 diff --git a/test/test_mifare_classic_mad.c b/test/test_mifare_classic_mad.c index d37f322..0127ea6 100644 --- a/test/test_mifare_classic_mad.c +++ b/test/test_mifare_classic_mad.c @@ -98,14 +98,14 @@ test_mifare_classic_mad (void) res = mad_write (tag, mad, key_b_sector_00, NULL); cut_assert_equal_int (0, res, cut_message ("mad_write() failed")); - ssize_t s = mad_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A); - cut_assert_equal_int (sizeof (application_data), s, cut_message ("mad_application_write() failed")); + ssize_t s = mifare_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A); + cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed")); char read_buf[500]; // Read it again - s = mad_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A); - cut_assert_equal_int (sizeof (application_data), s, cut_message ("mad_application_read() failed")); + s = mifare_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A); + cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_read() failed")); cut_assert_equal_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data")); mad_free (mad); @@ -199,12 +199,12 @@ test_mifare_classic_mad (void) res = mad_write (tag, mad, key_b_sector_00, key_b_sector_10); cut_assert_equal_int (0, res, cut_message ("mad_write() failed")); - s = mad_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A); - cut_assert_equal_int (sizeof (application_data), s, cut_message ("mad_application_write() failed")); + s = mifare_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A); + cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed")); // Read it again - s = mad_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A); - cut_assert_equal_int (sizeof (application_data), s, cut_message ("mad_application_read() failed")); + s = mifare_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A); + cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_read() failed")); cut_assert_equal_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data")); mad_free (mad);