Symbian3/SDK/Source/GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Fri, 11 Jun 2010 12:39:03 +0100
changeset 8 ae94777fff8f
permissions -rw-r--r--
Week 23 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 2714, Bug 462.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7" xml:lang="en"><title>How
to create a CryptoSPI plug-in</title><prolog><metadata><keywords/></metadata></prolog><conbody>
<section id="GUID-B0B7D886-8759-4806-9BB2-CC378B3A37CC"><title>Introduction</title> <p><b>Note</b>:
this document is intended for device manufacturers. </p> <p>The purpose of
a CryptoSPI plug-in is to implement one or more cryptographic algorithms. </p> <p>Symbian
provides a plug-in called <filepath>softwarecrypto.dll</filepath> 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 <filepath>softwarecrypto.dll</filepath> is located
under <filepath>src/common/generic/security/cryptospi/source/softwarecrypto/</filepath>. </p> <p>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. </p> <ul>
<li id="GUID-9E62C60F-AE68-57D4-939A-43631715D89C"><p> <xref href="GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita#GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7/GUID-FFA64681-40E3-5DCE-A4EC-3EEC75A35D63">Create the MMP file</xref>. </p> </li>
<li id="GUID-3726FB61-4B29-5AAF-AB57-A665DB1F6C0A"><p> <xref href="GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita#GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7/GUID-4B845864-BB8E-5207-8210-A3F608DF6E69">Define the characteristics of the algorithms.</xref>  </p> </li>
<li id="GUID-66A983CE-8D31-5B73-A326-4601B24F4C6B"><p> <xref href="GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita#GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7/GUID-CA441465-BDAB-5B7A-B75D-3B877EBE346F">Implement all or a subset of the functions defined in pluginentrydef.h</xref>. </p> </li>
<li id="GUID-AE856A3F-122C-50AF-BBB4-5A6136CA64B5"><p> <xref href="GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita#GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7/GUID-6ECA8DAB-37C4-5D83-9DBC-10641AA7B636">Implement the MPlugin-derived objects</xref>. </p> </li>
<li id="GUID-FE96900F-EBF2-528A-B0C6-2BA32DB65C77"><p> <xref href="GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7.dita#GUID-2DA8C6F2-93BD-5D39-9E5A-5FF8B8777CE7/GUID-661CE3E1-2FAE-58E1-BBB7-2F72AA8714A2">Update the ROM configuration file</xref>. </p> </li>
</ul> </section>
<section id="GUID-FFA64681-40E3-5DCE-A4EC-3EEC75A35D63"><title>How to create
the MMP file</title> <p>See for instance <filepath>src/common/generic/security/cryptospi/group/softwarecrypto.mmp</filepath>. </p> <codeblock id="GUID-842C71A7-45F4-5BFA-A088-BC4424741296" xml:space="preserve">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</codeblock> <p>Key points: </p> <ul>
<li id="GUID-0C322CF3-197E-5773-A4BB-CDF4943BE588"><p> <codeph>0x1000008d</codeph> identifies
the DLL as static (not polymorphic or an ECOM plug-in) and <codeph>0x102835C2</codeph> is
unique to this plug-in, allocated by Symbian Signed. </p> </li>
<li id="GUID-3D1094C3-A59C-58D0-9873-E5A24935785A"><p>It is recommended that
plug-ins have <codeph>ALL</codeph> capabilities because this ensures that
they can be loaded by client applications with any capabilities. </p> </li>
<li id="GUID-47338BE3-4A8C-5B17-BF37-184F996B0A2C"><p>The project needs to
link against <filepath>cryptospi.lib</filepath>, the CryptoSPI library. </p> </li>
<li id="GUID-1A985A73-A776-5AE1-A4BD-4CC3227CE223"><p>The plug-in needs to
link against <filepath>cryptography.lib</filepath> because big integers (<codeph>RInteger</codeph>)
are implemented in <filepath>cryptography.dll</filepath>. </p> </li>
<li id="GUID-7DEC5079-A30D-5D16-B2EC-FA03605691ED"><p> <codeph>SYSTEMINCLUDE
\epoc32\include\cryptospi</codeph> allows code to <codeph>#include</codeph> the
CryptoSPI header files, which are all exported to <filepath>epoc32\include\cryptospi\</filepath>. </p> </li>
</ul> </section>
<section id="GUID-4B845864-BB8E-5207-8210-A3F608DF6E69"><title>How to define
the algorithm's characteristics</title> <p>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 <xref href="GUID-48BB2346-6840-3A26-B43C-4DF70A322B17.dita#GUID-48BB2346-6840-3A26-B43C-4DF70A322B17/GUID-38201D43-59F9-34A1-9940-14997613998F"><apiname>CryptoSpi::TCommonCharacteristics</apiname></xref>: </p> <codeblock id="GUID-EAEADE27-C875-5713-92DC-050460D22ED5" xml:space="preserve">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;
      };
</codeblock> <p>Other characteristics are specific to a particular interface.
For each interface type, a T class is defined as an aggregation of a <xref href="GUID-BB5BF1BA-686D-30DC-AB50-9F1F58F78051.dita"><apiname>TCommonCharacteristics</apiname></xref> object
and some additional characteristics particular to that interface. For instance, <xref href="GUID-F8CF1F2E-E6EC-3ABE-B18A-C4821115E0AD.dita"><apiname>THashCharacteristics</apiname></xref> includes
a block size, output size and operation mode. (The operation mode can be either <codeph>KHashMode</codeph> or <codeph>KHmacMode</codeph>,
and indicates whether the hash algorithm is an HMAC or not.) </p> <codeblock id="GUID-628BA925-B38B-54F1-B69A-E630E50BB6BF" xml:space="preserve">class THashCharacteristics
    {
    public:
      IMPORT_C TBool IsOperationModeSupported(TUid aOperationMode) const;        
        
    public:
      TCommonCharacteristics cmn;
      TUint iBlockSize;
      TUint iOutputSize;
      const TInt32* iSupportedOperationModes;
      TUint iOperationModeNum;
      };
</codeblock> <p>All the data types relating to characteristics are defined
in <filepath>plugincharacteristics.h</filepath>. </p> <p>For an example, see <filepath>src/common/generic/security/cryptospi/source/softwarecrypto/pluginconfig.h</filepath>. </p> </section>
<section id="GUID-CA441465-BDAB-5B7A-B75D-3B877EBE346F"><title>How to implement
the framework code</title> <p>Plug-in modules must implement a defined set
of functions exported at defined ordinals. The function prototypes and the
ordinals (see <xref href="GUID-8C054BE1-1F0D-362D-A8CD-B868488FAAE2.dita"><apiname>TPluginEntryOrdinal</apiname></xref>) are defined in <filepath>pluginentrydef.h</filepath>.
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 <filepath>softwarecryptoU.def</filepath> exports
file, which can be found in the <filepath>EABI</filepath> and <filepath>BWINS</filepath> directories
in the CryptoSPI source code. </p> <p>Minimally, the plug-in DLL must implement
the function exported at ordinal 1, whose prototype is: </p> <codeblock id="GUID-A6D535EF-5657-5195-A375-5465B588427E" xml:space="preserve">typedef const TCharacteristics** (*EnumerateCharacteristicsFunc)(TUid, TInt&amp;);</codeblock> <p>and at least one of the algorithm factory functions. See for example
class <codeph>CCryptoPluginEntry</codeph> (<filepath>pluginentry.h</filepath> / <filepath>pluginentry.cpp</filepath>). </p> <p>If
the plug-in DLL does not support a particular algorithm, the <codeph>ABSENT</codeph> keyword
should be used in its <filepath>.def</filepath> file to ensure any subsequent
exports are at the correct ordinals. </p> <p><b>Querying the characteristics
of plug-ins</b> </p> <p>CryptoSPI builds up a list of the characteristics
of all the plug-in DLLs by calling the function exported at ordinal 1 (<codeph>EEnumerateCharacteristicsOrdinal</codeph>)
for each DLL and for each interface type. Here is an example implementation: </p> <codeblock id="GUID-02B7F687-19A5-527D-922E-09A32FC728C1" xml:space="preserve">EXPORT_C const TCharacteristics** CCryptoPluginEntry::Enumerate(TUid aInterface, TInt&amp; aNumPlugins)
    {
    const TCharacteristics** ptr(0);
    switch (aInterface.iUid)
        {
    case KHashInterface:
        {
        aNumPlugins=sizeof(KHashCharacteristics)/sizeof(THashCharacteristics*);
        ptr = (const TCharacteristics**) &amp;KHashCharacteristics[0];
        }
        break;

    case KRandomInterface:
        {
        aNumPlugins=sizeof(KRandomCharacteristics)/sizeof(TRandomCharacteristics*);
        ptr= (const TCharacteristics**) &amp;KRandomCharacteristics[0];
        }
        break;
  ...
  }
 return ptr;
 }
</codeblock> <p>Key points: </p> <ul>
<li id="GUID-CBAC6B6F-30CC-5B57-BF58-A4B14C94A04A"><p>Every plug-in must implement
this function. </p> </li>
<li id="GUID-E263363A-4137-5D7E-8988-4B25E492D39F"><p> <codeph>TUid aInterface</codeph> is
the interface UID, as defined in <codeph>CryptoSpi::KInterfacesUids</codeph>. </p> </li>
<li id="GUID-C7A913A0-DD63-599F-8A34-EA2D7466B050"><p> <codeph>TInt&amp; aNumPlugins</codeph> should
be set to the number of algorithms of that interface type implemented by the
plug-in. </p> </li>
</ul> <p><b>Extended characteristics</b> </p> <p>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 <codeph>CryptoSpi::CCryptoBase::GetExtendedCharacteristicsL()</codeph>. </p> <p>The
function exported at ordinal 2 has this prototype: </p> <codeblock id="GUID-5A10F3D2-DAE9-55F6-BF1A-A0E001637ACE" xml:space="preserve">typedef void (*GetExtendedCharacteristicsFuncL)(TUid, CExtendedCharacteristics*&amp;);</codeblock> <p>Symbian defines 2 extended characteristics: </p> <ul>
<li id="GUID-DFCA6450-2121-5257-9F26-A11FD8995E5D"><p> <codeph>TInt iAvailableConcurrency;</codeph>  </p> <p>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. </p> </li>
<li id="GUID-FEA9BD5F-B264-5316-9B15-FD5E0E51CAC2"><p> <codeph>TBool iExclusiveUse;</codeph>  </p> <p>Whether
it is possible for the application to reserve exclusive use of hardware resources
used by the plug-in. </p> </li>
</ul> <p>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 <codeph>CryptoSpi::CExtendedCharacteristics::AddCharacteristicL()</codeph>. </p> <p><b>Algorithm instantiation</b> </p> <p>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 <codeph>ECreateSymmetricKeyGeneratorOrdinal</codeph> and <codeph>ECreateAsyncSymmetricKeyGeneratorOrdinal</codeph> have
no corresponding declarations). </p> <codeblock id="GUID-A6330276-FB1A-5C14-A2BF-5BBCD452614B" xml:space="preserve">typedef void (*CreateRandomFuncL)(MRandom*&amp;, TUid, const CCryptoParams*);
typedef void (*CreateHashFuncL)(MHash*&amp;, TUid, TUid, const CKey*, const CCryptoParams*);
typedef void (*CreateSymmetricCipherFuncL)(MSymmetricCipher*&amp;, TUid, const CKey&amp;, TUid, TUid, TUid, const CCryptoParams*);
typedef void (*CreateAsymmetricCipherFuncL)(MAsymmetricCipher*&amp;, TUid, const CKey&amp;, TUid, TUid, const CCryptoParams*);
typedef void (*CreateSignerFuncL)(MSigner*&amp;, TUid, const CKey&amp;, TUid, const CCryptoParams*);
typedef void (*CreateVerifierFuncL)(MVerifier*&amp;, TUid, const CKey&amp;, TUid, const CCryptoParams*);
typedef void (*CreateKeyAgreementFuncL)(MKeyAgreement*&amp;, TUid, const CKey&amp;, const CCryptoParams*);
typedef void (*CreateKeyPairGeneratorFuncL)(MKeyPairGenerator*&amp;, TUid, const CCryptoParams*);
typedef void (*CreateAsyncRandomFuncL)(MAsyncRandom*&amp;, TUid, const CCryptoParams*);
typedef void (*CreateAsyncHashFuncL)(MAsyncHash*&amp;, TUid, TUid, const CKey*, const CCryptoParams*);
typedef void (*CreateAsyncSymmetricCipherFuncL)(MAsyncSymmetricCipher*&amp;, TUid, const CKey&amp;, TUid, TUid, TUid, const CCryptoParams*);
typedef void (*CreateAsyncAsymmetricCipherFuncL)(MAsyncAsymmetricCipher*&amp;, TUid, const CKey&amp;, TUid, TUid, const CCryptoParams*);
typedef void (*CreateAsyncSignerFuncL)(MAsyncSigner*&amp;, TUid, const CKey&amp;, TUid, const CCryptoParams*);
typedef void (*CreateAsyncVerifierFuncL)(MAsyncVerifier*&amp;, TUid, const CKey&amp;, TUid, const CCryptoParams*);
typedef void (*CreateAsyncKeyAgreementFuncL)(MAsyncKeyAgreement*&amp;, TUid, const CKey&amp;, const CCryptoParams*);
typedef void (*CreateAsyncKeyPairGeneratorFuncL)(MAsyncKeyPairGenerator*&amp;, TUid, const CCryptoParams*);</codeblock> <p>Clients
instantiate algorithms by calling one of the CryptoSPI factory methods, for
instance <xref href="GUID-FF3CFE33-C90A-328C-BF80-0A03B821AE1C.dita#GUID-FF3CFE33-C90A-328C-BF80-0A03B821AE1C/GUID-D91B2099-C9F4-3B7C-843F-39A654DC0555"><apiname>CHashFactory::CreateHashL()</apiname></xref>. All CryptoSPI factory
methods take a <xref href="GUID-C3704390-D2DD-3DFF-A1E3-433C5030044B.dita"><apiname>CCryptoParams</apiname></xref> 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. </p> <p>The data type of each parameter can be integer
(<codeph>TInt</codeph>), big integer (<codeph>RInteger</codeph>), or 8/16
bit descriptor. Additional data types could be added in future, by extending
the <codeph>TParamType</codeph> enum in <codeph>CCryptoParam</codeph> and
deriving a class from <codeph>CCryptoParam</codeph>, but this is unlikely
to be necessary. </p> </section>
<section id="GUID-6ECA8DAB-37C4-5D83-9DBC-10641AA7B636"><title>How to implement
the MPlugin-derived class</title> <p>All concrete algorithm classes are derived
from one of the abstract base classes listed below, which are in turn all
derived from <codeph>MPlugin</codeph>. </p> <ul>
<li id="GUID-83E757D2-E70D-51D3-BF46-53A2F8A8A3E9"><p>Random (<xref href="GUID-53D7EA29-2736-3B19-AA69-915FAD2A7130.dita"><apiname>MRandom</apiname></xref> /<xref href="GUID-A19A4B6F-CCF2-3167-B757-F8308B7B7C26.dita"><apiname>MAsyncRandom</apiname></xref>) </p> </li>
<li id="GUID-ABDD0216-BA34-5DD1-8D07-064B3F1EAB02"><p>Hash (<xref href="GUID-6896A7F0-AE37-369E-AB54-F069A7DE3FDB.dita"><apiname>MHash</apiname></xref> /<xref href="GUID-A4B3807A-82D1-39D3-8D00-D2A1D41EFEA5.dita"><apiname>MAsyncHash</apiname></xref>) </p> </li>
<li id="GUID-5611F951-0471-5A54-BCFE-4DBDB9FF7B1A"><p>Symmetric cipher (<xref href="GUID-733DAE85-68B3-3211-808A-4FBD9C1E1F05.dita"><apiname>MSymmetricCipher</apiname></xref> /<xref href="GUID-545AE46E-8CF1-3470-8F10-5FCB6D79859E.dita"><apiname>MAsyncSymmetricCipher</apiname></xref>) </p> </li>
<li id="GUID-C87B0A48-C66F-5E5E-BEA4-BB3F187AA59D"><p>Asymmetric cipher (<xref href="GUID-C044BB6D-6E78-3698-8710-89FFB7A6CDFD.dita"><apiname>MAsymmetricCipher</apiname></xref> /<xref href="GUID-EE7FCCA6-D86F-30E2-BB6A-862BAE111344.dita"><apiname>MAsyncAsymmetricCipher</apiname></xref>) </p> </li>
<li id="GUID-EE95A2C8-4F9C-5052-8709-AD7C1D2A5E6F"><p>Signer (<xref href="GUID-59F2E24A-5F48-383F-95C6-88A5B432E121.dita"><apiname>MSigner</apiname></xref> /<xref href="GUID-B0EC8744-B525-3599-B1B4-00E4A9C62C7A.dita"><apiname>MAsyncSigner</apiname></xref>) </p> </li>
<li id="GUID-717313C9-B2A3-5E78-8A61-A4C3093627BF"><p>Verifier (<xref href="GUID-98E08EBD-3758-39D6-A2B1-EC42F66D2F84.dita"><apiname>MVerifier</apiname></xref> /<xref href="GUID-BCCA1F97-B568-3B75-9974-5E70F1ADDEFA.dita"><apiname>MAsyncVerifier</apiname></xref>) </p> </li>
<li id="GUID-8EA174F1-16A5-5364-9672-5AF6644EC19A"><p>Key agreement (<xref href="GUID-A47EF879-B23E-339A-9EBC-3622668B83FB.dita"><apiname>MKeyAgreement</apiname></xref> /<xref href="GUID-E70B8C8A-384F-39F0-8845-4CE53E86B286.dita"><apiname>MAsyncKeyAgreement</apiname></xref>) </p> </li>
<li id="GUID-3988580D-047C-5492-9493-0A5365FEFB84"><p>Key pair generator (<xref href="GUID-238EBB3C-0ECC-38A5-848E-28716B75931B.dita"><apiname>MKeyPairGenerator</apiname></xref> /<xref href="GUID-5B2CE80F-536F-3B75-9FD9-3C0C98EE3D09.dita"><apiname>MAsyncKeyPairGenerator</apiname></xref>) </p> </li>
<li id="GUID-05483361-4043-5FC4-A134-AAEA2E31E872"><p>Key generator (<xref href="GUID-1492AF86-FD98-3219-B46B-543DD7066801.dita"><apiname>MSymmetricKeyGenerator</apiname></xref> /<xref href="GUID-A3F12E4C-51D7-3007-A53E-EC53FAEA3D9C.dita"><apiname>MAsyncSymmetricKeyGenerator</apiname></xref>) </p> </li>
</ul> <p> <xref href="GUID-6BD89347-671F-3518-9777-55801A090C79.dita"><apiname/></xref><xref href="GUID-47357E35-5781-3093-80FD-052EC7F0DF3F.dita"><apiname>MPlugin</apiname></xref> (<filepath>cryptoplugin.h</filepath>)
declares the following pure virtual functions: </p> <codeblock id="GUID-6CDA7919-C31E-50EB-8D67-7A142297DBAF" xml:space="preserve">virtual void Close() = 0;
virtual void Reset() = 0;
virtual void GetCharacteristicsL(const TCharacteristics*&amp; aPluginCharacteristics) = 0;
virtual const CExtendedCharacteristics&amp; GetExtendedCharacteristicsL() = 0;
virtual TAny* GetExtension(TUid aExtensionId) = 0;</codeblock> <p>For example,
the random number generator plug-in implemented in <filepath>softwarecrypto.dll</filepath> implements
these functions as follows: </p> <codeblock id="GUID-A18C6FDA-4E3C-570E-B700-7680F91D397D" xml:space="preserve">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*&amp; aPluginCharacteristics)
    {
 //Find out how many algorithms are implemented by the plug-in
    TInt randomNum = sizeof(KRandomCharacteristics)/sizeof(TRandomCharacteristics*);
    for (TInt i = 0; i &lt; randomNum; i++)
        {
  //Compare implementation UIDs
  //ImplementationUid() is a helper function that returns KCryptoPluginRandomUid
        if (KRandomCharacteristics[i]-&gt;cmn.iImplementationUID == ImplementationUid().iUid)
            {
            aPluginCharacteristics = KRandomCharacteristics[i];
            break;
            }
        }
    }

TAny* CRandomImpl::GetExtension(TUid /*aExtensionId*/)
    {
    return NULL;
    }</codeblock> <p>The main purpose of <codeph>MPlugin::Reset()</codeph> is
to reset the hardware, so is usually not relevant to a software-only implementation. <codeph>GetExtension()</codeph> is
intended for internal use, and may be removed from the API in future. </p> <p>These
functions are called through the client API to CryptoSPI, in other words <codeph>CCryptoBase</codeph> and
the various classes derived from it, in this case, <codeph>CRandom</codeph>.
For instance when the client calls <xref href="GUID-ED01CE2C-30E8-344F-B3C9-895FA576D33F.dita#GUID-ED01CE2C-30E8-344F-B3C9-895FA576D33F/GUID-8D93089E-1F97-376B-8CC0-08E0E34158F4"><apiname>CCryptoBase::GetCharacteristicsL()</apiname></xref>,
this calls <codeph>GetCharacteristicsL()</codeph> in the plug-in, or calling <xref href="GUID-CD88247C-561B-3AB4-BF77-AFD322F860A4.dita#GUID-CD88247C-561B-3AB4-BF77-AFD322F860A4/GUID-F251BF16-E212-3595-9FE8-C7BC754972E1"><apiname>CRandom::GenerateRandomBytesL()</apiname></xref>,
calls <codeph>GenerateRandomBytesL()</codeph> in the plug-in. </p> </section>
<section id="GUID-661CE3E1-2FAE-58E1-BBB7-2F72AA8714A2"><title>The configuration
file</title> <p>The set of available plug-ins is listed in the configuration
file <filepath>z:\resource\cryptospi\plug-ins.txt</filepath>. 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 <filepath>z:\sys\bin</filepath>.
The configuration file must be on the <filepath>Z:</filepath> 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 (<codeph>CLegacySelector</codeph>) loads plug-in DLLs as required. </p> </section>
</conbody></concept>