예제 #1
0
/*
 * Get the number of sectors allocated in the MAD for the provided application.
 */
size_t
count_aids (const Mad mad, const MadAid aid)
{
    size_t result = 0;

    MifareClassicSectorNumber s_max = (mad_get_version (mad) == 1) ? 0x0f : 0x27;

    /* Count application sectors */
    MadAid c_aid;
    for (MifareClassicSectorNumber s = FIRST_SECTOR; s <= s_max; s++) {
	mad_get_aid (mad, s, &c_aid);
	if (0 == aidcmp (aid, c_aid)) {
	    result++;
	}
    }

    return result;
}
예제 #2
0
/*
 * Allocates a new application into a MAD.
 */
MifareClassicSectorNumber *
mifare_application_alloc (Mad mad, MadAid aid, size_t size)
{
    uint8_t sector_map[40];
    MifareClassicSectorNumber sector;
    MadAid sector_aid;
    MifareClassicSectorNumber *res = NULL;
    ssize_t s = size;

    /*
     * Ensure the card does not already have the application registered.
     */
    MifareClassicSectorNumber *found;
    if ((found = mifare_application_find (mad, aid))) {
	free (found);
	return NULL;
    }

    for (size_t i = 0; i < sizeof (sector_map); i++)
	sector_map[i] = 0;

    /*
     * Try to minimize lost space and allocate as many large pages as possible
     * when the target is a Mifare Classic 4k.
     */
    MadAid free_aid = { 0x00, 0x00 };
    if (mad_get_version (mad) == 2) {
	sector = 32;
	while ((s >= 12*16) && sector < 40) {
	    mad_get_aid (mad, sector, &sector_aid);
	    if (0 == aidcmp (sector_aid, free_aid)) {
		sector_map[sector] = 1;
		s -= 15*16;
	    }
	    sector++;
	}
    }

    sector = FIRST_SECTOR;
    MifareClassicSectorNumber s_max = (mad_get_version (mad) == 1) ? 15 : 31;
    while ((s > 0) && (sector <= s_max)) {
	if (mad_sector_reserved (sector))
	    continue;
	mad_get_aid (mad, sector, &sector_aid);
	if (0 == aidcmp (sector_aid, free_aid)) {
	    sector_map[sector] = 1;
	    s -= 3*16;
	}
	sector++;
    }

    /*
     * Ensure the remaining free space is suficient before destroying the MAD.
     */
    if (s > 0)
	return NULL;

    int n = 0;
    for (size_t i = FIRST_SECTOR; i < sizeof (sector_map); i++)
	if (sector_map[i])
	    n++;

    if (!(res = malloc (sizeof (*res) * (n+1))))
	return NULL;

    n = 0;
    for (size_t i = FIRST_SECTOR; i < sizeof (sector_map); i++)
	if (sector_map[i]) {
	    res[n] = i;
	    mad_set_aid (mad, i, aid);
	    n++;
	}

    res[n] = 0;

    /* Return the list of allocated sectors */
    return res;
}
예제 #3
0
void
test_mad (void)
{
    int res;

    Mad mad = mad_new (1);
    cut_assert_not_null (mad, cut_message ("Can create a new MAD"));

    cut_assert_equal_int (1, mad_get_version (mad), cut_message ("Wrong default MAD version"));
    mad_set_version (mad, 2);
    cut_assert_equal_int (2, mad_get_version (mad), cut_message ("Can't change MAD version"));

    cut_assert_equal_int (0, mad_get_card_publisher_sector (mad), cut_message ("Wrong default MAD publisher"));

    res = mad_set_card_publisher_sector (mad, 13);
    cut_assert_equal_int (0, res, cut_message ("mad_set_card_publisher_sector() returned an error."));
    cut_assert_equal_int (13, mad_get_card_publisher_sector (mad), cut_message ("Wrong publisher sector"));

    res = mad_set_card_publisher_sector (mad, 0xff);
    cut_assert_equal_int (-1, res, cut_message ("Invalid sector"));
    cut_assert_equal_int (13, mad_get_card_publisher_sector (mad), cut_message ("Previous publisher sector value"));

    MadAid aid = {
	.function_cluster_code = 0,
	.application_code = 0
    };

    res = mad_get_aid (mad, 3, &aid);
    cut_assert_equal_int (0, res, cut_message ("mad_get_aid() failed"));
    cut_assert_equal_int (0, aid.function_cluster_code, cut_message ("Invalid default value"));
    cut_assert_equal_int (0, aid.application_code, cut_message ("Invalid default value"));

    aid.function_cluster_code = 0xc0;
    aid.application_code = 0x42;
    res = mad_set_aid (mad, 3, aid);
    cut_assert_equal_int (0, res, cut_message ("mad_set_aid() failed"));

    res = mad_get_aid (mad, 3, &aid);
    cut_assert_equal_int (0, res, cut_message ("mad_get_aid() failed"));
    cut_assert_equal_int (0xC0, aid.function_cluster_code, cut_message ("Invalid value"));
    cut_assert_equal_int (0x42, aid.application_code, cut_message ("Invalid value"));

    mad_free (mad);
}

#define CRC_PRESET 0xc7

void
test_mad_crc8_basic (void)
{
    uint8_t crc;
    const uint8_t crc_value = 0x42;

    /* Check integrity */
    crc = CRC_PRESET;
    nxp_crc(&crc, crc_value);
    uint8_t save = crc;

    crc = CRC_PRESET;
    nxp_crc(&crc, crc_value);
    nxp_crc(&crc, save);
    cut_assert_equal_int (0x00, crc, cut_message ("CRC should verify crc(message + crc(message)) = 0"));
}