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

Unused SM_MODE_ACL #971

Closed
frankmorgner opened this issue Feb 20, 2017 · 8 comments · Fixed by #1250
Closed

Unused SM_MODE_ACL #971

frankmorgner opened this issue Feb 20, 2017 · 8 comments · Fixed by #1250
Assignees

Comments

@frankmorgner
Copy link
Member

SM_MODE_ACL is defined in sm.h and sc_card_sm_load initializes card->sm_ctx.sm_mode to this value. However, there is no other code that references SM_MODE_ACL, let alone code that does something useful with it.

What should happen?

remove SM_MODE_ACL and initialize card->sm_ctx.sm_mode in sc_card_sm_load to SM_MODE_NONE

@viktorTarasov, could you comment on this, please?

@carblue
Copy link
Contributor

carblue commented Mar 5, 2017

@frankmorgner:
I assume, the reasoning is "housekeeping" in the code base, required in general, a good idea and I aim to participate later, but (though I'm not yet deep in "every" detail of OpenSC's SM) I advocate not to delete SM_MODE_ACL! Few hits by grep but huge impact: It's defining a state that seems to be currently used by cards (as of opensc.conf, some have secure_messaging: mode/type = acl, and all without mentioning mode use it as well, same as my upcoming driver acos5_64 wants to use it).

Your proposal actually seems to disable SM for those cards (if they rely on opensc.conf only for their sm_ctx.sm_mode) and gave rise to spot, that the mode = acl setting in opensc.conf doesn't get read/evaluated (opposed to evaluation for 'transmit'), but compensated by - in the sense of a default setting - (what You mentioned in the beginning): "... and sc_card_sm_load initializes card->sm_ctx.sm_mode to this value."
IMHO it's also a security feature of OpenSC to set (any suitable default) SM_MODE_* except SM_MODE_NONE when loading a SM module and thereby forcing a card to decide how to deal with SM.

@frankmorgner
Copy link
Member Author

Welcome to OpenSC! Is this the first time you're around? It's interesting, that you're caring for such an implementation detail. Are you using this flag in your SM module? Could you show what you're doing with it?

@carblue
Copy link
Contributor

carblue commented Mar 5, 2017

@frankmorgner:
Thanks for welcoming! I'm rarely around commenting, but regularly following some PRs and issues; we already communicated twice, last time ref. PR#814. When implementing a driver for OpenSC (capable of SM), sooner or later You get more and more into these details. Yes I plan to use it, if SM_MODE_ACL will still be there, but don't base Your SM_MODE_ACL-decision on that; (my experience with SM is that I got it basically working for ACOS5-64 within the OpenSC-framework, but it's not in final shape and not pushed for some weeks; the driver won't/can't use libsmm-local.so because establishing the secure channel is special with ACOS5-64, thus it has it's own SM-module; and yes, I'm intentionally not pointing You to code; not hard to find).

Don't get me wrong! I don't object deleting SM_MODE_ACL, if OpenSC decides that way for good reasons, but I do object the title "Unused SM_MODE_ACL" and removal "en passant".

You picked from my last comment exactly, what I don't consider an argument, leaving out any response about everything else I consider strong arguments (and leaving me surprised, that I wasn't able to convince in the first instance about what I consider an outright wrong #971, because this is true: (the probability ís high, that SM_MODE_ACL actually is NOT unused || You can not prove the contrary without extensive effort)
, and all that discussion to save 2 lines of code?).

Okay, one last trial:
If You are going on with Your proposal, than it is incomplete: You will also have to remove any mention of 'acl' in e.g. opensc.conf. Next is an excerpt where to begín, and all entries for cards with a secure_messaging section not explicitly requesting 'transmit' will have to be checked/drivers rewritten?:

excerpt, all are comments:
SM mode:
'transmit' -- in this mode the procedure to securize an APDU is called by the OpenSC general
APDU transmit procedure.
In this mode all APDUs, except the ones filtered by the card specific procedure,
are securized.
'acl' -- in this mode APDU are securized only if needed by the ACLs of the command to be executed.

mode = transmit;

Cheers, carblue

@frankmorgner
Copy link
Member Author

Sorry for not being more attentively. I'm looking forward for more SM implementations since the whole SM framework still seems to be a moving target.

In your response you seem to imply that the mode ACL means that SM calls should go to the SM module which then decides what or how to decrypt. This is not true. Whether and when the SM module is called (e.g. get_apdus) is a decision made by the specific card driver. Neither the IASECC nor the Authentic card make this decision based on the SM_MODE_ACL. That's why I stated that there is no meaningful code in OpenSC that uses this flag; not in the local SM module, not in a card driver, not in any of the common stuff.

If your card driver uses this flag to configure the SM module then this should be a driver configuration, not a global configuration option (remember: currently there is no card driver or sm module known that uses this flag). I can imagine that this flag is used inside some proprietary SM module. This kind of configuration should be managed by the SM module in this case. It should not seep through to OpenSC.

If I'm reading the SM module code correctly, the cards that currently use it, they are opening an SM channel directly after connecting to the card (sc_connect_card->sc_card_sm_check->sm_ctx.ops.open->module.ops.get_apdus in the card driver). The funny thing is that when sm_ctx.ops.open is done, all internal card drivers are setting the sm_mode to "transmit" (otherwise the SM routines would not be called before sending the APDUs). Again, you can see that the acl mode is not used.

The configuration entries for using the ACL mode have never been used anyway, because sc_card_sm_check parses the configuration for the "transmit" mode but not for the "acl" mode. Even if that was the case, the description of the so called acl mode is misleading. This SM mode is not coupled to any of the file attributes, let alone the ACLs.

All in all, removing the acl configuration from opensc.conf and the ACL flag should not change the behavior of any of the existing cards. It should not affect the local SM module. Both are not used anywhere in a meaningful way. None of the issues you pointed are applying, or, if I'm getting you wrong, please point me to it.

@carblue
Copy link
Contributor

carblue commented Mar 7, 2017

Probably You are right, that it might be possible to remove SM_MODE_ACL without changing any semantic (or with few adaptions only required), but I doubt it's wise to do so.
I'm switching perspective now to the driver/SM implementor for some background before coming back to the main topic:

I did some work on the acos5_64 SM implementation (some weeks ago, but postponed finalization in favour of other tasks since I got SM basically working, a really heavy birth; I didn't yet go as far as implementing get_apdus or get_sm_apdu yet, thus I won't comment on that; I don't expect big problems at this level).
An implementor is facing some other problems before getting to get_apdus or get_sm_apdu:
Next to difficulties with a flawed hardware's reference manual and vendors software which initializes a card/token in a way that prohibits SM, (in my case; now out of the way with my own initialization function) the following problem with SM is how to integrate into OpenSC, since the whole SM framework (You say:) "still seems to be a moving target"; I would call it: difficult to get into, because the subject needs even some more docs to read, decisions to make and there doesn't seem to be a mainstream OpenSC solution used, for quick guidance.
I read code of several SM-capable cards like card-dnie, card-epass2003, card-iasecc and card-authentic. To me, the approach of card-iasecc/card-authentic is the most appealing, one reason being they use a generic interface that could be/become an "umbrella" for more cards, e.g. the general solutions for config_get_keyset, though sadly I couldn't follow that closely, because ACOS5-64 establishes the secure channel in a way, that doesn't seem to fit (I'm not shure, having skimmed over old standard docs only) within CWA14890, GP-SCP or DH.
If You are familiar with that, I would like to know Your opinion about that https://github.com/carblue/acos5_64/blob/master/info/SessionKeyGenerationProdedure_ACOS5_64.png
What I did in the end is, go with the sm_context.sm_module.sm_module_operations-"API", "misuse" the sm_cwa_session struct somewhat, as I "squeezed" 24 byte keys into it (session_enc, session_mac, sm_cwa_keyset.enc, sm_cwa_keyset.mac), taking unused sm_cwa_token_data.k to hold excessive bytes; "squeezing" wouldn't have been neccessary though when using the less secure 16 byte key size option (acos does all SM-related mac/en-/decrypt based on 3des only).
Then I copied and adapted some code of what goes into libsmm-local.so for an acos5_64_specific "SM-module", but some functions like get_apdus aren't yet doing what they are intended for, just the skeletons, thus this is currently not active for SM but what I envision for the future.
If this where an internal driver, I would investigate in-depth and ask for advice if it is reasonable/feasable to go with smm-local.c, some acos5_64_sm_related.c and a PR.
For the real SM test, I went the easy/temporary/only-for-testing-purpose-route by implementing sm_ctx.ops.open and colleagues as required for working, again by-passing ops.get_sm_apdu (which only says: SM not required), but ops.read_binary and ops.update_binary are tailored for one-time-usage effective SM-testing. After the tests are done, the SM session get's closed, sm_ctx.ops.open and colleagues get NULLified and sm_ctx.sm_mode finally switched to SM_MODE_ACL (which may not be required, as You state; I won't check that now).

When I go on finalizing the SM code, I intend to do it this way: Switch SM on/off (SM-on-demand like IIRC card-iasecc does; this card's os seems to be quite similar to how acos operates) as the file's SecurityAccessConditions/acl will require for the operation in question.
Maybe it is as You state (I don't remember that), the SM_MODE_ACL is not coupled to any of the file attributes, let alone the ACLs: Then I will establish this coupling - and if I remember correctly Viktor Tarasov did exactly that too for card-iasecc - because acl bytes in FCI is the essential way how ACOS5-64 communicates the file access requirements to be fullfilled (the details are even more complex due to an additional layer of indirection (Security Environment File) and possibly also extended acls that are not bound to files but to their parentDF and focus on APDU contents that may need authorization).
And if performance tests show, that SM-on-demand is too bad, I'll do basically similar things but with a session-lifetime secure channel opened right in the beginning by SM_MODE_TRANSMIT.

I think, I'm aware what code should go into opensc (framework) and what has to be solved/decided specifically by dedicated card functions, and I'm a fan of pushing as much as possible common code into opensc (framework) as long as the growing complexity is managable.

My bird's eye view of OpenSC's SM is, that SM_MODE_TRANSMIT and SM_MODE_ACL have some common tasks to do, but each has it's own "API":
SM_MODE_TRANSMIT is connected to the sm_context.sm_card_operations-"API", requiring some individual? SM module (lets call cards using SM_MODE_TRANSMIT the "sm_card_operations-fraction"),
SM_MODE_ACL is connected to the sm_context.sm_module.sm_module_operations-"API", requiring either libsmm-local.so or some "equivalent" individual SM module like I do for acos5_64 and the functions to implement/export are at least those required by sc_card_sm_load and possibly some more (lets call cards using SM_MODE_ACL the "sm_module_operations-fraction"),
and both fractions are kind of mutually exclusive, if I remember correctly (except for very special scenarios, like I do for testing as outlined).

Maybe I catched a misconception as I analyze the sc_card_sm_check function differently:
At the last if statement, the 2 fraction's code flows divide:
None of the "sm_module_operations-fraction" (which are at least all cards following one of the secure_messaging sections of current git/master/opensc.conf.in) has/is allowed to configure opensc.conf with mode=transmit, thus none of them will call sc_connect_card->sc_card_sm_check->sm_ctx.ops.open !
Those cards don't need to and shouldn't implement for the "sm_card_operations-fraction"-API, unless they want to be a hybrid and can handle that.
Thus, what You call funny shouldn't happen in the regular case by convention, or bad things might happen !
Cards that want to be part of the "sm_card_operations-fraction" may set mode=transmit in opensc.conf yet none does in opensc.conf.in, conseqently those cards do this setting earlier, e.g. in cardxy_init. And any further setting to sm_mode = SM_MODE_TRANSMIT is superfluous.
I demonstrate the 2 different code flows with logs of opensc-tool -f : https://github.com/carblue/acos5_64/blob/master/info/log_demonstration_different_SM_MODE_settings

Now coming back to the original topic "removal of SM_MODE_ACL", my new understanding of what Your proposal is about/aiming at is:

You don't want to remove the sm_context.sm_module.sm_module_operations-"API", but just the "name" SM_MODE_ACL? Right?
Then You are creating a kind of "Lord Voldemort"/unmentionable name, something that still exists, but has no name any more.
As analogy from "Harry Potter", in D, this terminus is coined for a type: There, a Voldemort type is one that cannot be directly named outside of the scope it's declared in, but code outside the scope can still use this type by taking advantage of D's static type inference.
This is perfectly valid if required and I don't object Your proposal anymore if the sm_module_operations-"API" survives, but still the proposed removal makes no real sense to me: You save a few lines of code, but the "concept SM-on-demand"/API I erroneously synonymed with SM_MODE_ACL is still there and the problems with SM integration into OpenSC I outlined in the beginning are still essentially the same.
And I still stick to my statement, that very likely there are cards, that want to be in the "sm_module_operations-fraction", even if they can't anymore/don't need to name their mode (SM-on-demand), they are working at.

@viktorTarasov
Copy link
Member

My message is not an attempt to participate in the debates (there hardly could be the arguments against the fever of optimization and code purification).

I would like to explain the context where SM was implemented in OpenSC:

  • multi-application cards where the applications could have a different level of protections;
  • complex on-card object access mode, where could participate some external authorities (ex. using of crypto objects are allowed to user, but their update is done under SM);
  • different on-card objects (mostly keys) have different access mode -- protected and not protected can be placed side-by-side;
  • authority keys could be not known in the local context where card is used.

There from the idea to let the card to be used 'as normal' as far as possible, and only in the moments where it's really imposed by object's ACL, switch to the SM mode. That's for the 'SM_MODE_ACL' mode.

SM was implemented with the possibility to externalize the composing of SM secured APDUs.
SM functions could be:

  • static (implemented directly in card specific driver);
  • dynamic (implemented in loadable module):
    • 'local' module, that has knowledge of SM keys (ex. for Gemalto and Oberthur cards in OpenSC configuration file);
    • 'distant' module -- communicates with external entity to get secured APDU.

@carblue
Copy link
Contributor

carblue commented Mar 12, 2017

@viktorTarasov:

Thanks for Your background info. It's coming in the right moment and is helpfull as I design card/token-(re-)-initialization (skipping .profile for the moment) and how to populate a file's 7 access control bytes (each byte has a bit to yes/no force SM for the SC_AC_OP_* refered to + other bits that direct to a DF's Security Environment file record no. containing another authentication requirement such as internal pin file record no. xyz (| 0x80) or internal sym. key file's record no. xyz (| 0x80) verified/authenticated or both.

Occasionally, I would like to know Your view about:
An internal acos5_64 driver (ACOS5-64 OS allows all points of Your SM explanation) and with this https://github.com/carblue/acos5_64/blob/master/info/SessionKeyGenerationProdedure_ACOS5_64.png + host-challenge-based ssc counter maintained by cos, used as CBC's IV for the session keys ENC and MAC, available after a Mutual Authentication card<->host),

does it fit for 16 byte keys within the current structs (sm_??_session) or does OpenSC allow to make it fit (and e.g. increase sym. keysize to 24 bytes) and contribute code specific for acos5_64 to end up in smm-local module? Or is ACOS5-64 to divergent from the spirit of smm-local module? The problem then with an individual acos5_64_sm module, if I understood this right, would be, that both smm-local and acos5_64_sm module have to/do export some same function names and name clashing occures, or more precisely on Linux, the module loaded first among those 2 wins referring to calls, the other one being hidden. Depending on the usage scenario with more than 1 card/token it might happen then, that the "wrong" SM module is called. This seems to have happened to me on Linux (I will check this issue later again with a completed dynamic/local acos5_64_sm module).

With the current external acos5_64, in principle it's dynamic/local (though the current all-in-one external module does not distinct dynamic/static). With ACOS5-64, some module has to have knowledge of common 2 SM keys, i.e. those required by both parties card<->host for the Mutual Authentication. Once the/a new secure channel/SM is established and new Session Keys generated, ACOS5-64 doesn't impose where to go on composing of SM secured APDUs, 'local' or with a 'distant' module, as long as a possible 'distant' module gets passed ssc and the 2 session keys.
I think, what You called 'SM_MODE_ACL' and I synonymously also referred to as "concept SM-on-demand" is how I will currently continue for the external acos5_64 (having in mind that it might be turned into an internal driver some day; probably the best long-term solution once the driver is ready).

@viktorTarasov
Copy link
Member

@carblue
... I design card/token-(re-)-initialization (skipping .profile for the moment) and how to populate a file's 7 access control bytes (each byte has a bit to yes/no force SM for the SC_AC_OP_* refered to + other bits that direct to a DF's Security Environment file record no. containing another authentication requirement such as internal pin file record no. xyz (| 0x80) or internal sym. key file's record no. xyz (| 0x80) verified/authenticated or both.

The same in IAS/ECC standard:

  • there are SE SDOs (security data objects), that are pointing to the SM key objects;
  • SE can build the logical operations with the other SEs
  • an object's ACLs contain the references to SEs.

An internal acos5_64 driver (ACOS5-64 OS allows all points of Your SM explanation) and with this https://github.com/carblue/acos5_64/blob/master/info/SessionKeyGenerationProdedure_ACOS5_64.png + host-challenge-based ssc counter maintained by cos, used as CBC's IV for the session keys ENC and MAC, available after a Mutual Authentication card<->host),

Something like this is also in IAS/ECC standard.

does it fit for 16 byte keys within the current structs (sm_??_session) or does OpenSC allow to make it fit (and e.g. increase sym. keysize to 24 bytes) and contribute code specific for acos5_64 to end up in smm-local module? Or is ACOS5-64 to divergent from the spirit of smm-local module? The problem then with an individual acos5_64_sm module, if I understood this right, would be, that both smm-local and acos5_64_sm module have to/do export some same function names and name clashing occures, or more precisely on Linux, the module loaded first among those 2 wins referring to calls, the other one being hidden. Depending on the usage scenario with more than 1 card/token it might happen then, that the "wrong" SM module is called. This seems to have happened to me on Linux (I will check this issue later again with a completed dynamic/local acos5_64_sm module).

Currently the sizes of SM data type members (defined in 'sm.h') are fixed.
If you have other sizes of SM keys,
one way is to redefine these data and, for example, to use TLV type for all of them. This will need a serious refactoring of existing code.
Another way is to define a new SM data types, and then to make them accepted by the existing SM API and SM module. You can see that local SM module contains also the card specific part.

..
I think, what You called 'SM_MODE_ACL' and I synonymously also referred to as "concept SM-on-demand"

Yes.

frankmorgner added a commit to frankmorgner/OpenSC that referenced this issue Jan 24, 2018
frankmorgner added a commit to frankmorgner/OpenSC that referenced this issue Jan 24, 2018
frankmorgner added a commit that referenced this issue Jan 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants