16 Replies Latest reply on Feb 4, 2017 10:37 AM by Saravana Damodaram

    APDU Command and Secure Access Module (SAM) Development Using EMDK

    Alan Dimaano

      I'm relatively new to EMDK and Secure Access Module programming.

       

      I have a SAM that contains a key that I need to access an RF ID ... do you guys have any kind of sample codes that I can look into to do this?

       

      I'm also receiving a 'AV2 authentication failed' (Mifare SAM AV2) whenever I try to communicate with the SAM card. It gives me the impression that  I need to pass an authentication layer before I can access the key hosted in a DF sector of the SAM card.

       

      I really need help. I'm desperate.

       

      Below is the 'onOpened' code snippet of what I'm trying to do:

       

      ====================

       

      @Override
      public void onOpened(EMDKManager emdkManager) {

         this.emdkManager = emdkManager;

       

        Log.i("onOpened called", " ");

         status.append("\nApplication Initialized.");

       

         if (this.emdkManager != null) {

       

         secureNfcMgr = (SecureNfcManager) emdkManager

        .getInstance(EMDKManager.FEATURE_TYPE.SECURENFC);

       

         if (secureNfcMgr != null) {

       

         try {

         samType = secureNfcMgr.getAvailableSam();

       

         status.append(newline + newline + samType
         + " SAM is available on the device.");

       

         if (samType.equals(SecureNfcManager.SamType.MIFARE)) {

       

         mifareSam = (MifareSam) secureNfcMgr
         .getSamInstance(samType);

       

         mMifareDesfire = (MifareDesfire) secureNfcMgr
         .getTagTechInstance(SecureNfcManager.TagTechType.MIFARE_DESFIRE);

       

        MifareSam.SamMode samMode = mifareSam.connect();

        MifareSam.SamInfo samInfo = mifareSam.getSamInfo();

       

         // SamKey required for the SAM to Host authentication.

         SamKey samKey = new SamKey();

        samKey.keyNum = 0x08;

        samKey.keyVer = 0x01;

         byte[] KEY_AES128_DEFAULT = {0, 0, 0, 0, 0, 0, 0, 0,

         0, 0, 0, 0, 0, 0, 0, 0,};

         byte[] SELECT = {

        (byte) 0xC0, // CLA Class
         (byte) 0xA4, // INS Instruction
         (byte) 0x00, // P1 Parameter 1
         (byte) 0x00, // P2 Parameter 2
         (byte) 0x02,

        (byte) 0x4F00 // Select the
         };

         mifareSam.authenticateSam(KEY_AES128_DEFAULT, samKey, null);

       

         mifareSam.close();

       

         //setButtonEnabled(true);

         status.append(newline + newline + samMode

        + " SAM host authentication successful.");

         //statusTV.setText(status);
         textViewInfo.setText(status);

       

        } else if (samType.equals(SecureNfcManager.SamType.NONE)) {

       

         status.append(newline + newline
         + "SAM not available in the device");

       

        AlertDialog.Builder dlgAlert = new AlertDialog.Builder(

         this);

       

        dlgAlert.setMessage("Please insert the SAM into the device and try again.");

        dlgAlert.setTitle("Error Message...");

        dlgAlert.setPositiveButton("OK", null);

        dlgAlert.setCancelable(true);

        dlgAlert.create().show();

       

        dlgAlert.setPositiveButton("Ok",

         new DialogInterface.OnClickListener() {

         public void onClick(DialogInterface dialog,

         int which) {

       

        }

        });

        }

        } catch (SecureNfcException e1) {

       

        e1.printStackTrace();

         status.append(newline + newline + newline
         + "SecureNfcException Exception : "
         + e1.getResult().getDescription());

       

        } catch (MifareSamException e) {

       

        e.printStackTrace();

       

         //setButtonEnabled(false);

         status.append(newline + newline + "MifareSam Exception : "
         + e.getMessage());

         //statusTV.setText(status);
         textViewInfo.setText(status);

        Log.e("mifare error -- ", e.getMessage());

        }

       

        }

       

        }

       

       

      }

       

      ====================

        • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
          Bill Hecox

          Hello Alan, Have you tried the Secure NFC Sample app with your SAM card? I'm wondering if you may have a SAM card that is not provisioned correctly. We also have a programmers guide that may help. Secure NFC Programmer’s - Zebra Technologies Online Documentation

          1 of 1 people found this helpful
            • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
              Alan Dimaano

              Thank you, Bill.

               

              I have used the NFC Sample App and it returns the same error message. Either 'MifareSam Exception: Failure' or 'MifareSam Exception: AV2 Authentication Failed'

               

              I also followed the Online Documentation, and I think I have implemented all of them.

               

              But when I call the 'authenticateSam' method (mifareSam.authenticateSam(KEY_AES128_DEFAULT, samKey, null)), it throws the 'MifareSam Exception'.

               

              My theory is that:

               

              - I'm not authenticating correctly

              - I'm issuing a wrong command

              - I need to issue an APDU command

               

              I hope you can help me. Even if only on how to issue APDU commands using the EMDK.

                • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                  Bill Hecox

                  Hey Alan, thanks for the feedback.  I'm thinking it may be an issue with the SAM card.  How did you obtain the SAM and has it been provisioned to work the EMDK SecureNFC API's?

                    • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                      Alan Dimaano

                      It is a Mifare SAM AV2 from a client.

                       

                      We are making a proof of concept that will read a key from the SAM and authenticate data to communicate with an RF ID.

                       

                      The only instruction they gave us is that the secure key is saved in the SAM for us to get the details in the RF ID.

                       

                      Hope you can help.

                      • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                        Alan Dimaano

                        I modified my SamKey values and I'm getting a different error message.

                         

                        'MifareSam Exception: Invalid Key Length'

                         

                        Do you have instructions or error code lists that I can look into?

                         

                        Thanks!

                        • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                          Alan Dimaano

                          What does it mean if a SAM card is provisioned to use a certain API like EMDK?

                           

                          Even if the EMDK supports Mifare SAM AV2 and if it is not provisioned to used the API the SAM communication won't work?

                           

                          Hope you can help me with this.

                            • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                              Kanagal Raj Ramaswamy

                              As per my understanding, you are able to get the available SAM and this matches the SAM inserted (MIFARE) on the device. Then you can connect to SAM without any error.

                              When you called   MifareSam.SamInfo samInfo = mifareSam.getSamInfo(), what does it return? Does it provide the SAM details? Please can you share that info?

                               

                              The SAM will not have any authentication information out of the BOX from the Factory, normally the SAM will be personalized/provisioned by the system admin or other with authentication Key and other details based on there requirement. I am wondering did you receive the right SAM Key and authentication Key?. Please can you ensure that whether the key used in your application as the key which used during the personalization/provisioning?

                               

                              Let me how it goes to help you further.

                               

                              The below is the code snippet and which is perfectly works with my App and SAM:

                               

                              //EMDK: Implementing EMDKListener.onOpened interface.  EMDKManager Object returned in this call.

                                  @Override

                                  public void onOpened(EMDKManager emdkManager) {

                                      this.emdkManager = emdkManager;

                               

                               

                                      //EMDK: Get the feature object such as SecureNfcManager object for accessing the feature.

                                     secureNfcMgr = (SecureNfcManager) emdkManager.getInstance(FEATURE_TYPE.SECURENFC);

                               

                               

                                      //EMDK: Initialize and authenticate SAM

                                      initSam();

                                  }

                               

                              //EMDK: Implementing the SAM authentication. Once the SAM is authenticated, and it will be valid till the device reboot.

                                  void initSam() {

                                      if (secureNfcMgr != null) {

                               

                                         MifareSam mifareSam = null;

                                          try {

                                              SecureNfcManager.SamType samType = secureNfcMgr.getAvailableSam();

                                              displayStatus(samType + " SAM is available on device");

                               

                                              if (samType.equals(SecureNfcManager.SamType.MIFARE)) {

                               

                                                  mifareSam = (MifareSam) secureNfcMgr.getSamInstance(samType);

                               

                                                  MifareSam.SamMode samMode = mifareSam.connect();

                               

                                                  // AuthKey required for SAM to Host authentication

                                                  byte[] authKey = new byte[0x10];

                               

                                                  // SamKey required for the SAM to Host authentication.

                                                  SamKey samKey = new SamKey();

                                                  samKey.keyNum = 0x00;

                                                  samKey.keyVer = 0x00;

                               

                                                  mifareSam.authenticateSam(authKey, samKey, null);

                               

                                                  displayStatus("SAM is authenticated. App is ready for Transaction");

                               

                                              } else {

                                                  displayStatus(samType + " is not supported by this Application");

                                              }

                                          } catch (SecureNfcException e) {

                                              e.printStackTrace();

                                              displayStatus("Error:" + e.getMessage());

                                          } catch (MifareSamException e) {

                                              e.printStackTrace();

                                              displayStatus("Error:" + e.getMessage());

                                          }

                               

                                        if(mifareSam != null) {

                                              try {

                                                  mifareSam.close();

                                              } catch (MifareSamException e) {

                                                  e.printStackTrace();

                                              }

                                          }

                                      } else {

                                          displayStatus("Secure NFC feature is not supported or error occurred.");

                                      }

                                  }

                                • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                                  Alan Dimaano

                                  Thank you for your response.

                                   

                                  Attached is the SAM Info I got from the debug mode.

                                   

                                  Do I need a successful authentication first before I can talk to the SAM?

                                    • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                                      Kanagal Raj Ramaswamy

                                      YES, you must have successful SAM authentication to communicate with the Tag. The authentication call performs the mutual authentication between the Host system(Mobile Device) and SAM. The authentication must and this authentication will be valid till the mobile device reboot.

                                       

                                      I believe you didn't receive the correct SAM Key and Authentication key for the SAM you have received. Please work your those who provided the SAM to you.

                                        • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                                          Alan Dimaano

                                          Thank you for this response, very much appreciated.

                                           

                                          It's just weird that I would need authentication because the client said that the SAM card is not locked and that I will only have to get a key (saved in a DF) from the SAM card to communicate with the RF ID.

                                           

                                          Though they said, that they follow the ISO 7816 format of APDU, they have proprietary APDU commands.

                                           

                                          Does all of these matter for me to have a successful communication with the SAM?

                                           

                                          Do you have a sample APDU command (that I can pass to PassThruApduProcessor) to access a DF/EF on the SAM card?

                                           

                                          Hope to hear from you soon.

                                            • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                                              Kanagal Raj Ramaswamy

                                              Usage of PassThruApduProcessor API requires the complete knowledge of APDU specification.

                                                • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                                                  Marek Trusinski

                                                  From the information you have provided I am assuming you are
                                                  using Mifare SAM AV2

                                                  See below explanation of the APDU and  APDU Mifare SAM
                                                  command Get Version. 

                                                   

                                                  APDU FRAME-

                                                  Sam Command: | CLA | INS | P1 | P2 | Lc | DATA | Le |

                                                   

                                                  CLA -> 80 (for logical channel 0)

                                                  INS -> Instructions

                                                  P1, P2 -> Parameters

                                                  Lc -> Length of Data

                                                  Le -> Expected Length

                                                   

                                                  SamResponse command frame: | Data | SW1 | SW2 |

                                                  SamResponse (For Successful Execution): | Data | 90 | 00 |

                                                  SamResponse (Successful Execution + additional frame): |
                                                  Data | 90 | af |

                                                   

                                                   

                                                  1. Get Version:

                                                   

                                                  CLS  INS   P1   P2 
                                                  Lc  <---------Data-------->  Le

                                                   

                                                  Sam Command: | 80 | 60 | 00 | 00 | NULL | 00 |

                                                  SamResponse: | (04 01 01 03 02 28 01 04 01 01 03 02 28 01 04
                                                  2f 09 19 d6 28 80 91 57 74 00 00 0e 09 0a 00 a2) | 90 | 00 |

                                                   

                                                  1. Get Key Entry:

                                                  Sam Command: | 80 | 64 | 00 | 00 | NULL | 00 |

                                                  SamResponse: | (00 00 00 00 00 00 00 00 00 ff 20 00 00) | 90
                                                  | 00 |

                                                   

                                                   

                                                   

                                                  ***********************************

                                                  1. AV2 SAM_AuthenticateHost:

                                                   

                                                  /*

                                                   

                                                  The command SAM_AuthenticateHost (INS=A4h) is used to run a
                                                  mutual authentication between SAM and host system. It consists of three parts.
                                                  Such an authentication proves that both the SAM and the host contains the same
                                                  keys. At the end of the authentication, session keys for secure messaging are
                                                  generated.

                                                   

                                                  The general sam command structure is given below

                                                  Sam Command: | 80 | a4 | 00 | 00 | 03 | Data | 00 |

                                                   

                                                  However, data field will be different for different parts.

                                                   

                                                  Part 1: Data = KeyNo || Key Ver || HostMode

                                                            
                                                  Response Data = Rnd2

                                                   

                                                  Part 2: Data = MACHost || Rnd1

                                                            
                                                  Response Data = MACSAM1 || EncSAM1

                                                   

                                                  Part 3: Data = EncHost

                                                            
                                                  Response Data = EncSAM2

                                                   

                                                  MACHost (8 bytes) = MACt(Kx, Rnd2 || HostMode || ZeroPad)
                                                  with ZeroPad = 000000h (3 bytes)

                                                   

                                                  Rnd1 = 12 bytes random number

                                                   

                                                  MACSAM1 (8 bytes) = MACt(Kx, Rnd1 || HostMode || ZeroPad)
                                                  with ZeroPad = 000000h (3 bytes)

                                                   

                                                  EncSAM1 (16 bytes) = E(Kxe, RndB)

                                                   

                                                  EncHost = E(Kxe, RndA || RndB')

                                                  with RndB' = RndB << 2

                                                   

                                                  EncSAM2 (16 bytes) = E(Kxe, RndA')

                                                  with RndA' = RndA << 2

                                                   

                                                  An example of the authentication is shown below. Note that
                                                  for Part2 and Part3 data field will change.

                                                   

                                                  */

                                                  1. 3.1 AV2 AuthenticateHostPart1:

                                                  Sam Command: | 80 | a4 | 00 | 00 | 03 | (00 || 00 || 00) | 00
                                                  |

                                                  SamResponse: | (11 0d 65 8b f3 00 c4 94 e3 95 78 44) | 90 |
                                                  af |

                                                   

                                                  1. 3.2 AV2 AuthenticateHostPart2

                                                  Sam Command: | 80 | a4 | 00 | 00 | 14 | (be 72 27 40 24 ff
                                                  5d db || 8e fb 4a e7 bc f4 b5 44 cf 14 40 15) | 00 |

                                                  SamResponse: | (50 05 8d 55 95 59 d5 8f || 40 71 4b 4b 9e 09
                                                  75 a3 40 ee 59 dd a6 8c 01 4a) | 90 | af |

                                                   

                                                  1. 3.3 AV2 AuthenticateHostPart3

                                                  Sam Command: | 80 | a4 | 00 | 00 | 20 | (55 d8 19 7d 83 62
                                                  14 bb 9a 7b 21 8a f5 29 0a 54 70 4f b3 ca dd cf 18 eb 90 af 7b 25 69 e3 c3 43)
                                                  | 00 |

                                                  SamResponse: |(08 72 4d a4 63 fc c3 40 3f 12 f4 f4 6d 6c 70
                                                  0a) | 90 | 00 |

                                                  1 of 1 people found this helpful
                                • Re: APDU Command and Secure Access Module (SAM) Development Using EMDK
                                  Saravana Damodaram

                                  Getting the following response for Get Key entry :

                                  01 01 01 36 00 FE 00 00 01 FF 00 44

                                   

                                  Please let me know how to parse through for the Key number and key version for the Host authentication.