// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "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:
//
// Description:
// crypto.h - IPSEC API towards cryptographic libraries
//
/**
@internalComponent
*/
#ifndef __CRYPTO_H__
#define __CRYPTO_H__
/**
// @file crypto.h
//
// The basic API for cryptographic algorithm library.
//
// IPSEC hook itself does not contain any cryptographic algorithms.
// The available algorithms are dynamically imported to the IPSEC
// by binding the IPSEC (pfkey) to one or more cryptographic libraries,
// each of which are implemented as a protocol..
//
// This header describes the basic API and base classes for building
// such cryptographic algorithm libraries as protocol modules for IPSEC.
//
// In the TServerProtocolDesc of such protocol, the following fields
// are significant for the IPSEC:
//
// @li TServerProtocolDesc::iName (protocol name) is the symbolic
// name of the library. When multiple libraries are used,
// they should have different names.
// @li TServerProtocolDesc::iAddrFamily should be KAfCrypto
// @li TServerProtocolDesc::iProtocol must be KProtocolCrypto
//
// The remaining fields can be freely initialized to any values
// that satisfy the SocketServer requirements. The chosen values
// will have no effect on the IPSEC functionality.
//
// The cryptographic library protocol can be implemented in any
// protocol module (PRT file) along with other protocols. The
// value KProtocolCrypto alone in iProtocol tells that the protocol
// supports the API defined by this definition.
//
// An example of possible Ipsec configuration (ESK file)
// @verbatim
[sockman]
protocols= secpol,pfkey,lib1,lib2
[pfkey]
filename= ipsec6.prt
index= 2
bindto= lib1,lib2
[secpol]
filename= ipsec6.prt
index= 1
bindto= pfkey,ip6
[lib1]
filename= eaysymb.prt
index= 1
[lib2]
filename= newcrypto.prt
index= 1
@endverbatim
@internalTechnology
@released
*/
#include <e32base.h>
#include <es_prot.h>
#include "cryptospidef.h"
#include "cryptosymmetriccipherapi.h"
#include "cryptomacapi.h"
/**
// The protocol number for a library.
*/
const TUint KProtocolCrypto = 0x104;
/**
// The protocol family for the library.
*/
const TUint KAfCrypto = 0x0803;
typedef TBuf<0x20> TAlgorithmName;
/**
* @name Well Known Algorithm Names
* The cryptographic libary can choose the names for it's algorithms freely,
* but it will cause less confusion, if the well known standard algoriths
* are named uniformly.
*/
//@{
/**
* Single DES in CBC-Mode.
* - key: 8
* - block: 8
* - IV: 8
*/
_LIT(KIpsecName_DES_CBC, "descbc");
/**
* Triple DES in CBC-Mode.
* - key: 24
* - block: 8
* - IV: 8
*/
_LIT(KIpsecName_3DES_CBC, "3descbc");
/**
* Blowfish in CBC-Mode.
* - key: variable in 8..72
* - block: 8
* - IV: 8
*/
_LIT(KIpsecName_BLOWFISH_CBC, "blowfish");
/**
* IDEA in CBC-Mode.
* - key: 16
* - block: 8
* - IV: 8
*/
_LIT(KIpsecName_IDEA_CBC, "idea");
/**
* AES in CBC-Mode.
* - key: 16, 24 or 32
* - block: 16
* - IV: 16
*/
_LIT(KIpsecName_AES_CBC, "aescbc");
/**
* AES in CTR-Mode.
* - key 16, 24 or 32 (+ append 4 octets for the NONCE)
* - block: 16
* - IV: 8
*/
_LIT(KIpsecName_AES_CTR, "aesctr");
/**
* RC5 in CBC-Mode.
* - key: variable 5..255
* - block: 8
* - IV: 8
*/
_LIT(KIpsecName_RC5, "rc5");
/**
* SHA1 Digest.
* - digest length: 20
* - block: 64
*/
_LIT(KIpsecName_SHA1, "sha1");
/**
* SHA2-256 Digest.
* - digest length: 32
* - block: 64
*/
_LIT(KIpsecName_SHA2_256, "sha2-256");
/**
* MD5 Digest.
* - digest length: 16
* - block: 64
*/
_LIT(KIpsecName_MD5, "md5");
/**
*
*
*/
#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
_LIT(KIpsecName_AES_XCBC_MAC, "aesxcbcmac") ;
#endif //SYMBIAN_IPSEC_VOIP_SUPPORT
//@}
typedef enum
{
EAlgorithmClass_Digest, //< Message Digest algorithm
EAlgorithmClass_Cipher, //< Symmetric Cipher algorithm
#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
EAlgorithmClass_Mac ,
#endif //SYMBIAN_IPSEC_VOIP_SUPPORT
//
// New types are possible by adding the symbol here
// and defining the corresponding abstract class
// (similar to CMessageDigestCrypto and CSymmetricCipher)
//
} TAlgorithmClass;
// TAlgorithmDesc (and related types)
/**
// A description of available algorithm.
//
// Similar to ProtocolList, a protocol supporting this API must
// return a description of each implemented algorithm as an
// array of TAlgorithmDesc objects as a result of AlgorithmList
// call.
*/
class TAlgorithmDesc
{
public:
TAlgorithmName iName; //< Name of the algorithm
TAlgorithmClass iAlgType; //< Class of the algorithm (cipher/digest)
TUint iMinBits; //< Min Length of the key in bits (all keys total)
TUint iMaxBits; //< Max Length of the key in bits (all keys total)
TUint iBlock; //< Length of the block in bytes
TUint iVector; //< Initialization Vector length (bytes)
};
// Each of the following includes virtual destructor
// just in case there is a need for a cleanup code
// when the object is deleted using a pointer to
// the base virtual class.
// CMessageDigestCrypto
// ********************
/**
// Base Message Digest (abstract) class.
//
// All message digest algorithms must be derived from this
// base class, which defines the IPSEC required API for
// message digests (used by AH and ESP with authentication
// implementations).
//
// Because IPSEC needs to run digest for each packet
// independently, it is important that the implementation
// can reset the computation by Init() without needing
// to do any additional allocations.
*/
class CMessageDigestCrypto : public CBase
{
// NOTE: This class was originally designed based on assumption
// that the derived class implementing the digest includes all
// state in member variables and does not need to allocate
// additional space -- thus no ConstructL method.
public:
/**
// Set digest into initial state.
//
// IPSEC calls this method to start a new digest
// computation for each IP packet that needs
// digest computation.
*/
virtual void Init()=0;
/**
// Add segment of data to the digest.
//
// The octets in aMessage must be added to the digest
// value. The length of the aMessage can be anything
// from 0 or more octets. If the digest algorithm has
// any inherent block requirements, then this method
// must handle it (specifically, the digest must work
// correctly, even if the data is fed to it one byte
// at time).
//
// @param aMessage
// describe the segment of octets to be added into
// the digest (length >= 0).
*/
virtual void Update(const TDesC8& aMessage)=0;
/**
// Wrap up the digest and return the result.
//
// @param aDigest
// a buffer to return the final computed digest value.
*/
virtual void Final(TDes8& aDigest)=0;
virtual ~CMessageDigestCrypto() {}
};
#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
class CMacCrypto : public CBase
{
public:
/**
// Set digest into initial state.
//
// IPSEC calls this method to start a new digest
// computation for each IP packet that needs
// digest computation.
*/
virtual void Init()=0;
/**
// Add segment of data to the digest.
//
// The octets in aMessage must be added to the digest
// value. The length of the aMessage can be anything
// from 0 or more octets. If the digest algorithm has
// any inherent block requirements, then this method
// must handle it (specifically, the digest must work
// correctly, even if the data is fed to it one byte
// at time).
//
// @param aMessage
// describe the segment of octets to be added into
// the digest (length >= 0).
*/
virtual void Update(const TDesC8& aMessage)=0;
/**
// Wrap up the digest and return the result.
//
// @param aDigest
// a buffer to return the final computed digest value.
*/
virtual void Final(TDes8& aDigest)=0;
virtual ~CMacCrypto() {}
};
#endif //SYMBIAN_IPSEC_VOIP_SUPPORT
// CSymmetricCipher
// ****************
/**
// Base Symmetric Cipher (abstract) class.
//
// All cipher algorithms must be derived from this
// base class, which defines the IPSEC required API for
// cipher algorithms (used by ESP implementation).
//
// Because IPSEC needs to run cipher for each packet
// independently, it is important that the implementation
// can reset the computation by InitL() without needing
// to do any additional allocations [which means that
// it being a leaving function is a bad sign!]
*/
class CSymmetricCipher : public CBase
{
public:
enum TAction { EEncrypt, EDecrypt };
/**
// Define the cipher key.
//
// Because setting the key can be time consuming,
// this is only called once after instantiation of the
// class. Then, each packet is started with a call
// to InitL.
//
// @param aKey
// the cipher key. The length of the key is
// defined by the length of this descriptor,
// and is always multiple of 8 bits.
// @return
// @li > 0, the key is weak (but set anyway)
// @li = 0, all ok
// @li < 0, the key not usable (not set)
*/
virtual TInt Setkey(const TDesC8& aKey)=0;
/**
// Reset the cipher engine to initial state.
//
// As this method is called for each packet, it
// should not do any memory allocation or heavy
// computations.
//
// @param aIV initial vector.
// @param aMode tells whether initialize is for decrypt or encrypt.
*/
virtual void Init(const TDesC8 &aIV, TAction aMode)=0;
/**
// Perform encryption or decryption.
//
// Because algorithms are expected to work blocks, the
// caller will guarantee that ALL Outbuf's given to Update
// will exist up to Finish call (or at least as long as at
// least blocksize octets have been given to Update after it).
// The implementation of the algorithm can store pointer(s) to
// aOutbuf described memory area, and return data to such
// memory area on some later Update or Finish call.
//
// The lengths of buffers are always equal, e.g. aInbuf.Length()
// octets will always fit into aOutbuf. This length can be anything
// from zero upwards. The cipher must work even if octets were
// fed to it one by one.
//
// @param aOutbuf result of the decrypt/encrypt
// @param aInbuf input to decrypt/encrypt
*/
virtual void Update(TDes8& aOutbuf,const TDesC8& aInbuf)=0;
/**
// Finish encryption or decryption.
//
// Calling Finish is optional, it is needed if the total
// bytes is not multiple of the blocksize, or if one wants
// to get the final IV.
//
// IPSEC does use the final IV.
//
// @param aIV the place to return the final IV.
*/
virtual void Finish(TDes8& aIV)=0;
virtual ~CSymmetricCipher() {}
};
// CProtocolCrypto
// ***************
/**
// Base class of the protocol implementing an algorithm library as a protocol
//
// All algorithm libraries must be derived from this base class.
*/
class CProtocolCrypto : public CProtocolBase
{
public:
/**
// Return the list of supported algorithms.
//
// IPSEC calls this method once during the binding
// process to find out the algorithms that are supported
// by this library.
//
// @retval aList
// a pointer to a new allocated array of TAlgorithmDesc.
// This array contains the descriptions of the supported
// algorithms. Can also return NULL, if not algorithms
// are supported at this point. The calling IPSEC will
// release this array, when it is not needed.
//
// @returns
// the length of the the array. May also return <= 0,
// in which case IPSEC will not be using any algorithms
// from this library.
*/
virtual TUint AlgorithmList(TAlgorithmDesc *&aList) = 0;
/**
// Create an instance of cipher algorithm
//
// When IPSEC requires a use of specific algorithm, it
// asks a new instance of the algorithm by calling this
// method.
//
// @param aAlg
// index of the algorithm in the array of descriptions
// that was returned by the AlgorithmList().
//
// @param aKey - The key value to be used in the encryption/decryption operation
// @return
// @li NULL, if algorithm could not be instantiated
// @li non-NULL (= new algorithm engine instance), if algorithm instantiated
*/
virtual CryptoSpi::CSymmetricCipher* SymmetricCipherL(TUint aAlg, const TDesC8 &aKey)=0;
#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
virtual CryptoSpi::CMac* GetMacImplementationL(const TDesC8& aKey)=0;
#endif
/**
// Create an instance of digest algorithm
//
// When IPSEC requires a use of specific algorithm, it
// asks a new instance of the algorithm by calling this
// method.
//
// @param aAlg
// index of the algorithm in the array of descriptions
// that was returned by the AlgorithmList().
//
// @return
// @li NULL, if algorithm could not be instantiated
// @li non-NULL (= new algorithm engine instance), if algorithm instantiated
*/
virtual CMessageDigestCrypto* MessageDigest(TUint aAlg)=0;
protected:
virtual ~CProtocolCrypto() {}
};
#endif