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

wrap_command() for scp03 is incomplete. #20

Open
kaoh opened this issue Mar 18, 2020 · 8 comments
Open

wrap_command() for scp03 is incomplete. #20

kaoh opened this issue Mar 18, 2020 · 8 comments

Comments

@kaoh
Copy link
Owner

kaoh commented Mar 18, 2020

Although the function encrypt the data and generate the mac, it doesn't copy them into wrappedApduCommand bytes array.

Reported by: programatix

@kaoh
Copy link
Owner Author

kaoh commented Mar 18, 2020

Can you please be more verbose? I see a memcpy instruction in https://sourceforge.net/p/globalplatform/git/ci/master/tree/globalplatform/src/crypto.c#l1635

Can you provide a fix and test it?

Original comment by: kaoh

@kaoh
Copy link
Owner Author

kaoh commented Mar 18, 2020

If the security level == 0x03 (encrypt and mac), the encrypted data and the mac is copied, but the CLA secure messaging bit is not set in the CLA, meaning if CLA == 0x80, then it remains as 0x80. I can't confirm whether the encrypted data and mac is correct or not (yet).

Command --> 80E40080094F07D0D1D2D3D4D50100
Wrapped command --> 80E40080207022781B2AA7CDE5F993060FBB3D992CB124AC02F64DF917B386A98102897D3B00

The CLA 80, remains as 80. It should be 84.

If the security level == 0x01 (mac only), the mac is not copied. Also, somehow the data is corrupted. Similar to the above, the CLA is left unchanged too. Below is the log,

Command --> 80E40080094F07D0D1D2D3D4D50100
Wrapped command --> 80E40080094F798A80618A41003900

The CLA 80, remains as 80. It should be 84.
The original data 4F07D0D1D2D3D4D501 has been corrupted to 4F798A80618A410039.

I'm currently working on the card side of SCP03 and I've switched from gpshell to GlobalPlatformPro as the testing tool. After I finished implementing the card side, I'll return and try to fix the implementation in gpshell.

Original comment by: programatix

@kaoh
Copy link
Owner Author

kaoh commented Mar 18, 2020

So far I have not found an indication what could be wrong. Actually in wrap_command

there is a condition:

|| ((secInfo->secureChannelProtocolImpl != GP211_SCP03_SECURITY_LEVEL_NO_SECURE_MESSAGING)
				&& (secInfo->secureChannelProtocol == GP211_SCP03))) {

which should set the CLA: wrappedApduCommand[0] = apduCommand[0] | 0x04;

Maybe something is not passed correctly between some functions calls in the code. It could also be that gpshell is not prepared for SCP03 and not doing this correctly.

Original comment by: kaoh

@kaoh
Copy link
Owner Author

kaoh commented Mar 18, 2020

Ah, I see the issue with CLA not changed. I have set the secureChannelProtocolImpl aka "i" for my card to 0x00 as I haven't implemented RPDU enryption yet (card side).

According to table 5-1 of GPC_2.3_D_SCP03_v1.1.2_PublicRelease.pdf, bits 6 and 7 determine whether there is R-MAC and R-ENCRYPTION only. There is no mention (in any of the bits) whether there is C-MAC and C-ENCRYPTION or not. So, I'm taking that no matter what is the value of "i", C-MAC and C-ENCRYPTION must be supported.

However, gpshell assumed that if "i" == 0x00, then C-MAC and C-ENCRYPTION is not supported. Another thing I want to note (lines 1538 to 1547), shouldn't it check secInfo->securityLevel instead of secInfo->secureChannelProtocolImpl as in lines 1521 to 1524?

Original comment by: *anonymous

@kaoh
Copy link
Owner Author

kaoh commented Mar 18, 2020

But isn't the selecurityLevel used for this detection? Is this set when calling the functions?

From gpshell.c:

 status = GP211_mutual_authentication(cardContext, cardInfo,
                                                     optionStr.key,
                                                     optionStr.enc_key,
                                                     optionStr.mac_key,
                                                     optionStr.kek_key,
                                                     optionStr.keySetVersion,
                                                     optionStr.keyIndex,
                                                     optionStr.scp,
                                                     optionStr.scpImpl,
                                                     optionStr.securityLevel,
                                                     optionStr.keyDerivation,
                                                     &securityInfo211);
                                                     

Regarding the comparison in line 1538: It might be safer to also include secInfo->securityLevel == SCP02 && ... before the secureChannelProtocolImpl comparisons.

I think R-MAC and R-ENC is still missing in crypto.c

Original comment by: kaoh

@kaoh
Copy link
Owner Author

kaoh commented Mar 18, 2020

From what I understand, secureChannelProtocolImpl aka the "i" value determine what feature the card supports for the protocol (scp02, scp03 and etc). This is returned by INITIALIZE UPDATE for SCP03 only. So for other protocols, it must be obtained by GET DATA which gpshell does. Each SCPxx has its own "i" definitions.

This actually determine what the securityLevel can be accepted during EXTERNAL AUTHENTICATION (P1). So, if it the "i" states R_ENCRYPTION and/or R_MAC not supported, and they are enabled in securityLevel, the card should reject the command with 0x6A86 (incorrect P1P2).

After EXTERNAL AUTHENTICATION, in this case the wrap_command function, it should determine whether to perform C_MAC, C_DECRYPTION, R_MAC and/or R_ENCRYPTION (or anything that related to them) based on the securityLevel value it sent to the card. In the case of setting the secure messaging bit in CLA, it should be determined by securityLevel value.

Original comment by: *anonymous

@kaoh
Copy link
Owner Author

kaoh commented May 18, 2020

There have been several code updates for SCP03. It works now for C-MAC and C-DEC and several examples like installation and status. R-MAC and R-ENC was added, but my test card does not accept it. You can give it a try.

Original comment by: kaoh

@kaoh
Copy link
Owner Author

kaoh commented Jun 21, 2020

Only R-MAC and R-ENC is causing issues. No solution so far.

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

No branches or pull requests

1 participant