diff -r 51a74ef9ed63 -r ae94777fff8f Symbian3/SDK/Source/GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/SDK/Source/GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita Fri Jun 11 12:39:03 2010 +0100 @@ -0,0 +1,278 @@ + + + + + +How +to create a CryptoSPI plug-in +
Introduction

Note: +this document is intended for device manufacturers.

The purpose of +a CryptoSPI plug-in is to implement one or more cryptographic algorithms.

Symbian +provides a plug-in called softwarecrypto.dll that implements +all algorithms supported by the legacy (pre-Symbian^3) cryptography APIs. +In Symbian^3, the legacy APIs have all been re-implemented to use this plug-in +DLL. The source code for softwarecrypto.dll is located +under src/common/generic/security/cryptospi/source/softwarecrypto/.

This +is a summary of the steps involved in creating a plug-in, in no particular +order. Details of each step are given in the rest of the document.

    +
  • Create the MMP file.

  • +
  • Define the characteristics of the algorithms.

  • +
  • Implement all or a subset of the functions defined in pluginentrydef.h.

  • +
  • Implement the MPlugin-derived objects.

  • +
  • Update the ROM configuration file.

  • +
+
How to create +the MMP file

See for instance src/common/generic/security/cryptospi/group/softwarecrypto.mmp.

TARGET softwarecrypto.dll +TARGETTYPE dll + +UID 0x1000008d 0x102835C2 +VENDORID 0x70000001 + +CAPABILITY All + +DEFFILE softwarecrypto.def + +USERINCLUDE . +USERINCLUDE ..\inc +USERINCLUDE ..\inc\spi +SYSTEMINCLUDE \epoc32\include +SYSTEMINCLUDE \epoc32\include\cryptospi + +SOURCEPATH ..\source\softwarecrypto +SOURCE pluginentry.cpp +SOURCE md2impl.cpp md5impl.cpp sha1impl.cpp hmacimpl.cpp +SOURCE 3desimpl.cpp desimpl.cpp rc2impl.cpp rijndaelimpl.cpp arc4impl.cpp symmetriccipherimpl.cpp +SOURCE randomimpl.cpp dsasignerimpl.cpp dsaverifyimpl.cpp rsaimpl.cpp rsafunction.cpp +SOURCE signerimpl.cpp verifierimpl.cpp asymmetriccipherimpl.cpp + +LIBRARY euser.lib cryptospi.lib + +// Depends on bigint and padding code +LIBRARY cryptography.lib +//Depends on random server for random number generation +LIBRARY random.lib

Key points:

    +
  • 0x1000008d identifies +the DLL as static (not polymorphic or an ECOM plug-in) and 0x102835C2 is +unique to this plug-in, allocated by Symbian Signed.

  • +
  • It is recommended that +plug-ins have ALL capabilities because this ensures that +they can be loaded by client applications with any capabilities.

  • +
  • The project needs to +link against cryptospi.lib, the CryptoSPI library.

  • +
  • The plug-in needs to +link against cryptography.lib because big integers (RInteger) +are implemented in cryptography.dll.

  • +
  • SYSTEMINCLUDE +\epoc32\include\cryptospi allows code to #include the +CryptoSPI header files, which are all exported to epoc32\include\cryptospi\.

  • +
+
How to define +the algorithm's characteristics

All plug-ins must define the characteristics +of their algorithm implementations that are fixed at compile time, as constant +data. Some characteristics are common to all interface types, for instance +the name and UID of the algorithm implemented, the name of the plug-in vendor, +whether the plug-in uses hardware acceleration, and whether it is FIPS certified. +Common characteristics are defined in CryptoSpi::TCommonCharacteristics:

class TCommonCharacteristics + { + public: + ... + TInt32 iInterfaceUID; + TInt32 iAlgorithmUID; + TInt32 iImplementationUID; + const TRomLitC16* iCreatorName; + TBool iIsFIPSApproved; + TBool iIsHardwareSupported; + TUint iMaxConcurrencySupported; + const TRomLitC16* iAlgorithmName; + TInt iLatency; + TInt iThroughput; + }; +

Other characteristics are specific to a particular interface. +For each interface type, a T class is defined as an aggregation of a TCommonCharacteristics object +and some additional characteristics particular to that interface. For instance, THashCharacteristics includes +a block size, output size and operation mode. (The operation mode can be either KHashMode or KHmacMode, +and indicates whether the hash algorithm is an HMAC or not.)

class THashCharacteristics + { + public: + IMPORT_C TBool IsOperationModeSupported(TUid aOperationMode) const; + + public: + TCommonCharacteristics cmn; + TUint iBlockSize; + TUint iOutputSize; + const TInt32* iSupportedOperationModes; + TUint iOperationModeNum; + }; +

All the data types relating to characteristics are defined +in plugincharacteristics.h.

For an example, see src/common/generic/security/cryptospi/source/softwarecrypto/pluginconfig.h.

+
How to implement +the framework code

Plug-in modules must implement a defined set +of functions exported at defined ordinals. The function prototypes and the +ordinals (see TPluginEntryOrdinal) are defined in pluginentrydef.h. +When a client requests an algorithm, these functions are used by CryptoSPI +to query and instantiate algorithm implementations. The simplest way to ensure +that functions are assigned the correct ordinal is to copy the softwarecryptoU.def exports +file, which can be found in the EABI and BWINS directories +in the CryptoSPI source code.

Minimally, the plug-in DLL must implement +the function exported at ordinal 1, whose prototype is:

typedef const TCharacteristics** (*EnumerateCharacteristicsFunc)(TUid, TInt&);

and at least one of the algorithm factory functions. See for example +class CCryptoPluginEntry (pluginentry.h / pluginentry.cpp).

If +the plug-in DLL does not support a particular algorithm, the ABSENT keyword +should be used in its .def file to ensure any subsequent +exports are at the correct ordinals.

Querying the characteristics +of plug-ins

CryptoSPI builds up a list of the characteristics +of all the plug-in DLLs by calling the function exported at ordinal 1 (EEnumerateCharacteristicsOrdinal) +for each DLL and for each interface type. Here is an example implementation:

EXPORT_C const TCharacteristics** CCryptoPluginEntry::Enumerate(TUid aInterface, TInt& aNumPlugins) + { + const TCharacteristics** ptr(0); + switch (aInterface.iUid) + { + case KHashInterface: + { + aNumPlugins=sizeof(KHashCharacteristics)/sizeof(THashCharacteristics*); + ptr = (const TCharacteristics**) &KHashCharacteristics[0]; + } + break; + + case KRandomInterface: + { + aNumPlugins=sizeof(KRandomCharacteristics)/sizeof(TRandomCharacteristics*); + ptr= (const TCharacteristics**) &KRandomCharacteristics[0]; + } + break; + ... + } + return ptr; + } +

Key points:

    +
  • Every plug-in must implement +this function.

  • +
  • TUid aInterface is +the interface UID, as defined in CryptoSpi::KInterfacesUids.

  • +
  • TInt& aNumPlugins should +be set to the number of algorithms of that interface type implemented by the +plug-in.

  • +

Extended characteristics

Extended characteristics +are those which can only be determined at runtime. They are retrieved on demand +by CryptoSPI or clients can call the plug-in's implementation of CryptoSpi::CCryptoBase::GetExtendedCharacteristicsL().

The +function exported at ordinal 2 has this prototype:

typedef void (*GetExtendedCharacteristicsFuncL)(TUid, CExtendedCharacteristics*&);

Symbian defines 2 extended characteristics:

    +
  • TInt iAvailableConcurrency;

    The +number of available resources for processing the operation for the requested +plug-in. This could be zero even if no operations are in progress; for instance +cryptographic acceleration hardware is turned off to save battery power.

  • +
  • TBool iExclusiveUse;

    Whether +it is possible for the application to reserve exclusive use of hardware resources +used by the plug-in.

  • +

Additional plug-in specific characteristics may be defined. The plug-in +creator needs to define UIDs for each of these and specify the UID when calling CryptoSpi::CExtendedCharacteristics::AddCharacteristicL().

Algorithm instantiation

A plug-in must implement +one or more factory methods for instantiating algorithms. The functions exported +at ordinals 3 to 20 have the following declarations. (Note that symmetric +key generation is not yet implemented by Symbian's software crypto plug-in, +so the ordinals ECreateSymmetricKeyGeneratorOrdinal and ECreateAsyncSymmetricKeyGeneratorOrdinal have +no corresponding declarations).

typedef void (*CreateRandomFuncL)(MRandom*&, TUid, const CCryptoParams*); +typedef void (*CreateHashFuncL)(MHash*&, TUid, TUid, const CKey*, const CCryptoParams*); +typedef void (*CreateSymmetricCipherFuncL)(MSymmetricCipher*&, TUid, const CKey&, TUid, TUid, TUid, const CCryptoParams*); +typedef void (*CreateAsymmetricCipherFuncL)(MAsymmetricCipher*&, TUid, const CKey&, TUid, TUid, const CCryptoParams*); +typedef void (*CreateSignerFuncL)(MSigner*&, TUid, const CKey&, TUid, const CCryptoParams*); +typedef void (*CreateVerifierFuncL)(MVerifier*&, TUid, const CKey&, TUid, const CCryptoParams*); +typedef void (*CreateKeyAgreementFuncL)(MKeyAgreement*&, TUid, const CKey&, const CCryptoParams*); +typedef void (*CreateKeyPairGeneratorFuncL)(MKeyPairGenerator*&, TUid, const CCryptoParams*); +typedef void (*CreateAsyncRandomFuncL)(MAsyncRandom*&, TUid, const CCryptoParams*); +typedef void (*CreateAsyncHashFuncL)(MAsyncHash*&, TUid, TUid, const CKey*, const CCryptoParams*); +typedef void (*CreateAsyncSymmetricCipherFuncL)(MAsyncSymmetricCipher*&, TUid, const CKey&, TUid, TUid, TUid, const CCryptoParams*); +typedef void (*CreateAsyncAsymmetricCipherFuncL)(MAsyncAsymmetricCipher*&, TUid, const CKey&, TUid, TUid, const CCryptoParams*); +typedef void (*CreateAsyncSignerFuncL)(MAsyncSigner*&, TUid, const CKey&, TUid, const CCryptoParams*); +typedef void (*CreateAsyncVerifierFuncL)(MAsyncVerifier*&, TUid, const CKey&, TUid, const CCryptoParams*); +typedef void (*CreateAsyncKeyAgreementFuncL)(MAsyncKeyAgreement*&, TUid, const CKey&, const CCryptoParams*); +typedef void (*CreateAsyncKeyPairGeneratorFuncL)(MAsyncKeyPairGenerator*&, TUid, const CCryptoParams*);

Clients +instantiate algorithms by calling one of the CryptoSPI factory methods, for +instance CHashFactory::CreateHashL(). All CryptoSPI factory +methods take a CCryptoParams parameter. This class allows +clients to supply arbitrary, algorithm-specific data to plug-ins, for instance +the effective key length for RC2, or the number of bytes to discard from the +keystream for ARC4.

The data type of each parameter can be integer +(TInt), big integer (RInteger), or 8/16 +bit descriptor. Additional data types could be added in future, by extending +the TParamType enum in CCryptoParam and +deriving a class from CCryptoParam, but this is unlikely +to be necessary.

+
How to implement +the MPlugin-derived class

All concrete algorithm classes are derived +from one of the abstract base classes listed below, which are in turn all +derived from MPlugin.

    +
  • Random (MRandom /MAsyncRandom)

  • +
  • Hash (MHash /MAsyncHash)

  • +
  • Symmetric cipher (MSymmetricCipher /MAsyncSymmetricCipher)

  • +
  • Asymmetric cipher (MAsymmetricCipher /MAsyncAsymmetricCipher)

  • +
  • Signer (MSigner /MAsyncSigner)

  • +
  • Verifier (MVerifier /MAsyncVerifier)

  • +
  • Key agreement (MKeyAgreement /MAsyncKeyAgreement)

  • +
  • Key pair generator (MKeyPairGenerator /MAsyncKeyPairGenerator)

  • +
  • Key generator (MSymmetricKeyGenerator /MAsyncSymmetricKeyGenerator)

  • +

MPlugin (cryptoplugin.h) +declares the following pure virtual functions:

virtual void Close() = 0; +virtual void Reset() = 0; +virtual void GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics) = 0; +virtual const CExtendedCharacteristics& GetExtendedCharacteristicsL() = 0; +virtual TAny* GetExtension(TUid aExtensionId) = 0;

For example, +the random number generator plug-in implemented in softwarecrypto.dll implements +these functions as follows:

void CRandomImpl::Close() + { + delete this; + } + +void CRandomImpl::Reset() + { //Not required + } + +const CExtendedCharacteristics* CRandomImpl::GetExtendedCharacteristicsL() + // All Symbian software plug-ins have unlimited concurrency and cannot be reserved + // for exclusive use + { + return CExtendedCharacteristics::NewL(KMaxTInt, EFalse); + } + +//Get the plug-in characteristics (defined at compile time) +void CRandomImpl::GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics) + { + //Find out how many algorithms are implemented by the plug-in + TInt randomNum = sizeof(KRandomCharacteristics)/sizeof(TRandomCharacteristics*); + for (TInt i = 0; i < randomNum; i++) + { + //Compare implementation UIDs + //ImplementationUid() is a helper function that returns KCryptoPluginRandomUid + if (KRandomCharacteristics[i]->cmn.iImplementationUID == ImplementationUid().iUid) + { + aPluginCharacteristics = KRandomCharacteristics[i]; + break; + } + } + } + +TAny* CRandomImpl::GetExtension(TUid /*aExtensionId*/) + { + return NULL; + }

The main purpose of MPlugin::Reset() is +to reset the hardware, so is usually not relevant to a software-only implementation. GetExtension() is +intended for internal use, and may be removed from the API in future.

These +functions are called through the client API to CryptoSPI, in other words CCryptoBase and +the various classes derived from it, in this case, CRandom. +For instance when the client calls CCryptoBase::GetCharacteristicsL(), +this calls GetCharacteristicsL() in the plug-in, or calling CRandom::GenerateRandomBytesL(), +calls GenerateRandomBytesL() in the plug-in.

+
The configuration +file

The set of available plug-ins is listed in the configuration +file z:\resource\cryptospi\plug-ins.txt. Each line in +the file contains the filename of a single plug-in DLL, without the path. +The path is not required because the DLLs are assumed to be located in z:\sys\bin. +The configuration file must be on the Z: drive and therefore +additional plug-ins cannot be installed post-manufacture. Depending on the +plug-in selector in use, plug-ins may be loaded individually, as required, +or all at once when CryptoSPI is initialized. The default selector implemented +by Symbian (CLegacySelector) loads plug-in DLLs as required.

+
\ No newline at end of file