Amadis

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 16 Next »

This section is meant to help technical teams to integrate Agnos CL kernels onto their own framework using a CL entry point. The complexity of this task lies on the lake of standardization when time comes to certify a CL kernel. Today, CL L2 TA are executed in a fully integrated fashion so that CL kernels are submitted along with the same entry point (or a similar software component) that was used to qualify them. So, the level of coupling between these nodes may be important. Consequently, porting an Agnos CL kernel on a new framework may be difficult if the software contract between with the entry point is not normalized. Since all platforms and frameworks are different, that kind of porting will always be a unique task (using a reference entry point to certify any CL kernels would have been much more structuring). As such this section does not intend to cover all aspects of the an integration process but instead should be considered as a tool to start with. Further discussions should take place to understand all the specifics of the project.

Requirements

The coupling between any entry point and an Agnos CL kernel will require some glue code to act as a communication channel between those two elements. Not only this code will be responsible for conveying the information from one point to another but also for converting those data from one format to another. In the following sections, let's call this glue code the “wrapper”. The following sections describe the mandatory elements for a successful transaction:

  • A proper Architecture

  • The Data Structures that need to be instantiated and the structure elements that must be filled

  • The Functions that need to be called

Architecture

The view below is a logical model presenting how an Agnos CL kernel is integrated onto an EMV Framework running a Contactless Entry Point.

Strategy

In order to leverage as much as possible on Agnos Framework and existing code, the strategy is to port the minimum software parts required to run a kernel in a standalone mode. Along with the kernels, there are three components that are mandatory:

  1. Agnos (see Agnos) which is a library encapsulating EMV processing that doesn’t need to be modified

  2. AgnosMW (see Agnos MW) which is a library encapsulating EMV data management that doesn’t need to be modified

  3. GPI (see GPI) which is a HAL that needs to be adapted to the targeted platform API

And there will two levels of integration for that task:

  1. High Level implementing the contactless entry point API in order to integrate an Agnos kernel (the wrapper)

  2. Low Level integrating the hardware API to access to platform's services

High Level interface (entry point integration)

Agnos kernels are pretty much simple by design. Their API (a.k.a AFS services) is:

  • afsInitialize(tInterface* interface)

  • afsWhatIsYourKernelId: not used in that context of integration

  • afsWhatIsYourVersion: not used in that context of integration

  • afsPreprocessing(tEntryPointConfigurationData *entryPointData, tEntryPointIndicators *riskParameters, tPaymentContext *payment): used only if a kernel supports preprocesing stage (C3 alike specification)

  • afsPerformTransaction(tPaymentContext* payment, tOutComeParameter* outcome)

  • afsRelease()

At Agnos Framework runtime, a kernel is registered onto the framework thanks to the AFS services listed above. Then, a kernel is activated once a corresponding card has been detected by the entry point. n activation, a kernel runs its logic (specifications implementation) using:

  • Internal mechanisms like limit controls, torn management, track calculations, …

  • EMV services supported by Agnos, the EMV library implementing EMV core features for contact an contactless

  • Platform services supported by GPI (CAD/SPED/HSM parts), the HAL that is adapted to the device running Agnos

Switching to a new framework, the High Level porting consists in:

1.Developing an “empty” kernel implementing only the infrastructure → The first task is to understand the software mechanisms not related to functional aspects

2. Adapting the framework's kernel activation to afsPerformTransaction → The second task is to validate that all the pre-conditions required to run an Agnos kernel will be fulfilled at activation time

3.Developing a first version of a kernel → The third task is to prototype rapidly an Agnos kernel instantiation into the framework.

Low Level (platform integration)

This part of the project is close to what Agnos projects usually consist in (see Agnos Framework Porting). There is an exception: the GPI will be partially ported because the porting scope is on the kernels only. Basically, Agnos CL kernels requires:

  • gpiRemovalProcedure

  • gpiBeep

  • gpiAdvancedDisplay

  • gpiGetPrivateScratchPAD (if torn supported)

Below the kernels (see logical architecture), Agnos requires:

  • gpiExchangeAPDU

  • gpiGetEMVCertificate

  • gpiGetEMVCRL

  • gpiSHAInit

  • gpiSHAUpdate

  • gpiSHAFinal

  • gpiRsaComputation

  • gpiGetRandomNumber

  • gpiGetRAMForTags

  • gpiGetRAMForUnknownTags

Data Structures

4 structures need to be instantiated:

  1. tOutComeParameter (see paymentMW.h)

  2. tDataExchangeList (see paymentMW.h and dataxchng.h)

  3. tPaymentContext (see paymentMW.h)

  4. tTransactionalContext (see agnos.h)

The tOutcomeParameter structure will mainly be used as an output structure to feed the Entry Point back with the transaction outcome. Only one field need to be filled in before the transaction starts:

  • tOutcomeParameter.mFieldOffReq = 0

Note: the zeroisation of the mFieldOffReq element must be done after the pmwInitializeOutComeParameter function has been called.

The tDataExchangeList structure will be used to store data elements (TLVs mostly) when Data Exchange feature is required. It doesn’t need to be filled before the transaction starts but needs to be attached to a payment context (tPaymentContext structure).

The tPaymentContext structure is the most important one. It holds all the transaction related information (e.g. the pieces of information that may vary upon each transaction). Below is the list of the structure fields that need to be filled before the transaction can start:

  • tPaymentContext.mDataExchange.mDEList (a tDataExchangeList structure needs to be attached)

  • tPaymentContext.mCashBack (pointer to a cashback value, even if 0)

  • tPaymentContext.mAmount (pointer to an amount value, even if 0)

  • tPaymentContext.mDataExchange.mError.mSW1SW2 (value of the FINAL SELECT response status word)

  • tPaymentContext.mTransactionCurrencyCode

  • tPaymentContext.mTransactionCurrencyExponent

  • tPaymentContext.mTransactionType

  • tPaymentContext.mEMVContactless

  • tPaymentContext.mTransactionDate

  • tPaymentContext.mTransactionTime

  • tPaymentContext.mRID

The tTransactionalContext structure is mostly filled by the kernel itself but still a few fields need to be prepare by the wrapper:

  • tTransactionalContext .mTransactionDate (same information as the tPaymentContext structure)

  • tTransactionalContext .mTransactionTime (same information as the tPaymentContext structure)

  • tTransactionalContext .mPinTimeOut (in seconds)

Functions

To complete the selection process (if a kernel's specification supports the preprocessing as per EMVCo books A/B) the wrapper must call the following function (APIs):

void afPreprocessing(tEntryPointConfigurationData *entryPointData, tEntryPointIndicators *riskParameters, tPaymentContext *payment)

This function will calculate the risk parameters required by the entry point to complete the selection process.

To prepare the transaction context and start the transaction the wrapper must call a certain number of functions (APIs):

void pmwInitializePaymentContext(tPaymentContext *ctx)
void pmwInitializeOutComeParameter(tOutComeParameter *outcome)

These two functions will prepare and initialize the tPaymentContext and tOutcomeContext structures that must be declared in the wrapper.

tGPIError gpiInitialize(const char* transactionLogName)
tGPIError gpiInitializeHSM(const char* CertificateFilesName, const char* CertificatesRevocationListFileName,const char* ExceptionFileName)

These functions will initialize the GPI library with the different file paths it requires for processing.

tAgnosError agnSetAgnosDatabase(tSessionId session, const tByte *TLV, const tWord TLVLen)

This function should be called to provide the kernel with all the tags corresponding to the combination's configuration that has been selected by the Entry Point before kernel's activation.

void afsInitialize(tInterface *interface, void *parameters)

This function can be called with its parameters set to NULL and NULL.

tAgnosError agnOpenSessionCL(
const tString smartcardReaderName, const tString pinPadName, const tString applicationId, 
const tTransactionalContext *txnContext, tBoolean setEMVTag, tSessionId *session, 
tBoolean clipping, tBoolean sred)
 
tAgnosError agnSetAID(tSessionId session, const tByte *AID, const tWord AIDLen)
tAgnosError agnSetExitState(tSessionId session, tAgnosState exitState)

Important: Depending on the contactless framework implementation, the entry point might or might not performed the Final Select. If the Final Select has been performed right after PPSE selection, then agnSetExitState must be called with NO_SELECT_FINAL as the second argument.

At this point the transaction can be started with:

void afsPerformTransaction(tPaymentContext *payment, tOutComeParameter	*outcome)

Once the transaction has ended and all data has been transferred to the Entry Point, the wrapper can call the following functions:

tPaymentError pmwCloseEMVSession(tSessionId session)
tGPIError gpiRelease(void)

Note: in case the wrapper is a volatile entity (e.g. a library) then all the above functions must be called each time. In case the wrapper is a non-volatile entity (e.g. binary / daemon running continuously) then some of the functions must be called only once at start-up to avoid unnecessary workload:

  • gpiInitialize

  • gpiInitializeHSM

Same applies to a function that need to be called only before the wrapper fully stops:

  • gpiRelease

Pseudo-code Sequence (preprocessing a transaction)

If the preprocessing is supported by a specification, the entry point integrating the corresponding Agnos CL kernel will be calling afsPreprocessing several times.

static tEntryPointIndicators riskParameters[numberOfMaxSession]; // Store TTQ copy (among other flags) so that it can be fetched during actual card processing
// NumberOfMaxSession reflects the maximum number of times the entry point will be calling the preprocessing for a given transaction type
tPaymentContext payment;
tByte i; // session identifier corresponding to a CL combination
 
//
// At EACH ENTRY POINT CALL triggering, start preprocessing (i.e. once per eligible [kernel Identifier,AID Identifier] for a given transaction type)
//
// BEGIN ------------------------
 
// Reset payment context
pmwInitializePaymentContext(&payment);
 
//
// Prepare payment context
// Set tPaymentContext data members like
// 9F02, 9F03, 9C, 9A, 9F21, 5F2A, 5F36, 9F7C (see paymentMW.h, tPaymentContext structure/Information provide by Level3 section)
//
 
// Open session
afsWhatIsYourVersion(version);
agnOpenSessionCL((char*)"smartcardReaderName",(char*)"pinPadName",version,&txnContext,setEMVTag,&i,clipping,sred); // Where i is in [1..numberOfMaxSession]
 
// Depending of the kernel, some proprietary tags need to be converted
 
// Prepare session data
agnSetAgnosDataBaseStrategy(payment->mSession,STRATEGY); // STRATEGY value depends on Agnos kernel
xxxSetUpdateCondition(); // xxx prefix varies on Agnos kernel
adbSetAddTagContactlessCallback(&_xxxAddTag); // xxx prefix varies on Agnos kernel
agnSetAgnosDatabase(i,TLV,TLVLengh); // TLV contains selected CL combination for the preprocessing, where i is in [1..numberOfMaxSession]
 
// Card processing
afsPreprocessing(NULL,&riskParameters[i],&payment); // where i is in [1..numberOfMaxSession]
 
// Process preprocessing results like
// riskParameters->mExtendedSelectionFlagSupported
// riskParameters->mTTQCopy
// riskParameters->mContactlessApplicationNotAllowed
// riskParameters->mStatusCheckRequested
 
 
// END ------------------------

Pseudo-code Sequence (performing a transaction)

The following sequence is a generic example that may be used to encapsulate any Agnos kernel from a specific entry point framework.

tPaymentContext payment;
tOutComeParameter outcome;
tTransactionalContext txnContext;
tInterface interface;
tBoolean clipping=bFALSE, sred=bFALSE; // Optional. Depends on the platform
char version[100]="";
 
 
//
// At EACH SYSTEM START-UP, system initialization
//
// BEGIN ------------------------
//
gpiInitialize((const char*)"transactionLogName"); // Optional. Depends on the platform
gpiInitializeHSM((const char*)"certificateFilesName",(const char*)"certificatesRevocationListFileName",(const char*)"exceptionFileName"); // Optional. Depends on the platform
//
// END ------------------------
 
//
// At EACH NEW TRANSACTION triggering, transaction initialization
//
// BEGIN ------------------------
//
// Reset payment context
pmwInitializePaymentContext(&payment);
 
//
// Prepare payment context
// Set tPaymentContext data members like
// 9F02, 9F03, 9C, 9A, 9F21, 5F2A, 5F36, 9F7C (see paymentMW.h, tPaymentContext structure/Information provide by Level3 section)
// If PayPass, set an instance of tDataExchangeList 
//
 
// Initialize Agnos kernel
afsInitialize(&interface,NULL);
//
// END ------------------------
 
//
// At EACH ENTRY POINT CALL triggerring, start initialization (i.e. always)
//
// BEGIN ------------------------
//
// Reset outcome context
pmwInitializeOutComeParameter(&outcome);
 
// IF no preprocessing performed earlier THEN
// Open session
afsWhatIsYourVersion(version);
agnOpenSessionCL((char*)"smartcardReaderName",(char*)"pinPadName",version,&txnContext,setEMVTag,&payment->mSession,clipping,sred);
// ELSE
payment->mSession = i; // IMPORTANT: where i corresponds to the selected CL combination that is used to perform the transaction
// END IF
 
 
// Depending of the kernel, some proprietary tags need to be converted
 
// Prepare session data
agnSetAgnosDataBaseStrategy(payment->mSession,STRATEGY); // STRATEGY value depends on Agnos kernel
xxxSetUpdateCondition(); // xxx prefix varies on Agnos kernel
adbSetAddTagContactlessCallback(&_xxxAddTag); // xxx prefix varies on Agnos kernel
agnSetAgnosDatabase(payment->mSession,TLV,TLVLengh); // TLV contains selected CL combination
 
// Miscellaneous settings
memcpy(payment->mRID,AID,5); // AID is provided by the entry point
agnSetAID(session,AID,AID_LENGTH); // AID and AID_LENGTH are provided by the entry point
agnSetExitState(payment->mSession,NO_SELECT_FINAL); // Optional. Depends on entry point implementation (i.e if the entry point performs the Final Select)
 
// If 9F37 is provided by entry point then call agnOverwriteEMVTag with 9F37 value
// If NO_SELECT_FINAL then set 9F02 and 9F03 using agnSetEMVTag 
 
// Card processing
afsPerformTransaction(&payment,&outcome);
 
// Process card processing results like
// Tag reading
// Outcome conversion
// payment->mDataExchange conversion
// etc...
 
// Close Agnos session
pmwCloseEMVSession(payment->mSession);
//
// END ------------------------
 
//
// At EACH SYSTEM SHUT DOWN, system release
//
// BEGIN ------------------------
//
gpiRelease(); // Optional. Depends on the platform
//
// END ------------------------

Tags

See Configuration Model page to match potential specific framework's tags to Agnos Tags.

Technical Notes

  • For that kind of integration, Agnos' data model is not used. It's the framework's responsibility to guaranty that pre-processing, card discovery, combination selection and kernel activation will see to the appropriate tags set provided to the Agnos CL kernel

  • GPI porting is light. Focus on GPI/CAD and GPI/HSM to start. Refer to this wiki to get a good overview of the layer of the architecture

  • If ODA, EFL, and CRL are supported then refer to Deployment Model to learn keys related file formats

  • For any Agnos CL kernel to be integrated onto a framework, it is important to comment the call to agnResetSessionContext performed in xxxPrepareSessionData (xxx is a prefix depending on the kernel)

  • Don't forget to implement GPI/Platform/sharedram.c allowing kernels to access to RAM

  • No labels