@@ -165,7 +165,7 @@ ReturnCode picopass_detect_card(int timeout) {
165
165
return ERR_NONE ;
166
166
}
167
167
168
- ReturnCode picopass_read_card (ApplicationArea * AA1 ) {
168
+ ReturnCode picopass_read_card (PicopassBlock * AA1 ) {
169
169
rfalPicoPassIdentifyRes idRes ;
170
170
rfalPicoPassSelectRes selRes ;
171
171
rfalPicoPassReadCheckRes rcRes ;
@@ -205,10 +205,20 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) {
205
205
return err ;
206
206
}
207
207
208
- for (size_t i = 0 ; i < 4 ; i ++ ) {
209
- FURI_LOG_D (TAG , "rfalPicoPassPollerReadBlock block %d" , i + 6 );
208
+ rfalPicoPassReadBlockRes csn ;
209
+ err = rfalPicoPassPollerReadBlock (PICOPASS_CSN_BLOCK_INDEX , & csn );
210
+ memcpy (AA1 [PICOPASS_CSN_BLOCK_INDEX ].data , csn .data , sizeof (csn .data ));
211
+
212
+ rfalPicoPassReadBlockRes cfg ;
213
+ err = rfalPicoPassPollerReadBlock (PICOPASS_CONFIG_BLOCK_INDEX , & cfg );
214
+ memcpy (AA1 [PICOPASS_CONFIG_BLOCK_INDEX ].data , cfg .data , sizeof (cfg .data ));
215
+
216
+ size_t app_limit = cfg .data [0 ] < PICOPASS_MAX_APP_LIMIT ? cfg .data [0 ] : PICOPASS_MAX_APP_LIMIT ;
217
+
218
+ for (size_t i = 2 ; i < app_limit ; i ++ ) {
219
+ FURI_LOG_D (TAG , "rfalPicoPassPollerReadBlock block %d" , i );
210
220
rfalPicoPassReadBlockRes block ;
211
- err = rfalPicoPassPollerReadBlock (i + 6 , & block );
221
+ err = rfalPicoPassPollerReadBlock (i , & block );
212
222
if (err != ERR_NONE ) {
213
223
FURI_LOG_E (TAG , "rfalPicoPassPollerReadBlock error %d" , err );
214
224
return err ;
@@ -217,7 +227,7 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) {
217
227
FURI_LOG_D (
218
228
TAG ,
219
229
"rfalPicoPassPollerReadBlock %d %02x%02x%02x%02x%02x%02x%02x%02x" ,
220
- i + 6 ,
230
+ i ,
221
231
block .data [0 ],
222
232
block .data [1 ],
223
233
block .data [2 ],
@@ -227,7 +237,7 @@ ReturnCode picopass_read_card(ApplicationArea* AA1) {
227
237
block .data [6 ],
228
238
block .data [7 ]);
229
239
230
- memcpy (& ( AA1 -> block [i ]), & block , sizeof (block ));
240
+ memcpy (AA1 [i ]. data , block . data , sizeof (block . data ));
231
241
}
232
242
233
243
return ERR_NONE ;
@@ -251,7 +261,7 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) {
251
261
picopass_device_data_clear (picopass_worker -> dev_data );
252
262
PicopassDeviceData * dev_data = picopass_worker -> dev_data ;
253
263
254
- ApplicationArea * AA1 = & dev_data -> AA1 ;
264
+ PicopassBlock * AA1 = dev_data -> AA1 ;
255
265
PicopassPacs * pacs = & dev_data -> pacs ;
256
266
ReturnCode err ;
257
267
@@ -263,34 +273,39 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) {
263
273
FURI_LOG_E (TAG , "picopass_read_card error %d" , err );
264
274
}
265
275
266
- pacs -> biometrics = AA1 -> block [0 ].data [4 ];
267
- pacs -> encryption = AA1 -> block [0 ].data [7 ];
276
+ // Thank you proxmark!
277
+ pacs -> legacy = (memcmp (AA1 [5 ].data , "\xff\xff\xff\xff\xff\xff\xff\xff" , 8 ) == 0 );
278
+ pacs -> se_enabled = (memcmp (AA1 [5 ].data , "\xff\xff\xff\x00\x06\xff\xff\xff" , 8 ) == 0 );
279
+
280
+ pacs -> biometrics = AA1 [6 ].data [4 ];
281
+ pacs -> pin_length = AA1 [6 ].data [6 ] & 0x0F ;
282
+ pacs -> encryption = AA1 [6 ].data [7 ];
268
283
269
- if (pacs -> encryption == 0x17 ) {
284
+ if (pacs -> encryption == PicopassDeviceEncryption3DES ) {
270
285
FURI_LOG_D (TAG , "3DES Encrypted" );
271
- err = picopass_worker_decrypt (AA1 -> block [ 1 ].data , pacs -> credential );
286
+ err = picopass_worker_decrypt (AA1 [ 7 ].data , pacs -> credential );
272
287
if (err != ERR_NONE ) {
273
288
FURI_LOG_E (TAG , "decrypt error %d" , err );
274
289
break ;
275
290
}
276
291
277
- err = picopass_worker_decrypt (AA1 -> block [ 2 ].data , pacs -> pin0 );
292
+ err = picopass_worker_decrypt (AA1 [ 8 ].data , pacs -> pin0 );
278
293
if (err != ERR_NONE ) {
279
294
FURI_LOG_E (TAG , "decrypt error %d" , err );
280
295
break ;
281
296
}
282
297
283
- err = picopass_worker_decrypt (AA1 -> block [ 3 ].data , pacs -> pin1 );
298
+ err = picopass_worker_decrypt (AA1 [ 9 ].data , pacs -> pin1 );
284
299
if (err != ERR_NONE ) {
285
300
FURI_LOG_E (TAG , "decrypt error %d" , err );
286
301
break ;
287
302
}
288
- } else if (pacs -> encryption == 0x14 ) {
303
+ } else if (pacs -> encryption == PicopassDeviceEncryptionNone ) {
289
304
FURI_LOG_D (TAG , "No Encryption" );
290
- memcpy (pacs -> credential , AA1 -> block [ 1 ].data , RFAL_PICOPASS_MAX_BLOCK_LEN );
291
- memcpy (pacs -> pin0 , AA1 -> block [ 2 ].data , RFAL_PICOPASS_MAX_BLOCK_LEN );
292
- memcpy (pacs -> pin1 , AA1 -> block [ 3 ].data , RFAL_PICOPASS_MAX_BLOCK_LEN );
293
- } else if (pacs -> encryption == 0x15 ) {
305
+ memcpy (pacs -> credential , AA1 [ 7 ].data , PICOPASS_BLOCK_LEN );
306
+ memcpy (pacs -> pin0 , AA1 [ 8 ].data , PICOPASS_BLOCK_LEN );
307
+ memcpy (pacs -> pin1 , AA1 [ 9 ].data , PICOPASS_BLOCK_LEN );
308
+ } else if (pacs -> encryption == PicopassDeviceEncryptionDES ) {
294
309
FURI_LOG_D (TAG , "DES Encrypted" );
295
310
} else {
296
311
FURI_LOG_D (TAG , "Unknown encryption" );
0 commit comments