Beispiel #1
0
int
mifare_desfire_get_value_ex (MifareTag tag, uint8_t file_no, int32_t *value, int cs)
{
    if (!value)
	return errno = EINVAL, -1;

    void *p;

    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 2);
    BUFFER_INIT (res, 9);

    BUFFER_APPEND (cmd, 0x6C);
    BUFFER_APPEND (cmd, file_no);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    p = (uint8_t *)res + 1;

    if (cs) {
	ssize_t rdl = BUFFER_SIZE (res) - 1;
	p = mifare_cryto_postprocess_data (tag, p, &rdl, cs);
	if (rdl != 4) {
	    printf ("invalid data length");
	    return -1;
	}
    }

    *value = le32toh (*(int32_t *)(p));

    return 0;
}
Beispiel #2
0
static ssize_t
read_data (MifareTag tag, uint8_t command, uint8_t file_no, off_t offset, size_t length, void *data, int cs)
{
    ssize_t bytes_read = 0;

    void *p = data;

    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 8);
    BUFFER_INIT (res, MAX_FRAME_SIZE);

    BUFFER_APPEND (cmd, command);
    BUFFER_APPEND (cmd, file_no);
    BUFFER_APPEND_LE (cmd, offset, 3, sizeof (off_t));
    BUFFER_APPEND_LE (cmd, length, 3, sizeof (size_t));

    if (cs) {
	if (!(p = assert_crypto_buffer_size (tag, MAX_FRAME_SIZE - 1)))
	    return -1;
    }

    do {
	ssize_t frame_bytes;

	DESFIRE_TRANSCEIVE (tag, cmd, res);

	frame_bytes = BUFFER_SIZE (res) - 1;
	memcpy ((uint8_t *)p + bytes_read, res + 1, frame_bytes);
	bytes_read += frame_bytes;

	if (res[0] == 0xAF) {
	    if (p != data) {
		// If we are handling memory, request more for next frame.
		if (!(p = assert_crypto_buffer_size (tag, bytes_read + MAX_FRAME_SIZE - 1)))
		    return -1;

	    }
	BUFFER_CLEAR (cmd);
	BUFFER_APPEND (cmd, 0xAF);
	}

    } while (res[0] != 0x00);

    if (cs) {
	if (mifare_cryto_postprocess_data (tag, p, &bytes_read, cs))
	    memcpy (data, p, bytes_read);
    }

    return bytes_read;
}
Beispiel #3
0
int
mifare_desfire_change_key (MifareTag tag, uint8_t key_no, MifareDESFireKey new_key, MifareDESFireKey old_key)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);
    ASSERT_AUTHENTICATED (tag);

    BUFFER_INIT (cmd, 1+1+24);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xC4);
    BUFFER_APPEND (cmd, key_no);

    uint8_t data[24];

    if ((MIFARE_DESFIRE (tag)->authenticated_key_no != key_no) /* FIXME && (ChangeKey key != 0x0E)*/) {
	if (old_key) {
	    memcpy (data, old_key->data, 16);
	} else {
	    bzero (data, 16);
	}
	for (int n=0; n<16; n++) {
	    data[n] ^= new_key->data[n];
	}
	// Append XORed data CRC
	iso14443a_crc (data, 16, data+16);
	// Append new key CRC
	iso14443a_crc (new_key->data, 16, data+18);
	// Padding
	for (int n=20; n<24; n++) {
	    data[n] = 0x00;
	}
    } else {
	memcpy (data, new_key->data, 16);
	// Append new key CRC
	iso14443a_crc (data, 16, data+16);

	// Padding
	for (int n=18; n<24; n++) {
	    data[n] = 0x00;
	}
    }

    mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, data, 24, MD_SEND, 0);

    BUFFER_APPEND_BYTES (cmd, data, 24);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #4
0
static ssize_t
write_data (MifareTag tag, uint8_t command, uint8_t file_no, off_t offset, size_t length, void *data, int cs)
{
    size_t bytes_left;
    size_t bytes_send = 0;

    void *p = data;

    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, MAX_FRAME_SIZE);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, command);
    BUFFER_APPEND (cmd, file_no);
    BUFFER_APPEND_LE (cmd, offset, 3, sizeof (off_t));
    BUFFER_APPEND_LE (cmd, length, 3, sizeof (size_t));

    p = mifare_cryto_preprocess_data (tag, data, &length, cs);

    bytes_left = 52;

    while (bytes_send < length) {
	size_t frame_bytes = MIN(bytes_left, length - bytes_send);

	BUFFER_APPEND_BYTES (cmd, (uint8_t *)p + bytes_send, frame_bytes);

	DESFIRE_TRANSCEIVE (tag, cmd, res);

	bytes_send += frame_bytes;

	if (0x00 == res[0])
	    break;

	// PICC returned 0xAF and expects more data
	BUFFER_CLEAR (cmd);
	BUFFER_APPEND (cmd, 0xAF);
	bytes_left = 0x59;
    }

    if (0x00 != res[0]) {
	// 0xAF (additionnal Frame) failure can happen here (wrong crypto method).
	MIFARE_DESFIRE (tag)->last_picc_error = res[0];
	bytes_send = -1;
    }

    return bytes_send;
}
Beispiel #5
0
int
mifare_desfire_change_key_settings (MifareTag tag, uint8_t settings)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);
    ASSERT_AUTHENTICATED (tag);

    BUFFER_INIT (cmd, 9);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0x54);

    uint8_t data[8];

    data[0] = settings;
    iso14443a_crc (data, 1, data + 1);
    bzero (data+3, 5);

    mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, data, 8, MD_SEND, 0);

    BUFFER_APPEND_BYTES (cmd, data, 8);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #6
0
/*
 * Retrieve version information form the PICC.
 */
int
mifare_desfire_get_version (MifareTag tag, struct mifare_desfire_version_info *version_info)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    ASSERT_NOT_NULL (version_info);

    BUFFER_INIT (cmd, 1);
    BUFFER_INIT (res, 15); /* 8, 8, then 15 byte results */

    BUFFER_APPEND (cmd, 0x60);

    DESFIRE_TRANSCEIVE (tag, cmd, res);
    memcpy (&(version_info->hardware), res+1, 7);

    cmd[0] = 0xAF;
    DESFIRE_TRANSCEIVE (tag, cmd, res);
    memcpy (&(version_info->software), res+1, 7);

    DESFIRE_TRANSCEIVE (tag, cmd, res);
    memcpy (&(version_info->uid), res+1, 14);

    return 0;
}
Beispiel #7
0
int
mifare_desfire_delete_file (MifareTag tag, uint8_t file_no)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 2);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xDF);
    BUFFER_APPEND (cmd, file_no);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #8
0
int
mifare_desfire_change_file_settings (MifareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    // TODO: Use a current application files settings cache.
    struct mifare_desfire_file_settings settings;
    int res = mifare_desfire_get_file_settings (tag, file_no, &settings);
    if (res < 0)
	return res;

    if (MDAR_CHANGE_AR(settings.access_rights) == MDAR_FREE) {
    BUFFER_INIT (cmd, 5);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0x5F);
    BUFFER_APPEND (cmd, file_no);
    BUFFER_APPEND (cmd, communication_settings);
    BUFFER_APPEND_LE (cmd, access_rights, 2, sizeof (uint16_t));

    DESFIRE_TRANSCEIVE (tag, cmd, res);
    } else {
	BUFFER_INIT (cmd, 10);
	BUFFER_INIT (res, 1);

	uint8_t data[8];

	BUFFER_APPEND (cmd, 0x5F);
	BUFFER_APPEND (cmd, file_no);

	data[0] = communication_settings;
	uint16_t le_ar = htole16 (access_rights);
	memcpy (data + 1, &le_ar, sizeof (le_ar));
	iso14443a_crc (data, 3, data+3);
	bzero (data + 5, 3);
	mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, data, 8, MD_SEND, 0);

	BUFFER_APPEND_BYTES (cmd, data, 8);

	DESFIRE_TRANSCEIVE (tag, cmd, res);
    }

    return 0;
}
Beispiel #9
0
int
mifare_desfire_create_application (MifareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 6);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xCA);
    BUFFER_APPEND_LE (cmd, aid->data, sizeof (aid->data), sizeof (aid->data));
    BUFFER_APPEND (cmd, settings);
    BUFFER_APPEND (cmd, key_no);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #10
0
static int
create_file1 (MifareTag tag, uint8_t command, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 8);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, command);
    BUFFER_APPEND (cmd, file_no);
    BUFFER_APPEND (cmd, communication_settings);
    BUFFER_APPEND_LE (cmd, access_rights, 2, sizeof (uint16_t));
    BUFFER_APPEND_LE (cmd, file_size, 3, sizeof (uint32_t));

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #11
0
int
mifare_desfire_get_file_settings (MifareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 2);
    BUFFER_INIT (res, 18);

    BUFFER_APPEND (cmd, 0xF5);
    BUFFER_APPEND (cmd, file_no);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    struct mifare_desfire_raw_file_settings raw_settings;
    memcpy (&raw_settings, res+1, BUFFER_SIZE (res)-1);

    settings->file_type = raw_settings.file_type;
    settings->communication_settings = raw_settings.communication_settings;
    settings->access_rights = le16toh (raw_settings.access_rights);
    
    switch (settings->file_type) {
	case MDFT_STANDARD_DATA_FILE:
	case MDFT_BACKUP_DATA_FILE:
	    settings->settings.standard_file.file_size = le24toh (raw_settings.settings.standard_file.file_size);
	    break;
	case MDFT_VALUE_FILE_WITH_BACKUP:
	    settings->settings.value_file.lower_limit = le32toh (raw_settings.settings.value_file.lower_limit);
	    settings->settings.value_file.upper_limit = le32toh (raw_settings.settings.value_file.upper_limit);
	    settings->settings.value_file.limited_credit_value = le32toh (raw_settings.settings.value_file.limited_credit_value);
	    settings->settings.value_file.limited_credit_enabled = raw_settings.settings.value_file.limited_credit_enabled;
	    break;
	case MDFT_LINEAR_RECORD_FILE_WITH_BACKUP:
	case MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP:
	    settings->settings.linear_record_file.record_size = le24toh (raw_settings.settings.linear_record_file.record_size);
	    settings->settings.linear_record_file.max_number_of_records = le24toh (raw_settings.settings.linear_record_file.max_number_of_records);
	    settings->settings.linear_record_file.current_number_of_records = le24toh (raw_settings.settings.linear_record_file.current_number_of_records);
	    break;
    }

    return 0;
}
Beispiel #12
0
/*
 * Retrieve version information for a given key.
 */
int
mifare_desfire_get_key_version (MifareTag tag, uint8_t key_no, uint8_t *version)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    ASSERT_NOT_NULL (version);

    BUFFER_INIT (cmd, 2);
    BUFFER_APPEND (cmd, 0x64);
    BUFFER_APPEND (cmd, key_no);

    BUFFER_INIT (res, 2);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    *version = res[1];

    return 0;
}
/*
 * Read data to the provided MIFARE tag.
 */
int
mifare_ultralight_write (MifareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_ULTRALIGHT (tag);
    ASSERT_VALID_PAGE (tag, page, true);

    BUFFER_INIT (cmd, 6);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xA2);
    BUFFER_APPEND (cmd, page);
    BUFFER_APPEND_BYTES (cmd, data, sizeof (MifareUltralightPage));

    ULTRALIGHT_TRANSCEIVE (tag, cmd, res);

    /* Invalidate page in cache */
    MIFARE_ULTRALIGHT(tag)->cached_pages[page] = 0;

    return 0;
}
Beispiel #14
0
int
mifare_desfire_create_value_file (MifareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, int32_t lower_limit, int32_t upper_limit, int32_t value, uint8_t limited_credit_enable)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 18);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xCC);
    BUFFER_APPEND (cmd, file_no);
    BUFFER_APPEND (cmd, communication_settings);
    BUFFER_APPEND_LE (cmd, access_rights, 2, sizeof (uint16_t));
    BUFFER_APPEND_LE (cmd, lower_limit, 4, sizeof (int32_t));
    BUFFER_APPEND_LE (cmd, upper_limit, 4, sizeof (int32_t));
    BUFFER_APPEND_LE (cmd, value, 4, sizeof (int32_t));
    BUFFER_APPEND (cmd, limited_credit_enable);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #15
0
int
mifare_desfire_limited_credit_ex (MifareTag tag, uint8_t file_no, int32_t amount, int cs)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 10);
    BUFFER_INIT (res, 1);

    BUFFER_INIT (data, 4);
    BUFFER_APPEND_LE (data, amount, 4, sizeof (int32_t));

    BUFFER_APPEND (cmd, 0x1C);
    BUFFER_APPEND (cmd, file_no);
    size_t n = 4;
    void *d = mifare_cryto_preprocess_data (tag, data, &n, cs);
    BUFFER_APPEND_BYTES (cmd, d, n);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #16
0
int
mifare_desfire_abort_transaction (MifareTag tag)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 1);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xA7);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
/*
 * Read data from the provided MIFARE tag.
 */
int
mifare_ultralight_read (MifareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_ULTRALIGHT (tag);
    ASSERT_VALID_PAGE (tag, page, false);

    if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) {
	BUFFER_INIT (cmd, 2);
	BUFFER_ALIAS (res, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof(MifareUltralightPage) * 4);

	BUFFER_APPEND (cmd, 0x30);
	BUFFER_APPEND (cmd, page);

	ULTRALIGHT_TRANSCEIVE (tag, cmd, res);

	/* Handle wrapped pages */
	int iPageCount;
	if (IS_MIFARE_ULTRALIGHT_C(tag)) {
	    iPageCount = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ;
	} else {
	    iPageCount = MIFARE_ULTRALIGHT_PAGE_COUNT;
	}
	for (int i = iPageCount; i <= page + 3; i++) {
	    memcpy (MIFARE_ULTRALIGHT(tag)->cache[i % iPageCount], MIFARE_ULTRALIGHT(tag)->cache[i], sizeof (MifareUltralightPage));
	}

	/* Mark pages as cached */
	for (int i = page; i <= page + 3; i++) {
	    MIFARE_ULTRALIGHT(tag)->cached_pages[i % iPageCount] = 1;
	}
    }

    memcpy (data, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof (*data));
    return 0;
}
Beispiel #18
0
int
mifare_desfire_format_picc (MifareTag tag)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);
    ASSERT_AUTHENTICATED (tag);

    BUFFER_INIT (cmd, 1);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xFC);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #19
0
int
mifare_desfire_delete_application (MifareTag tag, MifareDESFireAID aid)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 4);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0xDA);
    BUFFER_APPEND_LE (cmd, aid->data, sizeof (aid->data), sizeof (aid->data));

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #20
0
int
mifare_desfire_get_key_settings (MifareTag tag, uint8_t *settings, uint8_t *max_keys)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 1);
    BUFFER_INIT (res, 3);

    BUFFER_APPEND (cmd, 0x45);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    if (settings)
	*settings = res[1];
    if (max_keys)
	*max_keys = res[2];

    return 0;
}
Beispiel #21
0
/*
 * Select the application specified by aid for further operation.  If aid is
 * NULL, the master application is selected (equivalent to aid = 0x00000).
 */
int
mifare_desfire_select_application (MifareTag tag, MifareDESFireAID aid)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    struct mifare_desfire_aid null_aid = { .data = { 0x00, 0x00, 0x00 } };

    if (!aid) {
	aid = &null_aid;
    }

    BUFFER_INIT (cmd, 4);
    BUFFER_INIT (res, 1);

    BUFFER_APPEND (cmd, 0x5A);
    BUFFER_APPEND_LE (cmd, aid->data, sizeof (aid->data), sizeof (aid->data));

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    return 0;
}
Beispiel #22
0
int
mifare_desfire_get_file_ids (MifareTag tag, uint8_t *files[], size_t *count)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 1);
    BUFFER_INIT (res, 16);

    BUFFER_APPEND (cmd, 0x6F);

    DESFIRE_TRANSCEIVE (tag, cmd, res);

    *count = BUFFER_SIZE (res) - 1;

    if (!(*files = malloc (*count))) {
	errno = ENOMEM;
	return -1;
    }
    memcpy (*files, res+1, *count);

    return 0;
}
Beispiel #23
0
int
mifare_desfire_get_application_ids (MifareTag tag, MifareDESFireAID *aids[], size_t *count)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    BUFFER_INIT (cmd, 1);
    BUFFER_INIT (res, MAX_FRAME_SIZE);

    BUFFER_APPEND (cmd, 0x6A);

    DESFIRE_TRANSCEIVE (tag, cmd, res);
    *count = (BUFFER_SIZE (res)-1)/3;
    *aids = malloc ((*count + 1) * sizeof (MifareDESFireAID));
    for (size_t i = 0; (3*i + 1) < BUFFER_SIZE (res); i++) {
	(*aids)[i] = memdup (res + 3*i + 1, 3);
    }

    if (res[0] == 0xAF) {
	cmd[0] = 0xAF;
	DESFIRE_TRANSCEIVE (tag, cmd, res);
	*count += (BUFFER_SIZE (res)-1) / 3;

	MifareDESFireAID *p;
	if ((p = realloc (*aids, (*count + 1) * sizeof (MifareDESFireAID)))) {
	    *aids = p;

	    for (size_t i = 0; (3*i + 1) < BUFFER_SIZE (res); i++) {
		(*aids)[19+i] = memdup (res + 3*i + 1, 3);
	    }
	}
    }

    (*aids)[*count] = NULL;

    return 0;
}
/*
 * Authenticate to the provided MIFARE tag.
 */
int
mifare_ultralightc_authenticate (MifareTag tag, const MifareDESFireKey key)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_ULTRALIGHT_C (tag);

    BUFFER_INIT (cmd1, 2);
    BUFFER_INIT (res, 9);
    BUFFER_APPEND (cmd1, 0x1A);
    BUFFER_APPEND (cmd1, 0x00);

    ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd1, res);

    uint8_t PICC_E_RndB[8];
    memcpy (PICC_E_RndB, res+1, 8);

    uint8_t PICC_RndB[8];
    memcpy (PICC_RndB, PICC_E_RndB, 8);
    uint8_t ivect[8];
    memset (ivect, '\0', sizeof (ivect));
    mifare_cypher_single_block (key, PICC_RndB, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);

    uint8_t PCD_RndA[8];
    DES_random_key ((DES_cblock*)&PCD_RndA);

    uint8_t PCD_r_RndB[8];
    memcpy (PCD_r_RndB, PICC_RndB, 8);
    rol (PCD_r_RndB, 8);

    uint8_t token[16];
    memcpy (token, PCD_RndA, 8);
    memcpy (token+8, PCD_r_RndB, 8);
    size_t offset = 0;

    while (offset < 16) {
	mifare_cypher_single_block (key, token + offset, ivect, MCD_SEND, MCO_ENCYPHER, 8);
	offset += 8;
    }

    BUFFER_INIT (cmd2, 17);

    BUFFER_APPEND (cmd2, 0xAF);
    BUFFER_APPEND_BYTES (cmd2, token, 16);

    ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd2, res);

    uint8_t PICC_E_RndA_s[8];
    memcpy (PICC_E_RndA_s, res+1, 8);

    uint8_t PICC_RndA_s[8];
    memcpy (PICC_RndA_s, PICC_E_RndA_s, 8);
    mifare_cypher_single_block (key, PICC_RndA_s, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);

    uint8_t PCD_RndA_s[8];
    memcpy (PCD_RndA_s, PCD_RndA, 8);
    rol (PCD_RndA_s, 8);

    if (0 != memcmp (PCD_RndA_s, PICC_RndA_s, 8)) {
	return -1;
    }
    // XXX Should we store the state "authenticated" in the tag struct??
    return 0;
}
Beispiel #25
0
/* Since auth_info structures contain malloced data, this function
 * is required in order to pack these structures in a vector in
 * order to store them to the DB.
 *
 * packed_session will contain the session data.
 *
 * The data will be in a platform independent format.
 */
int
_gnutls_session_pack (gnutls_session_t session,
                      gnutls_datum_t * packed_session)
{
  int ret;
  gnutls_buffer_st sb;
  opaque id;

  if (packed_session == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  _gnutls_buffer_init (&sb);

  id = gnutls_auth_get_type (session);
  BUFFER_APPEND (&sb, &id, 1);

  switch (id)
    {
#ifdef ENABLE_SRP
    case GNUTLS_CRD_SRP:
      ret = pack_srp_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
#ifdef ENABLE_PSK
    case GNUTLS_CRD_PSK:
      ret = pack_psk_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
#ifdef ENABLE_ANON
    case GNUTLS_CRD_ANON:
      ret = pack_anon_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
    case GNUTLS_CRD_CERTIFICATE:
      ret = pack_certificate_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
    default:
      return GNUTLS_E_INTERNAL_ERROR;

    }

  /* Auth_info structures copied. Now copy security_parameters_st. 
   * packed_session must have allocated space for the security parameters.
   */
  ret = pack_security_parameters (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_buffer_clear (&sb);
      return ret;
    }

  ret = _gnutls_ext_pack (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_buffer_clear (&sb);
      return ret;
    }

  ret = _gnutls_buffer_to_datum (&sb, packed_session);

  return ret;
}
Beispiel #26
0
/* Format: 
 *      4 bytes the total security data size
 *      1 byte the entity type (client/server)
 *      1 byte the key exchange algorithm used
 *      1 byte the read cipher algorithm
 *      1 byte the read mac algorithm
 *      1 byte the read compression algorithm
 *
 *      1 byte the write cipher algorithm
 *      1 byte the write mac algorithm
 *      1 byte the write compression algorithm
 *
 *      1 byte the certificate type
 *      1 byte the protocol version
 *
 *      2 bytes the cipher suite
 *
 *      48 bytes the master secret
 *
 *      32 bytes the client random
 *      32 bytes the server random
 *
 *      1 byte the session ID size
 *      x bytes the session ID (32 bytes max)
 *
 *      4 bytes a timestamp
 *            -------------------
 *                MAX: 165 bytes
 *
 */
static int
pack_security_parameters (gnutls_session_t session, gnutls_buffer_st * ps)
{

  int ret;
  int size_offset;
  size_t cur_size;
  record_parameters_st *params;

  if (session->security_parameters.epoch_read
      != session->security_parameters.epoch_write)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &params);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* move after the auth info stuff.
   */
  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;


  BUFFER_APPEND (ps, &session->security_parameters.entity, 1);
  BUFFER_APPEND (ps, &session->security_parameters.kx_algorithm, 1);
  BUFFER_APPEND (ps,
                 &session->security_parameters.current_cipher_suite.suite[0],
                 1);
  BUFFER_APPEND (ps,
                 &session->security_parameters.current_cipher_suite.suite[1],
                 1);
  BUFFER_APPEND (ps, &params->compression_algorithm, 1);
  BUFFER_APPEND (ps, &session->security_parameters.cert_type, 1);
  BUFFER_APPEND (ps, &session->security_parameters.version, 1);

  BUFFER_APPEND (ps, session->security_parameters.master_secret,
                 GNUTLS_MASTER_SIZE);
  BUFFER_APPEND (ps, session->security_parameters.client_random,
                 GNUTLS_RANDOM_SIZE);
  BUFFER_APPEND (ps, session->security_parameters.server_random,
                 GNUTLS_RANDOM_SIZE);

  BUFFER_APPEND_NUM (ps, session->security_parameters.session_id_size);
  BUFFER_APPEND (ps, session->security_parameters.session_id,
                 session->security_parameters.session_id_size);

  BUFFER_APPEND_NUM (ps, session->security_parameters.max_record_send_size);
  BUFFER_APPEND_NUM (ps, session->security_parameters.max_record_recv_size);
  BUFFER_APPEND_NUM (ps, session->security_parameters.timestamp);

  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
Beispiel #27
0
int
mifare_desfire_authenticate (MifareTag tag, uint8_t key_no, MifareDESFireKey key)
{
    ASSERT_ACTIVE (tag);
    ASSERT_MIFARE_DESFIRE (tag);

    MIFARE_DESFIRE (tag)->last_picc_error = OPERATION_OK;

    MIFARE_DESFIRE (tag)->authenticated_key_no = NOT_YET_AUTHENTICATED;
    free (MIFARE_DESFIRE (tag)->session_key);
    MIFARE_DESFIRE (tag)->session_key = NULL;

    BUFFER_INIT (cmd1, 2);
    BUFFER_INIT (res, 9);

    BUFFER_APPEND (cmd1, 0x0A);
    BUFFER_APPEND (cmd1, key_no);

    DESFIRE_TRANSCEIVE (tag, cmd1, res);

    uint8_t PICC_E_RndB[8];
    memcpy (PICC_E_RndB, res+1, 8);

    uint8_t PICC_RndB[8];
    memcpy (PICC_RndB, PICC_E_RndB, 8);
    mifare_cbc_des (key, PICC_RndB, 8, MD_RECEIVE, 0);

    uint8_t PCD_RndA[8];
    DES_random_key ((DES_cblock*)&PCD_RndA);

    uint8_t PCD_r_RndB[8];
    memcpy (PCD_r_RndB, PICC_RndB, 8);
    rol8 (PCD_r_RndB);

    uint8_t token[16];
    memcpy (token, PCD_RndA, 8);
    memcpy (token+8, PCD_r_RndB, 8);

    mifare_cbc_des (key, token, 16, MD_SEND, 0);

    BUFFER_INIT (cmd2, 17);

    BUFFER_APPEND (cmd2, 0xAF);
    BUFFER_APPEND_BYTES (cmd2, token, 16);

    DESFIRE_TRANSCEIVE (tag, cmd2, res);

    uint8_t PICC_E_RndA_s[8];
    memcpy (PICC_E_RndA_s, res+1, 8);

    uint8_t PICC_RndA_s[8];
    memcpy (PICC_RndA_s, PICC_E_RndA_s, 8);
    mifare_cbc_des (key, PICC_RndA_s, 8, MD_RECEIVE, 0);

    uint8_t PCD_RndA_s[8];
    memcpy (PCD_RndA_s, PCD_RndA, 8);
    rol8 (PCD_RndA_s);


    if (0 != memcmp (PCD_RndA_s, PICC_RndA_s, 8)) {
	    printf ("PCD_RndA_s != PICC_RndA_s");
		return -1;
    }

    MIFARE_DESFIRE (tag)->authenticated_key_no = key_no;
    MIFARE_DESFIRE (tag)->session_key = mifare_desfire_session_key_new (PCD_RndA, PICC_RndB, key);

    return 0;
}