The "kdf-setup" command introduced in GnuPG does set the KDF-DO (data object), but it does not set the admin and user PIN codes accordingly, as required by the OpenPGP specification (section 4.3.2 of the v3.3): "It is up to the terminal application to align all PWs and the KDF-DO with correct values, the functionality is transparent to the card."
My interpretation of the specification is different.
By requiring the condition of setting KDF-DO (it is only valid to setup KDF-DO when PINs are factory setting), Gnuk works well with current "kdf-setup".
If the procedure of setting KDF-DO includes multiple steps with KDF-DO update and PIN update, there is a risk of power down which results unusable card.
You are right about the fact that multiple steps could result in unusable cards in case of power down before all commands have been issued. Nevertheless, in practice, these commands would involve very few treatments on the token (i.e. no cryptographic operation or heavy data transfer) and it should really not take long to complete the three steps (admin PIN update, user PIN update, KDF-DO update).
Actually, when the current "kdf-setup" command is issued to any implementation that requires admin and user PIN codes do be updated accordingly by "the terminal", it already results in unusable tokens. The only token I have that supports KDF is a card with SmartPGP applet installed, which is following the specification strictly (i.e. "It is up to the terminal application to align all PWs and the KDF-DO with correct values.").
For the situation where PINs are not factory setting, given the specification, I don't know how to achieve "to align all PWs and the KDF-DO with correct values"; It might depend on card's implementation.
What I considered was:
- It would be possible for a card implementation to reset PINs to factory setting after the KDF-DO update. But this is not described explicitly in the specification.
- So, it makes sense for a card implementation only allows update of the KDF-DO when PINs are factory setting. <--- I did this.
- If we want to allow update of the KDF-DO when PINs are not factory setting, we have to define how to "align" things, adding detail in the specification. I think that we need to clarify semantics of changing PIN, old to new, how it's hashed or not. I have no concrete idea for this, and wonder if it's worth.
Do you have any specific suggestions?
Perhaps, I was so lazy (to modify the specification), and my tendency is like option (1) or (2).
Here is a sequence of operations/commands that permits to setup or update KDF-DO and align PIN codes accordingly:
- Ask the user for actual PIN codes (PW1, resetting code and PW3);
1bis. Derivate them if necessary according to the current KDF-DO of the card;
- Generate a new KDF-DO (as computed by the script in T3823) but do not put it on the card;
2bis. Derivate the PIN codes retrieved at step 1 with the new KDF-DO computed at step 2;
- VERIFY PW3;
3bis. Update the resetting code (if any) with PUT DATA where the data is the new resetting code computed at step 2bis;
- Update PW1 with CHANGE REFERENCE DATA where the <actual PIN> is the PIN computed at step 1bis and the <new PIN> is the PIN computed at step 2bis;
4bis. Idem with PW3.
- Update the KDF with PUT DATA where the data is the new KDF-DO computed at step 2
Steps 3 and 3bis are optional and must occur only if a resetting code is configured.
Some users of ours wanted to use KDF with their OpenPGP smart cards. Could you tell when solution to this issue could be expected?
Additionally, is there any workaround for the current state? Perhaps based on T3823, or on derived ? To which values the PINs had to be set?
I implemented the script described previsouly (https://dev.gnupg.org/T3891#114950) in the smartpgp-cli utility provided in the SmartPGP repository (see commit https://github.com/ANSSI-FR/SmartPGP/commit/4be0fa442b43c2bafd5f0171417ff68fd88cbe2d).
I can confirm this script correctly sets up KDF, at least with SmartPGP. After execution, the SmartPGP token is 100% functional with GnuPG (User PIN and Admin PIN verifications and changes are OK).
Thanks for concrete cases. Sorry, not responding earlier. It was an experimental feature, firstly only available in Gnuk Token.
Now, I have the card (V3.3) which I can test.
I'll support the feature by testing with the implementation.
I think that this is a problem of the interpretation of spec. Anyway, better support is needed.
@Amaud, I read your code in Python. IIUC, it asks users PW1, Reset Code, and PW3 to setup, just before registering KDF DO (as you describe in https://dev.gnupg.org/T3891#114950).
Doing same by gpg frontend would require some more user interaction changes (currently, it's scdaemon which initiates asking to user for authentication). It would be good if we can minimize complexity.
For the change of GnuPG, how about following?
- Get old KDF Data Object
- Generate a new KDF Data Object
- Ask the user about admin PIN (PW3)
- Verify PW3 with old setting of KDF
- Update PW3 with CHANGE REFERENCE DATA with new setting of KDF
- Update KDF-DO with PUT DATA
- Remove reset code (if any)
- Update PW1 with default "123456" with new setting of KDF
- Notify the user, reset code has been removed and PW1 should be updated
My intention of this proposal is to remove two user interactions (asking reset code, asking PW1) in the setup of KDF. Those will be done afterwards, by the user's explicit command.
I would prefer to have a procedure that do not reset PINs to their default values, but as long as all PINs are set to known and valid values when KDF is setup it will not make the token unusable after that, so it seems reasonable to me.