Mifare dictionary attack performance improvements. (#2173)
* NFC dictionary attack performance improvements. * Remove unnecessary assignment
This commit is contained in:
		
							parent
							
								
									ea054423b0
								
							
						
					
					
						commit
						26e5527a93
					
				| @ -1854,6 +1854,7 @@ Function,+,menu_set_selected_item,void,"Menu*, uint32_t" | |||||||
| Function,-,mf_classic_auth_attempt,_Bool,"FuriHalNfcTxRxContext*, MfClassicAuthContext*, uint64_t" | Function,-,mf_classic_auth_attempt,_Bool,"FuriHalNfcTxRxContext*, MfClassicAuthContext*, uint64_t" | ||||||
| Function,-,mf_classic_auth_init_context,void,"MfClassicAuthContext*, uint8_t" | Function,-,mf_classic_auth_init_context,void,"MfClassicAuthContext*, uint8_t" | ||||||
| Function,-,mf_classic_authenticate,_Bool,"FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey" | Function,-,mf_classic_authenticate,_Bool,"FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey" | ||||||
|  | Function,-,mf_classic_authenticate_skip_activate,_Bool,"FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey, _Bool, uint32_t" | ||||||
| Function,-,mf_classic_check_card_type,_Bool,"uint8_t, uint8_t, uint8_t" | Function,-,mf_classic_check_card_type,_Bool,"uint8_t, uint8_t, uint8_t" | ||||||
| Function,-,mf_classic_dict_add_key,_Bool,"MfClassicDict*, uint8_t*" | Function,-,mf_classic_dict_add_key,_Bool,"MfClassicDict*, uint8_t*" | ||||||
| Function,-,mf_classic_dict_add_key_str,_Bool,"MfClassicDict*, FuriString*" | Function,-,mf_classic_dict_add_key_str,_Bool,"MfClassicDict*, FuriString*" | ||||||
|  | |||||||
| 
 | 
| @ -680,13 +680,15 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { | |||||||
|                 nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context); |                 nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context); | ||||||
|             } |             } | ||||||
|             furi_hal_nfc_sleep(); |             furi_hal_nfc_sleep(); | ||||||
|             if(furi_hal_nfc_activate_nfca(200, NULL)) { |             uint32_t cuid; | ||||||
|                 furi_hal_nfc_sleep(); |             if(furi_hal_nfc_activate_nfca(200, &cuid)) { | ||||||
|  |                 bool deactivated = false; | ||||||
|                 if(!card_found_notified) { |                 if(!card_found_notified) { | ||||||
|                     nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); |                     nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); | ||||||
|                     card_found_notified = true; |                     card_found_notified = true; | ||||||
|                     card_removed_notified = false; |                     card_removed_notified = false; | ||||||
|                     nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i); |                     nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i); | ||||||
|  |                     deactivated = true; | ||||||
|                 } |                 } | ||||||
|                 FURI_LOG_D( |                 FURI_LOG_D( | ||||||
|                     TAG, |                     TAG, | ||||||
| @ -696,22 +698,26 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { | |||||||
|                     (uint32_t)key); |                     (uint32_t)key); | ||||||
|                 if(!is_key_a_found) { |                 if(!is_key_a_found) { | ||||||
|                     is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); |                     is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); | ||||||
|                     if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyA)) { |                     if(mf_classic_authenticate_skip_activate( | ||||||
|  |                            &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) { | ||||||
|                         mf_classic_set_key_found(data, i, MfClassicKeyA, key); |                         mf_classic_set_key_found(data, i, MfClassicKeyA, key); | ||||||
|                         FURI_LOG_D(TAG, "Key found"); |                         FURI_LOG_D(TAG, "Key found"); | ||||||
|                         nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); |                         nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); | ||||||
|                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); |                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); | ||||||
|                     } |                     } | ||||||
|                     furi_hal_nfc_sleep(); |                     furi_hal_nfc_sleep(); | ||||||
|  |                     deactivated = true; | ||||||
|                 } |                 } | ||||||
|                 if(!is_key_b_found) { |                 if(!is_key_b_found) { | ||||||
|                     is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); |                     is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); | ||||||
|                     if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyB)) { |                     if(mf_classic_authenticate_skip_activate( | ||||||
|  |                            &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { | ||||||
|                         FURI_LOG_D(TAG, "Key found"); |                         FURI_LOG_D(TAG, "Key found"); | ||||||
|                         mf_classic_set_key_found(data, i, MfClassicKeyB, key); |                         mf_classic_set_key_found(data, i, MfClassicKeyB, key); | ||||||
|                         nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); |                         nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); | ||||||
|                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); |                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); | ||||||
|                     } |                     } | ||||||
|  |                     deactivated = true; | ||||||
|                 } |                 } | ||||||
|                 if(is_key_a_found && is_key_b_found) break; |                 if(is_key_a_found && is_key_b_found) break; | ||||||
|                 if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; |                 if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; | ||||||
|  | |||||||
| @ -403,15 +403,16 @@ static bool mf_classic_auth( | |||||||
|     uint32_t block, |     uint32_t block, | ||||||
|     uint64_t key, |     uint64_t key, | ||||||
|     MfClassicKey key_type, |     MfClassicKey key_type, | ||||||
|     Crypto1* crypto) { |     Crypto1* crypto, | ||||||
|  |     bool skip_activate, | ||||||
|  |     uint32_t cuid) { | ||||||
|     bool auth_success = false; |     bool auth_success = false; | ||||||
|     uint32_t cuid = 0; |  | ||||||
|     memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data)); |     memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data)); | ||||||
|     memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity)); |     memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity)); | ||||||
|     tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; |     tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         if(!furi_hal_nfc_activate_nfca(200, &cuid)) break; |         if(!skip_activate && !furi_hal_nfc_activate_nfca(200, &cuid)) break; | ||||||
|         if(key_type == MfClassicKeyA) { |         if(key_type == MfClassicKeyA) { | ||||||
|             tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_A_CMD; |             tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_A_CMD; | ||||||
|         } else { |         } else { | ||||||
| @ -460,7 +461,23 @@ bool mf_classic_authenticate( | |||||||
|     furi_assert(tx_rx); |     furi_assert(tx_rx); | ||||||
| 
 | 
 | ||||||
|     Crypto1 crypto = {}; |     Crypto1 crypto = {}; | ||||||
|     bool key_found = mf_classic_auth(tx_rx, block_num, key, key_type, &crypto); |     bool key_found = mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0); | ||||||
|  |     furi_hal_nfc_sleep(); | ||||||
|  |     return key_found; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool mf_classic_authenticate_skip_activate( | ||||||
|  |     FuriHalNfcTxRxContext* tx_rx, | ||||||
|  |     uint8_t block_num, | ||||||
|  |     uint64_t key, | ||||||
|  |     MfClassicKey key_type, | ||||||
|  |     bool skip_activate, | ||||||
|  |     uint32_t cuid) { | ||||||
|  |     furi_assert(tx_rx); | ||||||
|  | 
 | ||||||
|  |     Crypto1 crypto = {}; | ||||||
|  |     bool key_found = | ||||||
|  |         mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, skip_activate, cuid); | ||||||
|     furi_hal_nfc_sleep(); |     furi_hal_nfc_sleep(); | ||||||
|     return key_found; |     return key_found; | ||||||
| } | } | ||||||
| @ -483,7 +500,9 @@ bool mf_classic_auth_attempt( | |||||||
|                mf_classic_get_first_block_num_of_sector(auth_ctx->sector), |                mf_classic_get_first_block_num_of_sector(auth_ctx->sector), | ||||||
|                key, |                key, | ||||||
|                MfClassicKeyA, |                MfClassicKeyA, | ||||||
|                &crypto)) { |                &crypto, | ||||||
|  |                false, | ||||||
|  |                0)) { | ||||||
|             auth_ctx->key_a = key; |             auth_ctx->key_a = key; | ||||||
|             found_key = true; |             found_key = true; | ||||||
|         } |         } | ||||||
| @ -500,7 +519,9 @@ bool mf_classic_auth_attempt( | |||||||
|                mf_classic_get_first_block_num_of_sector(auth_ctx->sector), |                mf_classic_get_first_block_num_of_sector(auth_ctx->sector), | ||||||
|                key, |                key, | ||||||
|                MfClassicKeyB, |                MfClassicKeyB, | ||||||
|                &crypto)) { |                &crypto, | ||||||
|  |                false, | ||||||
|  |                0)) { | ||||||
|             auth_ctx->key_b = key; |             auth_ctx->key_b = key; | ||||||
|             found_key = true; |             found_key = true; | ||||||
|         } |         } | ||||||
| @ -568,7 +589,7 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u | |||||||
|         if(!key_a_found) break; |         if(!key_a_found) break; | ||||||
|         FURI_LOG_D(TAG, "Try to read blocks with key A"); |         FURI_LOG_D(TAG, "Try to read blocks with key A"); | ||||||
|         key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a)); |         key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a)); | ||||||
|         if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto)) break; |         if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto, false, 0)) break; | ||||||
|         for(size_t i = start_block; i < start_block + total_blocks; i++) { |         for(size_t i = start_block; i < start_block + total_blocks; i++) { | ||||||
|             if(!mf_classic_is_block_read(data, i)) { |             if(!mf_classic_is_block_read(data, i)) { | ||||||
|                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { |                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { | ||||||
| @ -587,7 +608,7 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u | |||||||
|         FURI_LOG_D(TAG, "Try to read blocks with key B"); |         FURI_LOG_D(TAG, "Try to read blocks with key B"); | ||||||
|         key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b)); |         key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b)); | ||||||
|         furi_hal_nfc_sleep(); |         furi_hal_nfc_sleep(); | ||||||
|         if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto)) break; |         if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) break; | ||||||
|         for(size_t i = start_block; i < start_block + total_blocks; i++) { |         for(size_t i = start_block; i < start_block + total_blocks; i++) { | ||||||
|             if(!mf_classic_is_block_read(data, i)) { |             if(!mf_classic_is_block_read(data, i)) { | ||||||
|                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { |                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { | ||||||
| @ -631,7 +652,7 @@ static bool mf_classic_read_sector_with_reader( | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Auth to first block in sector
 |         // Auth to first block in sector
 | ||||||
|         if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto)) { |         if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto, false, 0)) { | ||||||
|             // Set key to MF_CLASSIC_NO_KEY to prevent further attempts
 |             // Set key to MF_CLASSIC_NO_KEY to prevent further attempts
 | ||||||
|             if(key_type == MfClassicKeyA) { |             if(key_type == MfClassicKeyA) { | ||||||
|                 sector_reader->key_a = MF_CLASSIC_NO_KEY; |                 sector_reader->key_a = MF_CLASSIC_NO_KEY; | ||||||
| @ -961,7 +982,7 @@ bool mf_classic_write_block( | |||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         furi_hal_nfc_sleep(); |         furi_hal_nfc_sleep(); | ||||||
|         if(!mf_classic_auth(tx_rx, block_num, key, key_type, &crypto)) { |         if(!mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0)) { | ||||||
|             FURI_LOG_D(TAG, "Auth fail"); |             FURI_LOG_D(TAG, "Auth fail"); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -156,6 +156,14 @@ bool mf_classic_authenticate( | |||||||
|     uint64_t key, |     uint64_t key, | ||||||
|     MfClassicKey key_type); |     MfClassicKey key_type); | ||||||
| 
 | 
 | ||||||
|  | bool mf_classic_authenticate_skip_activate( | ||||||
|  |     FuriHalNfcTxRxContext* tx_rx, | ||||||
|  |     uint8_t block_num, | ||||||
|  |     uint64_t key, | ||||||
|  |     MfClassicKey key_type, | ||||||
|  |     bool skip_activate, | ||||||
|  |     uint32_t cuid); | ||||||
|  | 
 | ||||||
| bool mf_classic_auth_attempt( | bool mf_classic_auth_attempt( | ||||||
|     FuriHalNfcTxRxContext* tx_rx, |     FuriHalNfcTxRxContext* tx_rx, | ||||||
|     MfClassicAuthContext* auth_ctx, |     MfClassicAuthContext* auth_ctx, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Thomas Roth
						Thomas Roth