Too many passwords to remember? Use KeePassNFC to make your password management super easy.

KeePassNFC is a free open source implementation of the KeePass Password Safe for Android,which helps you to manage your passwords in a secure way.

Please see this article to know how to use KeePassNFC step by step.

SecureChannel.unwrap fails in JCIDE simulator when no data present

JCIDE related questions and answers.

Moderator: product

kosullivan
Posts: 16
Joined: Mon Jun 29, 2015 9:03 pm
Points: 222
Contact:

SecureChannel.unwrap fails in JCIDE simulator when no data present

Postby kosullivan » Sun Sep 10, 2017 10:47 pm

Hi,

I've implemented GP SecureChannel handling in an applet that enforces encryption and mac (CEnc+CMac) on the incoming command data. This is generally working fine but in the JCIDE simulator, the call to unwrap() fails when there is no CDATA in the APDU. I've then tested this on several real cards and it works as expected.

The source code to demonstrate this is below. It shows a simple check for the CEnc+CMac attributes then has two valid INS commands.
00000000 should work always
00010000 should work only when in an encrypted/mac'd session

I suspect that this might be a bug in the simulator?

Thanks,
Ko

EDIT: Fixed a compilation bug in the example.

Code: Select all

package SecureChannelTest;

import javacard.framework.*;
import org.globalplatform.*;
import javacardx.crypto.*;

public class SecureChannelTest extends Applet
{
   // Holds our secure channel
   private SecureChannel secureChannel;

   // GlobalPlatform instructions for establishing a Secure Channel
   private static final byte INS_GP_INITIALIZE_UPDATE      = (byte) 0x50;
   private static final byte INS_GP_EXTERNAL_AUTHENTICATE   = (byte) 0x82;

   public static void install(byte[] bArray, short bOffset, byte bLength)
   {
      new SecureChannelTest().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
   }
   
   public void process(APDU apdu)
   {
      if (selectingApplet()) return;
      
      byte[] buffer = apdu.getBuffer();

      // Get a reference to the GlobalPlatform SecureChannel
      if (secureChannel == null) secureChannel = GPSystem.getSecureChannel();   
      
      short length = apdu.setIncomingAndReceive();

      boolean isAuthenticated = false;
      
      // Decrypt and Verify any commands that are wrapped in a GP SecureChannel with CEncCMac
      final byte SC_MASK = SecureChannel.AUTHENTICATED | SecureChannel.C_DECRYPTION | SecureChannel.C_MAC;
      if ((secureChannel.getSecurityLevel() & SC_MASK) == SC_MASK) {
         // Unwrap, including the entire APDU which is required for verifying the MAC
         secureChannel.unwrap(buffer, (short)0, (short)(ISO7816.OFFSET_CDATA + length));                  
         // Now flag the command as being authenticated
         isAuthenticated = true;
      }

      switch (buffer[ISO7816.OFFSET_INS])
      {

      // GP commands
      case INS_GP_INITIALIZE_UPDATE:
         secureChannel.resetSecurity();
         length = secureChannel.processSecurity(apdu);
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, length);
         break;
         
      case INS_GP_EXTERNAL_AUTHENTICATE:
         length = secureChannel.processSecurity(apdu);
         apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, length);
         break;

      
      // This INS can be executed by anyone
      case (byte)0x00:
         // TODO: Do something here
         break;

      // This INS requires an authenticated session
      case (byte)0x01:

         // Check if we have an appropriately secured session
         if (!isAuthenticated) ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
         
         // TODO: Do something here
         break;
         
      default:
         ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
      }
   }

   public void deselect() {      
      // Reset any security domain session (this is suggested in the documentation for resetSecurity)
      if (secureChannel != null) secureChannel.resetSecurity();      
   }

}

kuafu
Posts: 28
Joined: Thu Jun 25, 2015 2:09 am
Points: 255
Contact:

Re: SecureChannel.unwrap fails in JCIDE simulator when no data present

Postby kuafu » Mon Sep 18, 2017 3:24 am

Why the CLA isn't 04 . If cla is 04 ,then it's all right.

kuafu
Posts: 28
Joined: Thu Jun 25, 2015 2:09 am
Points: 255
Contact:

Re: SecureChannel.unwrap fails in JCIDE simulator when no data present

Postby kuafu » Mon Sep 18, 2017 3:30 am

Code: Select all

  final byte SC_MASK = SecureChannel.AUTHENTICATED ;// SecureChannel.C_DECRYPTION | SecureChannel.C_MAC;
      status = secureChannel.getSecurityLevel();
      if ((status & SC_MASK) == SC_MASK) {
               // Unwrap, including the entire APDU which is required for verifying the MAC
         secureChannel.unwrap(buffer, (short)0, (short)(ISO7816.OFFSET_CDATA + length));                 
         // Now flag the command as being authenticated
         isAuthenticated = true;
      }
   


Code: Select all

>> 00 00 00 00 (APDU CASE1)
<< 90 00

>> 00 01 00 00 (APDU CASE1)
<< 90 00



It's working well when 00 01 00 00 .

kosullivan
Posts: 16
Joined: Mon Jun 29, 2015 9:03 pm
Points: 222
Contact:

Re: SecureChannel.unwrap fails in JCIDE simulator when no data present

Postby kosullivan » Mon Sep 18, 2017 7:37 am

Thanks kuafu for checking this! I'm not sure why but I'm not getting the same results you are.

Apologies, my sample APDU's did not include the CLA=04, but I have been testing with this. Here's an APDU script of the whole session with notes

I am executing this using the JCIDE simulator (tried both A40CR and eJava Token) and this failure occurs, but when I load it onto a real smartcard (I'm using G&D SmartCafe 3, 6.0, 7.0 and 7.1's as well as NXP JCOP J3A080 and NXP P60's) and they all work completely as expected.

Code: Select all


// SELECT AID
> 00 A4 04 00 06 11 22 33 44 55 00 00
< 90 00

// INS 00 (No auth required, no data)
> 00 00 00 00
< 90 00

// INS 01 (GP auth required, no data)
> 00 01 00 00
< 69 82 // Expected result = 6982 as we are not authenticated yet

// GP Authenticate SCP02 i=15 w/CEnc+CMac, key = 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
> 80 50 00 00 08 40 58 BF 47 8C A7 91 B5 00
< 00 00 00 00 00 00 00 00 00 00 FF 02 00 05 70 64 69 F0 A9 94 DF D3 16 79 98 A7 13 31 90 00
> 84 82 03 00 10 E0 FC 18 61 3F 20 51 8D 68 7E C0 9C 52 9C 50 04
< 90 00

// INS 00 (No auth required, WITH data = 'AA', encrypted and MAC'd w/CLA=04)
> 04 00 00 00 10 65 7E 78 65 7C A5 5F 36 68 8C FC AE EF 23 2B A3
< 90 00

// INS 01 (GP auth required, WITH data = 'AA', encrypted and MAC'd w/CLA=04)
> 04 01 00 00 10 65 7E 78 65 7C A5 5F 36 ED EC F2 71 EE C6 76 A0
< 90 00 // Expected result = 9000, which means our auth verification works

// INS 00 (No auth required, no data, encrypted and MAC'd w/CLA=04)
> 04 00 00 00 08 B0 2F B7 40 41 C7 1B 94
< 69 82 // Expected result = 9000, but fails on the unwrap() call!

// INS 01 (GP auth required, no data, encrypted and MAC'd w/CLA=04)
> 04 01 00 00 08 06 8B 2C 59 AE C6 71 A4
< 69 82 // Expected result = 9000, but fails on the unwrap() call!


So as you can see with the last 4 APDU's, when data is supplied ('AA' but it could be anything) the unwrap call succeeds and the command works as expected, but without data I believe it fails on either the decryption or the MAC validation.

Are you using the latest version of JCIDE? I'm using v2.0.1.70 build 2016-03-20 (the download archive shows v1.0.5.39).

kuafu
Posts: 28
Joined: Thu Jun 25, 2015 2:09 am
Points: 255
Contact:

Re: SecureChannel.unwrap fails in JCIDE simulator when no data present

Postby kuafu » Mon Sep 18, 2017 9:58 pm

Code: Select all

//instanceaid = 11223344556601

//Select File                           (defined by ISO/IEC 7816-4)
00A4040007 11223344556601
9000

//Initial Update                                    (defined by GP)
8050000008 73FD018206531155
00000000000000000000FF020002F57382FF8D1D1E1015FB30F70513
9000

//External Authenticate                            (defined by GP)
8482030010 F914438C2854922D76733A46AFF798E1
9000

//this command not send to card, only display to scrren for next script, return data format 0x10 SessionSENCKey, 0x10 SessionCMACKey, 0x10 SessionCDEKKey

//External Authenticate                            (defined by GP)
8482030010 F914438C2854922D76733A46AFF798E1
ADC1163BA2A147FBB84BF44C8676FB7D3E06B1C8FCFD788A573B9A9889D0CA50FC01096B6DB13ADEE0D4CB61D03FD3AA
9000


//not defined instruction
0400000010 9B16598FF33DB862D12B05D70BDB5361
9000

//not defined instruction
0401000010 9B16598FF33DB862D18B458235A7A275
9000


It's odd. Why the LC in your 08, but not 10.

kuafu
Posts: 28
Joined: Thu Jun 25, 2015 2:09 am
Points: 255
Contact:

Re: SecureChannel.unwrap fails in JCIDE simulator when no data present

Postby kuafu » Mon Sep 18, 2017 10:52 pm

D.3.4 APDU Data Field Encryption and Decryption
E.4.6 APDU Command Data Field Encryption and Decryption

In D.3.4 and E.4.6 . May be has the detail that you need.


Return to “Questions & Answers”

Who is online

Users browsing this forum: No registered users and 1 guest

JavaCard OS : Disclaimer