Skip to content
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

Current PIV Answer to Select Parsing in PIV AID #45

Open
dengert opened this issue Feb 24, 2021 · 42 comments
Open

Current PIV Answer to Select Parsing in PIV AID #45

dengert opened this issue Feb 24, 2021 · 42 comments

Comments

@dengert
Copy link

dengert commented Feb 24, 2021

In response to OpenSC issue OpenSC/OpenSC#2242 by @jo-bitsch please see
OpenSC/OpenSC#2242 (comment)

This points out a problem in the response to the Select AID where the length of the tag is wrong,
61 81 4F is parsed as tag=61 len=4F with next tag as 06.
But the it looks like it should have been
61 81 81 with tag=61 len=81 and next tag =4F

And the interpretation "AC" by NIST approved Idemia card which supports sp800-73-4 Secure Messaging differs from PivApplet interpretation which also made the response larger then needed.

OpenSC/OpenSC#2242 deals with tag is not parsed correctly, but looking at the data in the response, the response is not constructed by PivApplet correctly.

Incoming APDU (133 bytes):
61 81 4F 06 00 00 10 00 01 00 79 0D 4F 0B A0 00 a.O.......y.O...
00 03 08 00 00 10 00 01 00 50 22 50 69 76 41 70 .........P"PivAp
70 6C 65 74 20 76 30 2E 38 2E 32 2D 64 65 76 2F plet v0.8.2-dev/
52 45 65 50 53 41 73 78 4C 72 61 44 58 5F 50 26 REePSAsxLraDX_P&
68 74 74 70 73 3A 2F 2F 67 69 74 68 75 62 2E 63 https://github.c
6F 6D 2F 61 72 65 6B 69 6E 61 74 68 2F 50 69 76 om/arekinath/Piv
41 70 70 6C 65 74 AC 1B 80 01 03 80 01 08 80 01 Applet..........
0A 80 01 0C 80 01 06 80 01 07 80 01 11 80 01 14 ................
06 01 00 90 00 

Based on the name this appears to be a dev build, with a long name that caused the problem with the long tag.

It also pointed out current OpenSC card-piv.c can not handle the response if over 128 bytes.
But OpenSC/OpenSC#2053 could handle it.

Contributing to the problem is the length of the tag AC This is new in NIST sp800-74-4 and defined in Table 5. Which say just before table 5:
" A PIV Card Application may use a subset of the cryptographic algorithms defined in SP 800-78. Tag 0xAC encodes the cryptographic algorithms supported by the PIV Card Application. The encoding of tag 0xAC shall be as specified in Table 5. Each instance of tag 0x80 shall encapsulate one algorithm. The presence of algorithm identifier '27' or '2E' indicates that the corresponding cipher suite is supported by the PIV Card Application for secure messaging and that the PIV Card Application possesses a PIV Secure Messaging key of the appropriate size for the specified cipher suite. Tag 0xAC shall be present and indicate algorithm identifier 0x27 or 0x2E (but not both) when the PIV Card Application supports secure messaging."

PivApplet added 9 elements by adding "ALL" the algorithms supported by the card.

An Idemia NIST approved demo card that supports SM from sp800-74-4 only adds 2 elements:
AC 06 80 01 2E 06 01 00 i.e. is supports SM using 2E and a null OID.

sp800-73-3 does not define the "AC" tag.

It looks like Idemia interpreted table 5 to be added only when SM was supported as stated in bolded line above and did not report the standard required algorithms.

So if PivApplet can shorten the AC, or remove it or shorten comments by 2 bytes everything will work.

@jo-bitsch
Copy link

Just to make sure this is clear: this was not the upstream version of the PiVApplet, but one, where I locally lengthened the version information by a few bytes. This resulted in the answer to select becoming longer than 129 bytes. This made the generated asn1 invalid that was generated in the following line:

wtlv.push((byte)0x61);

If we replace the call with

wtlv.push256((byte)0x61);

the asn1 can be parsed correctly again. Hexdump:

61 81 85 4F 06 00 00 10 00 01 00 79 0D 4F 0B A0 
00 00 03 08 00 00 10 00 01 00 50 26 50 69 76 41 
70 70 6C 65 74 20 76 30 2E 38 2E 32 2D 64 65 76 
65 6C 6F 70 2F 52 45 65 50 53 41 73 78 4C 72 61 
44 58 5F 50 26 68 74 74 70 73 3A 2F 2F 67 69 74 
68 75 62 2E 63 6F 6D 2F 61 72 65 6B 69 6E 61 74 
68 2F 50 69 76 41 70 70 6C 65 74 AC 1B 80 01 03 
80 01 08 80 01 0A 80 01 0C 80 01 06 80 01 07 80 
01 11 80 01 14 06 01 00

--> https://lapo.it/asn1js/#YYGFTwYAABAAAQB5DU8LoAAAAwgAABAAAQBQJlBpdkFwcGxldCB2MC44LjItZGV2ZWxvcC9SRWVQU0FzeExyYURYX1AmaHR0cHM6Ly9naXRodWIuY29tL2FyZWtpbmF0aC9QaXZBcHBsZXSsG4ABA4ABCIABCoABDIABBoABB4ABEYABFAYBAA

Now this is a problem in my code, not (necessarily yet) in the unchanged code from this repository. However, it might lead to issues in the future, with cards having more algorithms, compile options being added or version numbers potentially including a git reference.

Thanks so much to @dengert for pointing out the malformed ASN1. I didn't notice it while debugging.

@jo-bitsch
Copy link

So I justed tested again with the version from the current master (806a035)

The current answer to select is (in the default configuration running in jcardsim):

61 80 4F 0B A0 00 00 03 08 00 00 10 00 01 00 79
0D 4F 0B A0 00 00 03 08 00 00 10 00 01 00 50 1C
50 69 76 41 70 70 6C 65 74 20 76 30 2E 38 2E 32
2F 52 45 65 50 53 41 78 4C 72 61 44 5F 50 26 68
74 74 70 73 3A 2F 2F 67 69 74 68 75 62 2E 63 6F
6D 2F 61 72 65 6B 69 6E 61 74 68 2F 50 69 76 41
70 70 6C 65 74 AC 1B 80 01 03 80 01 08 80 01 0A
80 01 0C 80 01 06 80 01 07 80 01 11 80 01 14 06
01 00

which runs actually already in exactly this problem: The ASN1 is malformed and should start with:
61 81 80 4F [...].
The culprit is exactly the referenced code line above in sendSelectResponse:

wtlv.push((byte)0x61);

which should be wtlv.push256((byte)0x61); . So, this is an actual bug in the current master and not just a potential bug later on if strings gets longer.

Nevertheless: Thanks for this awesome piece of software! I really appreciate the work!

@dengert
Copy link
Author

dengert commented Feb 25, 2021

OK, thanks for catching OpenSC/OpenSC#2242 which only shows up if the asn1 tag length is not correct. If the PivApplet sends valid length, things will work.

There is still a question why PivApplet sends all the cryptographic algorithms but NIST approved sp800-74-4 cards do not, but only send it to indicate card supports of Secure Messaging.

@dengert
Copy link
Author

dengert commented Feb 28, 2021

PivApplet does not appear to follow NIST or ISO standards in the following lines:

wtlv.push((byte)0xAC);
//#if PIV_SUPPORT_3DES
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_3DES);
//#endif
//#if PIV_SUPPORT_AES
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_AES128);
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_AES192);
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_AES256);
//#endif
//#if PIV_SUPPORT_RSA
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_RSA1024);
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_RSA2048);
//#endif
//#if PIV_SUPPORT_EC
if (ecdsaSha != null || ecdsaSha256 != null) {
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_ECCP256);
}
if (ecdsaSha384 != null) {
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_ECCP384);
}
/*#if !PIV_USE_EC_PRECOMPHASH
if (ecdsaSha != null) {
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_ECCP256_SHA1);
}
if (ecdsaSha256 != null) {
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_ECCP256_SHA256);
}
if (ecdsaSha384 != null) {
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_ECCP384_SHA1);
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_ECCP384_SHA256);
wtlv.writeTagRealLen((byte)0x80, (short)1);
wtlv.writeByte(PIV_ALG_ECCP384_SHA384);
}
#endif*/
//#endif
/*
* SP 800-83-4 part 2, 3.1 says: "Its value is set to 0x00"
* regarding this 0x06 tag. Previous PivApplet releases
* interpreted this as an empty 0x06 tag with no contents
* (length = 0), but it seems more logical that it should
* contain a single zero byte.
*/
wtlv.writeTagRealLen((byte)0x06, (short)1);
wtlv.writeByte((byte)0x00);

  1. NIST sp800-73-3 list the required and optional tags it supports and does not list the 'AC' tag at all.
  2. NIST sp800-73-4 list the 'AC' tag to be used if the card supports Secure Messaging, and "Table 5 Data Objects in a Cryptographic Algorithm Identifier Template (Tag 'AC')" shall have "Cryptographic algorithm identifier", and "Object identifier" "Its value is set to 0x00". and says "Tag 0xAC shall be present and indicate algorithm identifier 0x27 or 0x2E (but not both) when the PIV Card Application supports secure messaging."
  3. ISO 7816-4 "5.4.2 Cryptographic mechanism identifier template" Says "Referenced by tag 'AC', one or more cryptographic mechanism identifier templates may be present in the control parameters of any DF" "The first data object shall be a cryptographic mechanism reference, tag '80' (see Table 33).
    The second data object shall be an object identifier, tag '06', as defined in ISO/IEC 8825-1."
  4. ISO 7816-4 gives two examples: "{'AC' - '0B' - {'80'-'01'-'01'} - {'06'-'06'-'28818C710201'}}" and "{'AC' - '11' - {'80'-'01'-'02'} - {'06'-'05'-'28CC460502'} - {'06'-'05'-'28CF060303'}}"
  5. ISO 7816-4 uses the term "Cryptographic mechanism identifier template" PIV uses the term "Cryptographic Algorithm Identifier Template" which is not in ISO 7816.
  6. Idemia NIST approved demo card that supports SM from sp800-74-4 only adds 2 elements:
    AC 06 80 01 2E 06 01 00 i.e. is supports SM using 2E and a null OID.
  7. Neither NIST or ISO appear to limit the size of the response to a select AID command.

From the above there is some ambiguity.

  • 5 Different names for the same thing?
  • 3 and 4 say tag 'AC' can be repeated.
  • 4 says each 'AC' has one tag '80' and one or more tags of '06'
  • 1 does not require or even mention 'AC'
  • 2 uses the 'AC' for Secure Messaging for the '27' and '2E' tags.
  • 2 also says "Each instance of tag 0x80 shall encapsulate one algorithm."
  • 2 also says "but not both ('27' and '2E')" which implies there could be multiple 'AC' tags.
  • Some other PIV like cards/applets don't support all the required algorithms, but that is not a problem because the algorithms can also be found from private keys in certificates.

The way I read all of this:

  • The 'AC' tag should only be present if Secure Messaging is supported by the card.
  • Since 3 did not require all algorithms be listed, they need not be listed in the response to SELECT. In addition the use of the symmetric algorithms are only used for card management and card management is left up to the vendor, they should not be in response to SELECT. The vendor should have other ways to determine what the card supports.
  • The use of multiple tag 'AC' is allowed both by 2, 3 and 4 and ignored by 1.
  • 2, 3, and 4 all say there is only one tag '80' within each 'AC'.
  • 6 adds only one tag 'AC' with one tag '80' and one tag '06' which meets both the requirements of 1, 2, 3 and most of 4 and 7.

I would suggest that the code in PivApplet be simplified and do what the 6 Idemia does. Keep it short and meet the minimum requirements for the response to SELECT AID.

OpenSC/OpenSC#2053 is looking for the first 'AC' and will only look at the first tag '80' to see if its value is '27' or '2E' and ignore all other tag 'AC' or or all other tag '80' in the first tag 'AC'.

If you don't change the code but intend to support Secure Messaging at a later date, Please make sure the first tag 'AC' has a singe tag '80' with the value '27' or '2E'.

@arekinath
Copy link
Owner

Since PivApplet supports different algorithms in different builds, I've been using that AC tag to indicate which ones have been enabled and detected in the particular build and card that it's running. I understand that the spec doesn't require it, but my reading was that it doesn't say you can't do it, either, and it seems convenient to me. Do you know of any implementations which actually blow up at repeated AC tags for non-SM algos? If you know of some, that might change by mind on using it.

For now, I'll change this to multiple AC tags with one 80 in each, as you've indicated. That was my bad, misreading how the multiple instances of the tag were meant to be structured. And I'll make sure to add a note that if/when SM is supported, it should go first in the list (that seems sensible anyway).

arekinath added a commit that referenced this issue Mar 1, 2021
This corrects the malformed BER-TLV being generated on some
builds (when strings in the APT are long enough), and makes
our APT a little closer to standards-compliant.

To get back a little of the space we're paying for all the
'AC' tags per algo, we'll stop pushing quite so many into
the list (just one AES, for example).

See #45
@dengert
Copy link
Author

dengert commented Mar 1, 2021

This is a chicken and egg problem...

A driver would test for the 'AC' tag only if the driver supported the optional Secure Messaging defined in 800-73-4.
because this it the way the driver knows if the card supports SM or not. (800-74-4 also extends the pin policy bits and can support a "pairing" code too.)

The only cards I know of that support 800-73-4 SM are the Idemia cards, ID-One PIV 2.4.1. The vendor sent me a set. They have their own driver to support it on windows for sure, not clear if they have an Apple or Linux version. But it would most likely never be used to access any other cards. There maybe others by now and I know some US government agencies are looking at issuing these cards.

OpenSC/OpenSC#2053 is the only open source driver I know of that supports supports SM, the pin policy and the pairing code and I used the Idemia cards to test it.

I would hope other PIV Applet developers could use the OpenSC/OpenSC#2053 to implement the applet side of the SM, as it is very complicated.

The Secure Messaging is most useful over NFC or if one is worried about USB sniffers or Remote Desktop. SM can protect all the traffic including PIN. Could be useful with a phone or tablet. But most phones are Apple or Android.

So the answer is I do not know of any drivers that would choke.

@arekinath
Copy link
Owner

@dengert Yeah, I understand the situation roughly. I thought there was more than just Idemia's implementation out in the commercial world though? E.g. I thought some other physical security vendors advertised support for PIV SM when reading cards over NFC?

In any case, I'm going to continue including AC tags in the APT for now for other algorithms. pivy uses these to detect the extra proprietary algorithm IDs that PivApplet supports on JC2.2.x cards for doing hash-on-card ECDSA.

Maybe I will revisit this behaviour when removing the hash-on-card extension (which I'm considering doing at some point, since it seems like most of the JC2.2.x cards which this is useful on have pretty bad side-channel weaknesses when doing ECDSA anyway, and JC3.0.x cards are becoming very common and cheap now)

@mistial-dev
Copy link
Contributor

mistial-dev commented Mar 1, 2022

In terms of SP-800-73-4, C.2 seems to require a singular AC tag.

"The Application Property Template, which is included in the response to the SELECT command,
optionally includes a tag 0xAC, which indicates what cryptographic algorithms the PIV Card
Application supports"

I would think that they would have said "one or more" if they wanted that to be permitted, but that's just how I read it.

@dengert
Copy link
Author

dengert commented Mar 1, 2022

In SP-800-73-4 part 1, C.3 "PIV Algorithm Identifier Discovery for Secure Messaging" Has the above and it says "algorithms" So there can be more then one.

Then it says: "The presence of algorithm identifier '27' or '2E' indicates that the corresponding cipher suite is supported by the PIV Card Application for secure messaging and that the PIV Card Application possesses a PIV Secure Messaging key of the appropriate size for the specified cipher suite." '27' uses ECDSA p-256 and '`2E' uses ECDSA P-384. Since the SM requires the "PIV Secure Messaging key" '04' there is only one key and one "3.3.7 Secure Messaging Certificate Signer" per card.

Since NIST only defined RSA 2048 and ECDSA P-256 and ECDSA P-384 these are defined in the standards they are implied and are not required to be listed in any 'AC' tag.

The AC tag could have other algorithms but only '27' or '2E' indicate card supports SM.

The OpenSC proposed PR checks for '27' or '27':
https://github.com/dengert/OpenSC/blob/PIV-4-extensions/src/libopensc/card-piv.c#L2798-L2851

@mistial-dev
Copy link
Contributor

mistial-dev commented Apr 4, 2022

Has the above and it says "algorithms" So there can be more then one.

I agree.

If you look at 800-73-4, table 3.1.1, it again states "Cryptographic algorithms supported", not algorithm. This means that the tag would contain multiple algorithms.

Further down, it states "Tag 0xAC encodes the cryptographic algorithms supported by the PIV Card Application. The encoding of tag 0xAC shall be as specified in Table 5. Each instance of tag 0x80 shall encapsulate one algorithm"

So, 0xAC contains multiple algorithms, each encapsulated in one 0x80.

In other words, the Application Property Template "optionally includes a tag 0xAC", and that tag (if present) encodes the cryptographic algorithm(s).

With secure messaging, then, you would have only one of the references 0x27 or 0x2E, but other references could be present without such restrictions.

The presence of algorithm identifier '27' or '2E' indicates that the corresponding cipher suite is supported by the PIV Card Application for secure messaging and that the PIV Card Application possesses a PIV Secure Messaging key of the appropriate size for the specified cipher suite.

Tag 0xAC shall be present and indicate algorithm identifier 0x27 or 0x2E (but not both) when the PIV Card Application supports secure messaging

This says "Tag 0xAC", which is consistent with singular usage. The use of "but not both" in that context would seem to indicate singular.

I'd respectfully disagree on your interpretation that "but not both" implies there could be multiple AC tags. The way that I'd read it would be "the card must choose one or the other, because you can't do multiple AC tags". They clearly don't want both supported on one card, and if you could have two tags, then the appropriate phrasing would be something along the lines of "a Application Property Template may not contain both '27' and '2E' cipher suites". Instead, they only constrain the AC tag to achieve their end, because there should be only one AC tag.

The GSA also considers this a ban on 0x27 and 0x2E both being present in a card, not just in a tag.

https://www.idmanagement.gov/docs/fips201ep-smocc.pdf

When Cipher Suite 2 or 7 are supported, only one is allowed. Both are not allowed on the same card, per the following:

...

Tag ‘AC’ may contain a series of ‘0x80’ tags defining cryptographic algorithms and one PIV cipher suite supported by the PIV card.

As further evidence of a singular tag, I'd point out the way that the tag is referred to elsewhere in SP 800-73-4.

If the 0xAC tag of the application property template (APT) includes '27'

If the 0xAC tag of the APT includes '2E', then generate an ephemeral key pair over Curve P-384.

Both usages are singular, and consistent with a single 0xAC tag that must contain one or the other. If multiple 0xAC tags could be present, then it should be "If a 0xAC tag in the application property template"

This continues in the command interface section:

Algorithm reference ('27' or '2E'), as specified in the 0xAC tag of the application property template

I would agree with your assessment of ISO 7816-4, and Microsoft seems to as well in their GIDS specification based upon it, but PIV is a subset of 7816-4, as we see in many areas in the standard.

@mistial-dev
Copy link
Contributor

The interface test guidelines are also singular:

https://csrc.nist.rip/external/nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-85A-4.pdf

P1, algorithm reference, is set to '27' or '2E', as indicated by the 0xAC tag obtained from the application
property template in step 1

Step 1 is a SELECT command, so it would return multiple tags if present. The test guidelines say "the 0xAC tag".

All four times that tag is referenced in the test guidelines (that are not quoted from the other standards), it's used in the singular form, as a result of a SELECT.

@makinako
Copy link

makinako commented Apr 6, 2022

From OF201's perspective:

  • Lengths >= 128 are a-ok, it just needs to fit into a short-form RAPDU.
  • The AC tag is conditional, which we interpret as 'Optional, but mandatory if you support PIV SM'
  • AC tag is definitely intended to convey multiple algorithms Tag 0xAC encodes the cryptographic algorithms supported by the PIV Card Application. (3.1.1)
  • The AC tag should only appear once, containing multiple 80h tags Each instance of tag 0x80 shall encapsulate one algorithm

For reference, this is the current OF201 FCI (145 bytes + SW12):

61 81 8F 
  4F 0B A0 00 00 03 08 00 00 10 00 01 00 
  79 07 4F 05 A0 00 00 03 08 
  50 0B 4F 70 65 6E 46 49 50 53 32 30 31 
  5F 50 49 
        68 74 74 70 3A 2F 2F 6E 76 6C 70 75 62 73 2E 6E 69 73 74 2E 
        67 6F 76 2F 6E 69 73 74 70 75 62 73 2F 53 70 65 63 69 61 6C 
        50 75 62 6C 69 63 61 74 69 6F 6E 73 2F 4E 49 53 54 2E 53 50 
        2E 38 30 30 2D 37 33 2D 34 2E 70 64 66 
  AC 1E 
     80 01 00 
     80 01 03 
     80 01 08 
     80 01 0A 
     80 01 0C 
     80 01 06 
     80 01 07 
     80 01 11 
     80 01 14 
     06 01 00 

@dengert
Copy link
Author

dengert commented Apr 6, 2022

https://www.idmanagement.gov/docs/fips201ep-smocc.pdf also says:

When one of 0x27 or 0x2E are present, this text states “…the PIV Card Application supports
secure messaging.” This is an incomplete view. When the APT says SM is supported by the
card, it means the card manufacturer enabled SM on the PIV card platform and the PIV applet.
It does not indicate that the issuer enabled Secure Messaging on the PIV card that is
responding to the reader/application.
This must be verified by determining if the CVC certificates and keys are present as
established by the issuer.

The way I read 800-73-4 the CVC certificate is either P256 or p384 thus if SM is to work the AC must have 0x27 or 0x2E.

My test PIV cards have AC 06 80 01 27 06 01 00

As you indicated, the specs follow ISO 7816, but are written to only require a subset be supported. What they appear to say is only a subset of algorithms i.e. (either 0x27 or 0x2E) are allowed.

Have you tried asking on the https://csrc.nist.gov/projects/piv/nist-piv-test-cards ?
David Cooper has been very responsive.

Looking at the OpenSC PR https://github.com/dengert/OpenSC/blob/PIV-4-extensions/src/libopensc/card-piv.c#L2805-L2829
it looks for either 0x27 or 0x2E and will use the first found, and skip over any other in the list, so should work with the "OF201 FCI (145 bytes + SW12):" if 0x27 or 0x2E was added anywhere in the list.

@makinako
Copy link

makinako commented Apr 6, 2022

Yes now having a read through the 7816 wording is actually very clear. OF201 was implemented only from the SP800-73 wording and this is in contradiction with the ISO standard intention. This is something we need an answer on too so I've just joined the piv-test-cards group and will post the question there.

@mistial-dev
Copy link
Contributor

mistial-dev commented Apr 6, 2022

Yes now having a read through the 7816 wording is actually very clear. OF201 was implemented only from the SP800-73 wording and this is in contradiction with the ISO standard intention.

Is it, though?

In terms of "be conservative in what you do, be liberal in what you accept from others", would the current OF201 implementation actually violate ISO 7816 in any way?

If PIV is read as a subset of the ISO standards, wouldn't the existing OF201 implementation be compatible with both?

@makinako
Copy link

makinako commented Apr 6, 2022

In terms of "be conservative in what you do, be liberal in what you accept from others", would the current OF201 implementation actually violate ISO 7816 in any way?
I take your point @mistial-dev and true no-one has complained yet (including the PIV compliance tool), but I've asked the question to NIST anyway because why not and if we get a good response it never hurts to improve!

@dengert
Copy link
Author

dengert commented Apr 7, 2022

Do you know exactly what the PIV compliance tool looks at? For example if you passed in
0x27 and 0x2E in the middle of the list, would it complain?

 AC 24
     80 01 00 
     80 01 03 
     80 01 08 
     80 01 0A 
     80 01 27
     80 01 0C 
     80 01 06
     80 01 2E 
     80 01 07 
     80 01 11 
     80 01 14 
     06 01 00 

If it dose complain, it means it is parsing the list. If not, it may only look at the first entry.

@mistial-dev
Copy link
Contributor

I take your point @mistial-dev and true no-one has complained yet (including the PIV compliance tool), but I've asked the question to NIST anyway because why not and if we get a good response it never hurts to improve!

I think asking the question is absolutely the right call. My question was more if it mattered.

If they come back and say "yes, you can have multiple AC tags, each with multiple 80 algorithms", would it make sense to do so?

The same with whether the 0x27/0x2E has to be first in the list or not. From a consumer standpoint, it absolutely makes sense to handle the edge cases. From a producer standpoint, though, would it not make sense to do it the way least likely to cause issues?

In other words, is the answer actually useful for PivApplet or OF201, or should both just try to do it the compact, sensible, compatible way?

@makinako
Copy link

makinako commented Apr 7, 2022 via email

@dengert
Copy link
Author

dengert commented Apr 8, 2022

If you are going to add additional Algorithms you will want to avoid any conflicts with whatever NIST might do in the future.

sp800-73-4 refers to sp800-78 for Algorithms. The latest version of sp800-78 I could find is: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-78-4.pdf
"Table 6-2. Identifiers for Supported Cryptographic Algorithms"
The way NIST define the "GENERAL AUTHENTICATE" command you are stuck with using a single byte P1 with the Algorithm.

You will note that 0x05 is not defined but: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-73-1.pdf defined it as RSA 3072. Some other AES and ECC Algorithms were also defined but dropped in later version of sp800-73. So RSA 3072 would be the easy one to add.

If you do add additional Algorithms to the applet, middleware like OpenSC will also need to be updated to use these. If you can coordinate with NIST or even Yubikey, it would make the middleware changes easier.

@makinako
Copy link

makinako commented Apr 8, 2022 via email

@dengert
Copy link
Author

dengert commented Apr 8, 2022

Looking closer at iso7816-4 "5.4.2 Cryptographic mechanism identifier template"
"Such a template shall consist of two or more data objects"
"The first data object shall be a cryptographic mechanism reference, tag '80' (see Table 33)."
"The second data object shall be an object identifier, tag '06'"
"If present, one or more subsequent data objects shall either identify a mechanism, tag '06'..."

So I don't think this list of encoding of AC listed in previous comments is correct:

AC 1C
     80 01 00 
     80 01 03 
     80 01 08 
     80 01 0A 
     80 01 0C 
     80 01 06 
     80 01 07 
     80 01 11 
     80 01 14 
     06 01 00 

It should look more like:

AC 42
     80 01 00    06 01 00
     80 01 03    06 01 00
     80 01 08    06 01 00
     80 01 0A    06 01 00
     80 01 0C    06 01 00
     80 01 06    06 01 00
     80 01 07    06 01 00
     80 01 11    06 01 00
     80 01 14    06 01 00

So the algorithms IDs are what NIST specifies in the docs as there is a OID of 0.
But if the algorithms IDs had an OID the algorithm's ID is used in GENERAL AUTHENTICATE "P1"
and thus any crypto OID could be used between the card and the middleware.

So for example sp800-78-2 "Table 3-6. ECC Parameter Object Identifiers for Approved Curves" lists:
Curve P-256 ansip256r1 ::= { iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 }
Curve P-384 ansip384r1 ::= { iso(1) identified-organization(3) certicom(132) curve(0) 34 }

Using https://misc.daniel-marschall.de/asn.1/oid-converter/online.php
1.2.840.10045.3.1.7 == 06 08 2A 86 48 CE 3D 03 01 07
1.3.132.0.34 = 06 05 2B 81 04 00 22

If NIST wanted to, they could have added the ECC algorithms as:

     80 01 11   06 08 2A 86 48 CE 3D 03 01 07
     80 01 14   06 05 2B 81 04 00 22

And if you wanted to add a Ed25519 i.e.
http://oid-info.com/get/1.3.6.1.4.1.11591.15.1

80 01 XX    06 09 2B 06 01 04 01 DA 47 0F 01

where XX is of your choosing for the card that returns the above in the AC tag.

An example with all the standard NIST defines not needed and the card also ED25519 and RSA3072 and SM 27 supported:

AC 1A
80 01 27 06 01 00 (card says it supports SM using 256)
80 01 05 06 01 00 (Using NIST RSA 3072 from old sp800-73-2)
80 01 ED 06 09 2B 06 01 04 01 DA 47 0F 01 (Card says it supports Ed25519)
(and card implies is supports all other NIST defined algorithms.)


 The above may all be academic. Sp800-73 defines the read only end user interface and leaves it up to card vendors to provide provisioning software, and many use SCP03. One issue with using the AC tag with RSA and RSA  it not only defines algorithm it also defines the size. NIST expects the middleware to get the size and algorithm from the public key in a certificate to map to what is used in GENERAL AUTHENTICATE P1. 

Generating/importing keys, creating certificates and loading other objects on the card are provisioning functions and anything you add to the AC should not interfere with read only access by middleware.   

NIST does define a few commands to write to the card, but does not require that they be useable by an end user and don't expect the end user to have access to the management keys. 

I believe this trade off of simple read only access and vendor provisioning was to allow card vendors to compete in open markets to sell their cards to agencies based on their provisioning and card management software. 
 






@mistial-dev
Copy link
Contributor

"The first data object shall be a cryptographic mechanism reference, tag '80' (see Table 33)."
"The second data object shall be an object identifier, tag '06'"
"If present, one or more subsequent data objects shall either identify a mechanism, tag '06'..."

The parts you quote require first and second. The third line says "one or more", not "subsequent pairs", and uses either a mechanism or tag 06. That would be singular, would it not?

At first glance, that would suggest something like this to me:

AC 1C
     80 01 00 
     06 01 00 
     80 01 03 
     80 01 08 
     80 01 0A 
     80 01 0C 
     80 01 06 
     80 01 07 
     80 01 11 
     80 01 14 

@dengert
Copy link
Author

dengert commented Apr 8, 2022

ISO7816-4
5.4.2 Cryptographic mechanism identifier template
Starts with:

Referenced by tag 'AC', one or more cryptographic mechanism identifier templates may be present in the control parameters of any DF (see Table 12). Each one explicitly indicates the meaning of a cryptographic mechanism reference in the DF and its hierarchy. Such a template shall consist of two or more data objects.

I read this as "a mechanism identifier template consist of two or more data objects."

@makinako
Copy link

makinako commented Apr 8, 2022

We have some answers from NIST:

  1. Could I confirm that the presence of the AC tag in the PIV FCI should be conforming to the definition in ISO 7816-4 9.2? i.e. multiple AC tags in the FCI with one 80/06 tag pair each.
    NIST: How we have specified is to expect tag AC with nested 80/06 pairs each pair specifying an algorithm

  2. Is it the intention of PIV to list all supported mechanisms (i.e. RSA2048/ECC256/TDEA/AES128/etc in the FCI, or just the relevant Secure Messaging one?
    NIST: Just the relevant secure messaging one is expected if secure messaging is supported. Vendors can also have 80/06 pairs of other supported PIV algorithms included as well.

  3. The AC tag is marked as conditional. Is it correct to interpret this as:
    a. "You may use it any time, but you must use it if you support PIV Secure Messaging";
    NIST: This (above) is the right interpretation.
    b. "You only use the AC tag if you support PIV Secure Messaging"?

@mistial-dev
Copy link
Contributor

Looks like @dengert is correct in his interpretation. Thank you for asking the mailing list.

I will change the pull request to conform.

@dengert
Copy link
Author

dengert commented Apr 9, 2022

Based in statement above: "multiple AC tags in the FCI with one 80/06 tag pair each."

The old version of ISO/IEC 7816-4:2005(E) says: "Table 12 lists the file control parameters, all in the context-specific class. When a control parameter is present for a file, the Table says whether it occurs only once (explicit indication), or it may be repeated (no indication)."
The final entry has: "'AC' Var. Cryptographic mechanism identifier template (see 5.4.2) Any DF" and it does not include the (explicit indication) of "Once" like some other entries in the table.

I think my example should look like:

AC 06   80 01 27    06 01 00           (card says it supports SM using 256)
AC 06   80 01 05    06 01 00            (Using NIST RSA 3072 from old sp800-73-2)
AC 0E   80 01 ED    06 09 2B 06 01 04 01 DA 47 0F 01 (Card says it supports Ed25519)
(and card implies is supports all other NIST defined algorithms.)

I will update the OpenSC PR OpenSC/OpenSC#2053

@arekinath
Copy link
Owner

arekinath commented Apr 12, 2022

The reply from NIST still sounds ambiguous to me as to whether they expect us to use a singular AC tag with multiple pairs of 80/06 inside it, or whether they expect us to use multiple AC tags, each with one singular pair of 80/06 inside.

They're clear that there should be pairs of 80/06 inside AC, and it sounds like advertising more than just the SM mechs there is fine, but that particular point still seems open to interpretation to me with the sentence "How we have specified is to expect tag AC with nested 80/06 pairs each pair specifying an algorithm"

ISO 7816-4 clearly expects us to have multiple AC tags with a single pair in each, but this wouldn't be the first place where NIST has deviated from a strict reading of 7816-4.

I think they might be trying to say that multiple pairs of 80/06 inside one AC is allowed, but not required? If so, it sounds like they're ok with the idea of one AC tag with multiple pairs in it, but the 7816-style multiple AC tags should be fine too?

If it's that, I would be inclined towards using a singular AC tag, because it's more compact and lowers the probability that there will have to be response chaining on the response to select.

@dengert
Copy link
Author

dengert commented Apr 12, 2022

Who at NIST responded to the inquire(s)? I can try asking the same type of question and point out there are three of us @arekinath, @mistial-dev, @makinako and @dengert are discussing the issue on github.

@makinako
Copy link

Who at NIST responded to the inquire(s)? I can try asking the same type of question and point out there are three of us @arekinath, @mistial-dev, @makinako and @dengert are discussing the issue on github.

I got the reply from Hildegard Ferraiolo, though she passed it to some internal team members.

For more context here is my original question on the piv-test-cards list: https://groups.google.com/a/list.nist.gov/g/piv-test-cards/c/zLaCz5l6IyQ

From that and the response I got, I for one am happy to accept the answer as being a single AC tag with multiple 80/06 tags. Even though there is a slight ambiguity in the wording, If I presume they meant multiple AC tags and re-read it, the language doesn't make sense any more. Of course ask though if you want to get clarity.

@dengert
Copy link
Author

dengert commented Apr 12, 2022

@arekinath, @mistial-dev, @makinako do you have a copy of ISO7816-4? I ask because it appears to me that it says Multiple 0xAC tags. Each 0xAC tag is a "Cryptographic mechanism identifier template" and the template has one 0x80 tag followed by one or more (or is it zero or more) 0x06 OID tags.

Prior to 800-73-4 there was no reason to have to look for 0XAC tags in the FCI returned by SELECT.

From the NIST/PIV point of view there is only one 0xAC tag enclosing one 0x80 tag with value 0x27 or 0x2E followed by one OID with value 0. But their response: "NIST: How we have specified is to expect tag AC with nested 80/06 pairs each pair specifying an algorithm" which contradicts ISO7816-4. And since they don't ever use any additional pairs, they are still following ISO7816-4.

From the point of view of a PIV applet, you could follow strict PIV specification and not ever use any additional pairs either.
As I understand why you are trying to add additional algorithms is to use this information for provisioning cards which is left up to the vendors. (and a vendor does not have to put this in response to select.) There is no requirement that after the card is provisioned these extra algorithms are in the response to select.

If you still want these visible after provisioning, one way to satisfy NIST and ISO7816-4, it to make sure if card supports SM, the first 0xAC is for 0x27 or 0x2E. And if you add additional algorithms add them as additional 0xAC templates.

The next issue is what middleware needs from the card. Any provisioning software which you chose to provide or any middleware needs the info somewhere or that needs to know if card supports SM. Card vendors are providing their own drivers. It appears Windows is no longer providing a Microsoft driver, and it is not clear to me what Apple is up to with MacOS. But that is there problem.

From OpenSC driver prospective, I can support either, by looking for any 0xAC that has 0x27 or 0x2E and disregard the rest as they are not needed after provisioning, as the certificates SPKI is the public key which has RSA key size or ECC nameCurve OIDs that can map to the PIV algorithm IDs used in "P1"

Hopefully PivApplet and OpenFIPS201 can agree on one method that still works with NIST if they decide to add more algorithms to PIV specs. Personally I would how you agree on the iso7816-4 view that a 0xAC had only one 0x80 with one OID and there can be multiple 0XAC tags present.

@dengert
Copy link
Author

dengert commented Apr 13, 2022

Sent e-mail to NIST and CC: @arekinath, @makinako but could not find actual e-mail address for @mistial-dev

@mistial-dev
Copy link
Contributor

[@mistial-dev] do you have a copy of ISO7816-4?

I do. I purchased ISO/IEC 7816-4:2020(en) from ISO a while ago. I don't have any earlier versions.

could not find actual e-mail address for @mistial-dev

My admin@mistial.dev email should show publicly on my profile. I'll look into why it's not.

Each 0xAC tag is a "Cryptographic mechanism identifier template" and the template has one 0x80 tag followed by one or more (or is it zero or more) 0x06 OID tags.

The SP800-74 mechanism seems to mainly not try to break ISO7816-4, rather than actually implementing it. Using an example from the specification (for example):

{'AC' - '11' - {'80'-'01'-'02'} - {'06'-'05'-'28CC460502'} - {'06'-'05'-'28CF060303'}}

ISO7816-4 allows multiple types of OIDs in the standards: encryption, MAC, authentication protocols, and digital signatures. That example includes an authentication mechanism, and a hash function.

Meanwhile, SP800-74 explicitly seems to say that the OID should be blank, and the cryptographic identifier needs to come from SP800-78.

And since they don't ever use any additional pairs, they are still following ISO7816-4.

I agree with your interpretation, but NIST is only following it to a degree.

They meet the first requirement, which requires the first DO to be a reference '80'. 7816-4 requires the second DO to be an OID (check), which is a cryptographic mechanism defined in a standard. A null OID isn't.

7816-4 requires further DOs to be either '06' or '0D', but not including any of them would be fine. From a pure standards standpoint, it would be nice if they allocated an OID to their own standard and used it, but they didn't.

I'm not sure how to reconcile the two standards in terms of using this mechanism to advertise support.

As I understand why you are trying to add additional algorithms is to use this information for provisioning cards which is left up to the vendors.

With open PIV-compatible implementations, the "vendor" is often the end-user. The question then becomes whether to limit the user to exactly what NIST does, or allow them to go outside those boundaries in the interest of functionality.

Hopefully PivApplet and OpenFIPS201 can agree on one method that still works with NIST if they decide to add more algorithms to PIV specs. Personally I would how you agree on the iso7816-4 view that a 0xAC had only one 0x80 with one OID and there can be multiple 0XAC tags present.

Sadly, this is one case where the mechanism in 7816-4 could be handy. Using real OIDs would allow a local reference to be unambiguously associated with a mechanism, although there is still an issue with NIST clobbering it in the future. SP800-78 states " Table 6-2 lists the algorithm identifiers for the cryptographic algorithms that may be recognized on the PIV interfaces. All other algorithm identifier values are reserved for future use."

@mistial-dev
Copy link
Contributor

@arekinath @makinako

As a thought, would it make sense to put any extra supported algorithms in a different data file, essentially?

PIV uses GET DATA as 'XX CB 3F FF'. Looking at 7816-4, table 98, a P1-P2 value other than 0000 or FFFF is a file identifier. Essentially, the PIV data is all in the "3F FF" file, with tags being retrieved from there. I believe this would be a "Dedicated File" under 7816-4, which "[hosts] an application in a card".

It would be possible to move any extra algorithms supported into a different dedicated file, and present the control parameter in a proper ISO7816-4 compliant format, with OIDs actually representing the underlying supported algorithm. It would not expand the PIV ATS, standard PIV devices would not need to know it existed, and would not affect their functionality at all. It would look along the lines of @dengert 's example (for ed25519):

80 01 XX 06 09 2B 06 01 04 01 DA 47 0F 01

Essentially, the applets would have "PIV mode", and "PIV plus" mode, where PIV plus more closely followed 7816-4. If the 5x50 tag were used to identify the applet or the specification supported, middleware could act upon and support it.

@makinako 's examples are good ones of extensions and the reason why having that capability makes sense. Some orgs (for example) prefer ED25519, and I've seen policies that required secp256k1 over secp256r1, for example.

Having it as a separate DF would allow such functionality to be hidden from standard PIV implementations (for example, the windows built-in driver), but still allow its use with PKCS11 or custom drivers.

@dengert
Copy link
Author

dengert commented Apr 13, 2022

With open PIV-compatible implementations, the "vendor" is often the end-user. The question then becomes whether to limit the user to exactly what NIST does, or allow them to go outside those boundaries in the interest of functionality.

The end-user still needs administrative tools to administer the card. You will need to address all the issues Yubico has addressed as they have extended the ability of the end user to administer their own card by providing administrative tools. NIST does provide some administrative commands, including generating a key pair on the card. But it does not define how to load an external key. (And the card does not store the public key directly, but returns it in responds to generate key pair.)

The OpenSC piv-tool is not a Card Management System, but provides the bare bones set of NIST defined commands that could be part of a CMS. It does support authentication using 2DES, 3DES and AES administration keys. It can store on disk the public key, that can then be used in a CSR that is then signed by the token.

OpenSC PIV driver, if called by PKCS11 or Minidriver could be modified to store in memory the results of a generate keypair that could then be used in a later call to retrieve it from memory. This would be an easy change. But providing the administrator key would be more difficult. (Personally I have no interesting in creating a CMS but am open to making the changes for PKCS11 and Minidriver.

@mistial-dev
Copy link
Contributor

I am working on an open source CMS, and will be releasing with support for YubiKey and PIV Applet, at a minimum. I hope to also support Open FIPS 201, but haven't looked into that side of things.

It's definitely a missing piece of the puzzle, and getting a GUI that is functional, secure, and usable is an interesting challenge.

I don't think the YubiKey manager goes quite far enough in terms of functionality beyond changing PINs and loading keys/certs.

@mistial-dev
Copy link
Contributor

With YubiKey 5.3+ you can use get metadata to get the public key.

https://docs.yubico.com/yesdk/users-manual/application-piv/commands.html#get-metadata

Attestation should work on older firmware as well, I believe, as the cert is issued to the public key.

PIVApplet supports the attestation interface, and the PR I'm putting together implements full 5.3 API compatibility as well.

I don't think it technically violates NIST standards to have the public key compatible, and attestation makes things like rekey/recert much easier for a CMS.

If I have a way to get supported algorithms, I will use it to filter commands for generate and import. PivApplets build flags also allow this, but I like the OF201 dynamic approach better. It's a good idea.

@makinako
Copy link

I am working on an open source CMS, and will be releasing with support for YubiKey and PIV Applet, at a minimum. I hope to also support Open FIPS 201, but haven't looked into that side of things.
Absolutely agreed an Open CMS is a big gap and I think all of us at one point or another have thought about it, so if you make it happen I will order you a pizza of your choosing :) Obviously if you end up with OF201 support that is awesome but even if you just design a reasonable degree of modularity in it I would be happy to plug in the OF201 portion.

@mistial-dev Regarding your suggestion for a different DF to describe mechanisms, this is something @arekinath suggested and I like the idea of. OF201 will soon have data object and key enumeration, so adding supported mechanisms makes sense and why not make it a 80/06 pair with real OID's? Perhaps to avoid making the response too large we could only populate the OID's for non-vanilla PIV mechanisms.

@dengert
Copy link
Author

dengert commented Apr 14, 2022

Some other tidbits...

One thing Yubikey-piv-tool does have is the ability to create a PIV CHUID object with action "set-chuid". sp800-73 does not define a serial number. OpenSC use the CHUID's FASC-N or GUID to create a serial number. Both OpenSC and the original Microsoft PIV driver endup using the CHUID's FASC-N or GUID for container names on windows. Yubikey-piv-tool can also create a CCC with "set-ccc"

I don't think it technically violates NIST standards to have the public key compatible, and attestation makes things like rekey/recert much easier for a CMS.

I agree. Two years ago I wrote a PR for OpenSC to use the Yubikey attestation to get touch policy. But no one was interested it. See https://github.com/dengert/OpenSC/tree/

Also note OpenSC uses PivApplet and yubico-piv-tool is github actions when a PR is submitted. https://github.com/OpenSC/OpenSC/blob/master/.github/test-piv.sh

@dengert
Copy link
Author

dengert commented Apr 14, 2022

If you are interested, before I retired, we where just implementing a way to use temporary PIV cards to be used to login to AD for people who forgot their card at home, lost cards, broken cards or for employees who where waiting to get a government issued card. This is all based on OpenSC's piv-tool and bash scripts. It also contains some other utility programs to encode/decode a FASC-N, create/show a CHUID and display the facial image object. Contact me via e-mail.

@mistial-dev
Copy link
Contributor

mistial-dev commented Mar 20, 2023

Looking through the NIST comments, Obethur asked specifically about the algorithm specification (OT-32):

Could you please clarify whether the tag AC is supposed to list all cryptographic algorithms supported by the card or only the one supported for the Secure Messaging.

NIST's response was vague:

Resolved by adding the following text in-place of the sentence on line 467 of NIST SP 800-73-4 part 2 below
table 4 in the select command section.
• The presence of algorithm identifier '27' or '2E' indicates that the corresponding cipher suite is supported by the PIV Card Application for secure messaging and that the PIV Card Application possesses a PIV Secure Messaging key of the appropriate size for the specified cipher suite.

They seemed to feel this resolved the question, changing it from the earlier statement

1178 The Application Property Template, which is included in the response to the SELECT command,
1179 optionally includes a tag 0xAC, which indicates what cryptographic algorithms the PIV Card 
1180 Application supports. The presence of algorithm identifier '27' or '2B' indicates that the 
1181 corresponding cipher suite is supported by the PIV Card Application for secure messaging and that 
1182 the PIV Card Application possesses a PIV Secure Messaging key of the appropriate size for the 
1183 specified cipher suite.

Clear as mud.

Perhaps to avoid making the response too large we could only populate the OID's for non-vanilla PIV mechanisms.

I think that's quite reasonable. As the Obethur comment pointed out, there's little reason to waste space on responses that do not provide useful information.

@dengert
Copy link
Author

dengert commented Mar 23, 2023

Perhaps to avoid making the response too large we could only populate the OID's for non-vanilla PIV mechanisms.

I also agree. NIST is only using the tag AC as a flag that SM is supported by the card.

And SP 800-78 defines the mapping for algorithms supported by NIST and is referenced in SP 800-73-4 for PIV cards. So beware of using 0xED as NIST may pick it in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants