-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix NFC presence timeout in Android 13+ #52
base: community
Are you sure you want to change the base?
Fix NFC presence timeout in Android 13+ #52
Conversation
Thank you very much for this. We already investigate your solution internally. |
Thank you very much again. Your idea helped us to understand a bug we had with the Fairphone 3 a lot better. When the Fairphone 3 got an update from Android 11 (8901.4.A...) to Android 13 (6.A...) some id cards no longer worked because of the problem you noticed. It looks like that only some older id cards are affected. LineageOS has exactly the same behavior on the Fairphone 3. After a lot of communication with the Fairphone 3 Team (Thank you very much again) Android 13 started to work again with Version 6.A.028... The Problem was a change of the NFC package. For Android 11 they used "NQNfcNci" (from NXP/Qualcomm). But this package has no official support for Android 13 so they replaced it with "NfcNci" (from AOSP). After porting NQNfcNci to Android 13 by themself everything works fine again. So it looks like a bug in "NfcNci" and maybe LineageOS should go the same way and use "NQNfcNci". We can also confirm that a presence check delay of 1000ms helps to get old id cards working again with 6.A.025... which is using "NfcNci". When we try to understand the situation it also makes sense: When there is a transaction with an explicit transmit timeout of 1 or 2 seconds, the presence check should not be interesting because the system should know there is probably a busy card. Nevertheless, we tried your idea on a Samsung S20 with Samsung Android. Sadly there is at least one reproducible negative effect, where removal of the id card is no longer detected after the third contact. Also the (now expected) delay of the removed card detection does not feel very well. So based on the current situation we would not like to accept your change. |
Very interesting observation. I suppose the ID cards use progressively newer chipsets (eg. the NXP P71D321) as they are issued each year, and older chipsets might be to slow to perform the key transformations in the default timeout window.
Thank you for the detailed explanation! This actually helps a lot. I will try to report the suggestion of using
I see your reasoning concerning the detrimental side effects. I did some testing on my side as well, The timeout can be reduced to 500 ms without loss of functionality on my device, which might help with the observed latency / sluggishness. However, I do not observe the card not working after the third contact, it works every time for me - not sure what is going on there, but I agree that this is not what you would want to deliver to your clients as a default experience. Maybe you want to consider a simple "compatibility switch" option in the app settings with a short explanation? My ID card is still valid for more than a year, it might take even longer until citizens have received faster cards. That option could then increase the timeout to 500 - 1000 ms, but would be disabled by default. You could even check for communication errors during the APDU transfer and suggest enabling this option to the user. Thank you for the transparency and research! |
Issue report in the LineageOS project: https://gitlab.com/LineageOS/issues/android/-/issues/7268 |
Backlink into related Fairphone support thread: https://forum.fairphone.com/t/nfc-ausweis-app-fehler-nach-pin-eingabe/105244/61?u=stargate01 |
The sources for our NQNfcNci repository can be found here: https://gerrit-public.fairphone.software/plugins/gitiles/platform/vendor/nxp/opensource/packages/apps/Nfc/+log/refs/tags/rel/13/fp3/6.A.028.1 (right now only this tag and the release branch are pushed there, hopefully There's also a few other relevant repositories (like |
We see you already found the right way and got feedback.
We had a discussion @ option like this before some years when we had a lot of problems with extended length. Sadly the cost-benefit ratio is to low and we need to set other priories. I am in the same situation, my id card is still valid for two years. |
To complete the technical situation and maybe help to find the bug we would like to add a hint: Maybe the EXTRA_READER_PRESENCE_CHECK_DELAY is not a problem while the card is busy. It looks like the way, "NfcNci" implements the presence check, destroys the secure messaging channel. The relevant part of the authentication with a german id card works as follows:
When the response from the server in 4. takes to long (> 125 milliseconds), the presence check becomes active and destroys the PACE channel. In general a PACE channel should be destroyed when a command was received not matching the current secure messaging channel. With a fast server this is not a problem. Please consider these statements as speculation based on some circumstantial evidence. |
Thanks for the information, this matches my observation in another place. I was trying to manage applets on some smartcards via GlobalPlatform, using the Fidesmo app. The same bug occurred there, specifically Looking at the log files, it appears that |
Is this Bug, why I always get? :
And no, I didnt remove the Card. (im also running lineage 13) Btw, why are Issues disabled? |
@snoweuph Yes, the app error you describe (see the attached screenshot) is caused by the connection terminating while the card is performing key computations, due to |
I found even more apps struggling with this issue (specifically Nect Wallet). This prompted me to finish up and publish an LSPosed module, which injects the NFC configuration fix into any selected apps at runtime. It is open source at https://github.com/StarGate01/NFCPresenceFix , downloads are available as well. I hope this helps affected LineageOS users. |
yea, exact Issue I got, thanks for your Work 👍 |
Thats awesome ,I gonna give it a test rn |
I also published my NfcNci Patience module after encountering this issue on several apps. The difference here compared to @StarGate01's module is that this module directly hooks into the "Nfc Service" ( |
@rmnscnce Great work! Your module works flawlessly! It is a lot better than mine, as it does not clash with Shamiko due to injecting directly into Android instead of the individual apps. Kudos! |
Thanks 😄 but my module would have never existed without your initial bug report, so kudos to you too for noticing (and reporting) the primary cause of this issue. |
This PR fixes a breaking bug which I encountered on my smartphone (Samsung Galaxy S10+, running Android 13, specifically LineageOS 20-20240402-microG-beyond2lte). The bug breaks the communication with the id card while the secure element in the card is still computing key transformations, because Android times out the NFC connection. This leads to a complete failure of functionality.
The core issue is that the Android API
NFCAdapter::enableReaderMode
[1] apparently had a subtle implementation change regarding the tag presence detection, sometime before or during Android 13 [2].Specifically, the mechanism how the Android OS detects the presence of a tag has been modified. Because different NFC chipsets and Android versions handle function differently, there is no real standard how presence detection should work [2]. Especially on Broadcom chips, these seem to be issues with how the
enableReaderMode
handles presence checks [4].The
EXTRA_READER_PRESENCE_CHECK_DELAY
configuration parameter [6] (which is passed via the Bundle configuration option inenableReaderMode
) controls the timeout after which the Android OS considers a tag as lost. By default, this is 125 (presumably milliseconds) [5]. This explains why I was observing OS-induced reconnection attempts in my logfiles, as a GlobalPlatform key transformation might take longer than 125 milliseconds. Apparently Android uses the timeout value set viaIsoDep::setTimeout
only for active communication, not for the automatic OS-level presence checks.The value of
1000
forEXTRA_READER_PRESENCE_CHECK_DELAY
translates to presumably one second. I am unsure if it would be wise to set this any higher, I fear the Android tag detection system might hang if the timeout is too long. One second works fine for my phone - you might want to test this on your side as well.This appears to be a general issue with the app and Android 13+ on select models, regardless of LineageOS or any other Android distribution.
[1] https://developer.android.com/reference/android/nfc/NfcAdapter#enableReaderMode(android.app.Activity,%20android.nfc.NfcAdapter.ReaderCallback,%20int,%20android.os.Bundle)
[2] https://community.st.com/t5/st25-nfc-rfid-tags-and-readers/what-is-the-difference-between-android-11-and-android-13-for-nfc/td-p/121846
[3] https://github.com/frankmorgner/vsmartcard/blob/master/remote-reader/app/src/main/java/com/vsmartcard/remotesmartcardreader/app/MainActivity.java#L163
[4] https://community.nxp.com/t5/NFC/Tranceive-method-throws-a-tag-lost-exception-only-for-specific/m-p/665270
[5] https://android.googlesource.com/platform/packages/apps/Nfc/+/master/src/com/android/nfc/NfcService.java#235
[6] https://developer.android.com/reference/android/nfc/NfcAdapter#EXTRA_READER_PRESENCE_CHECK_DELAY