NFC: fix creating MF Classic tags from "Add Manually" menu (BCC calulation and ATQA/SAK writing) (#2342)
* NFC: fix creating MF Classic cards from "Add Manually" menu (BCC calculation and AQTA/SAK writing) * NFC: Fix BCC/SAK/ATQA in unit_tests and SAK in nfc_generate_mf_classic Co-authored-by: gornekich <n.gorbadey@gmail.com>
This commit is contained in:
		
							parent
							
								
									01a9854f8a
								
							
						
					
					
						commit
						46fb86265c
					
				| @ -348,13 +348,37 @@ static void mf_classic_generator_test(uint8_t uid_len, MfClassicType type) { | |||||||
|     memcpy(atqa, nfc_dev->dev_data.nfc_data.atqa, 2); |     memcpy(atqa, nfc_dev->dev_data.nfc_data.atqa, 2); | ||||||
| 
 | 
 | ||||||
|     MfClassicData* mf_data = &nfc_dev->dev_data.mf_classic_data; |     MfClassicData* mf_data = &nfc_dev->dev_data.mf_classic_data; | ||||||
|     // Check the manufacturer block (should be uid[uid_len] + 0xFF[rest])
 |     // Check the manufacturer block (should be uid[uid_len] + BCC (for 4byte only) + SAK + ATQA0 + ATQA1 + 0xFF[rest])
 | ||||||
|     uint8_t manufacturer_block[16] = {0}; |     uint8_t manufacturer_block[16] = {0}; | ||||||
|     memcpy(manufacturer_block, nfc_dev->dev_data.mf_classic_data.block[0].value, 16); |     memcpy(manufacturer_block, nfc_dev->dev_data.mf_classic_data.block[0].value, 16); | ||||||
|     mu_assert( |     mu_assert( | ||||||
|         memcmp(manufacturer_block, uid, uid_len) == 0, |         memcmp(manufacturer_block, uid, uid_len) == 0, | ||||||
|         "manufacturer_block uid doesn't match the file\r\n"); |         "manufacturer_block uid doesn't match the file\r\n"); | ||||||
|     for(uint8_t i = uid_len; i < 16; i++) { | 
 | ||||||
|  |     uint8_t position = 0; | ||||||
|  |     if(uid_len == 4) { | ||||||
|  |         position = uid_len; | ||||||
|  | 
 | ||||||
|  |         uint8_t bcc = 0; | ||||||
|  | 
 | ||||||
|  |         for(int i = 0; i < uid_len; i++) { | ||||||
|  |             bcc ^= uid[i]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         mu_assert(manufacturer_block[position] == bcc, "manufacturer_block bcc assert failed\r\n"); | ||||||
|  |     } else { | ||||||
|  |         position = uid_len - 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     mu_assert(manufacturer_block[position + 1] == sak, "manufacturer_block sak assert failed\r\n"); | ||||||
|  | 
 | ||||||
|  |     mu_assert( | ||||||
|  |         manufacturer_block[position + 2] == atqa[0], "manufacturer_block atqa0 assert failed\r\n"); | ||||||
|  | 
 | ||||||
|  |     mu_assert( | ||||||
|  |         manufacturer_block[position + 3] == atqa[1], "manufacturer_block atqa1 assert failed\r\n"); | ||||||
|  | 
 | ||||||
|  |     for(uint8_t i = position + 4; i < 16; i++) { | ||||||
|         mu_assert( |         mu_assert( | ||||||
|             manufacturer_block[i] == 0xFF, "manufacturer_block[i] == 0xFF assert failed\r\n"); |             manufacturer_block[i] == 0xFF, "manufacturer_block[i] == 0xFF assert failed\r\n"); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -30,12 +30,32 @@ static void nfc_generate_mf_classic_uid(uint8_t* uid, uint8_t length) { | |||||||
|     furi_hal_random_fill_buf(&uid[1], length - 1); |     furi_hal_random_fill_buf(&uid[1], length - 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void nfc_generate_mf_classic_block_0(uint8_t* block, uint8_t uid_len) { | static void nfc_generate_mf_classic_block_0( | ||||||
|  |     uint8_t* block, | ||||||
|  |     uint8_t uid_len, | ||||||
|  |     uint8_t sak, | ||||||
|  |     uint8_t atqa0, | ||||||
|  |     uint8_t atqa1) { | ||||||
|     // Block length is always 16 bytes, and the UID can be either 4 or 7 bytes
 |     // Block length is always 16 bytes, and the UID can be either 4 or 7 bytes
 | ||||||
|     furi_assert(uid_len == 4 || uid_len == 7); |     furi_assert(uid_len == 4 || uid_len == 7); | ||||||
|     furi_assert(block); |     furi_assert(block); | ||||||
|     nfc_generate_mf_classic_uid(block, uid_len); | 
 | ||||||
|     for(int i = uid_len; i < 16; i++) { |     if(uid_len == 4) { | ||||||
|  |         // Calculate BCC
 | ||||||
|  |         block[uid_len] = 0; | ||||||
|  | 
 | ||||||
|  |         for(int i = 0; i < uid_len; i++) { | ||||||
|  |             block[uid_len] ^= block[i]; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         uid_len -= 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     block[uid_len + 1] = sak; | ||||||
|  |     block[uid_len + 2] = atqa0; | ||||||
|  |     block[uid_len + 3] = atqa1; | ||||||
|  | 
 | ||||||
|  |     for(int i = uid_len + 4; i < 16; i++) { | ||||||
|         block[i] = 0xFF; |         block[i] = 0xFF; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -74,7 +94,6 @@ static void | |||||||
|     data->nfc_data.type = FuriHalNfcTypeA; |     data->nfc_data.type = FuriHalNfcTypeA; | ||||||
|     data->nfc_data.interface = FuriHalNfcInterfaceRf; |     data->nfc_data.interface = FuriHalNfcInterfaceRf; | ||||||
|     data->nfc_data.uid_len = uid_len; |     data->nfc_data.uid_len = uid_len; | ||||||
|     nfc_generate_mf_classic_block_0(data->mf_classic_data.block[0].value, uid_len); |  | ||||||
|     data->nfc_data.atqa[0] = 0x44; |     data->nfc_data.atqa[0] = 0x44; | ||||||
|     data->nfc_data.atqa[1] = 0x00; |     data->nfc_data.atqa[1] = 0x00; | ||||||
|     data->nfc_data.sak = 0x08; |     data->nfc_data.sak = 0x08; | ||||||
| @ -316,6 +335,7 @@ static void nfc_generate_ntag_i2c_plus_2k(NfcDeviceData* data) { | |||||||
| 
 | 
 | ||||||
| void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { | void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { | ||||||
|     nfc_generate_common_start(data); |     nfc_generate_common_start(data); | ||||||
|  |     nfc_generate_mf_classic_uid(data->mf_classic_data.block[0].value, uid_len); | ||||||
|     nfc_generate_mf_classic_common(data, uid_len, type); |     nfc_generate_mf_classic_common(data, uid_len, type); | ||||||
| 
 | 
 | ||||||
|     // Set the UID
 |     // Set the UID
 | ||||||
| @ -339,7 +359,6 @@ void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType | |||||||
|         } |         } | ||||||
|         // Set SAK to 18
 |         // Set SAK to 18
 | ||||||
|         data->nfc_data.sak = 0x18; |         data->nfc_data.sak = 0x18; | ||||||
| 
 |  | ||||||
|     } else if(type == MfClassicType1k) { |     } else if(type == MfClassicType1k) { | ||||||
|         // Set every block to 0xFF
 |         // Set every block to 0xFF
 | ||||||
|         for(uint16_t i = 1; i < MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4; i += 1) { |         for(uint16_t i = 1; i < MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4; i += 1) { | ||||||
| @ -366,6 +385,13 @@ void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType | |||||||
|         data->nfc_data.sak = 0x09; |         data->nfc_data.sak = 0x09; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     nfc_generate_mf_classic_block_0( | ||||||
|  |         data->mf_classic_data.block[0].value, | ||||||
|  |         uid_len, | ||||||
|  |         data->nfc_data.sak, | ||||||
|  |         data->nfc_data.atqa[0], | ||||||
|  |         data->nfc_data.atqa[1]); | ||||||
|  | 
 | ||||||
|     mfc->type = type; |     mfc->type = type; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 AloneLiberty
						AloneLiberty