/** Copyright (c) 2003-2009 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:** Description: * ** IMPORTANT ** API's in this file are published to 3rd party developers via the * Symbian website. Changes to these API's should be treated as PublishedAll API changes and the Security TA should be consulted.* Asymmetric crypto implementation**//** @file @publishedAll @released */#ifndef __ASYMMETRIC_H__#define __ASYMMETRIC_H__#include <padding.h>#include <asymmetrickeys.h>#include <random.h>#include <hash.h>// All the classes in this file have their default constructors and// assignment operators defined private, but not implemented, in order to// prevent their use./** * Mixin class defining common operations for public key encryption and* decryption classes.* */class MCryptoSystem {public: /** * Gets the maximum size of input accepted by this object. * * @return The maximum input length allowed in bytes. */ virtual TInt MaxInputLength(void) const = 0; /** * Gets the maximum size of output that can be generated by this object. * * @return The maximum output length in bytes. */ virtual TInt MaxOutputLength(void) const = 0;protected: /** * Constructor */ IMPORT_C MCryptoSystem(void);private: MCryptoSystem(const MCryptoSystem&); MCryptoSystem& operator=(const MCryptoSystem&); };/** * Abstract base class for all public key encryptors.* */class CEncryptor : public CBase, public MCryptoSystem {public: /** * Encrypts the specified plaintext into ciphertext. * * @param aInput The plaintext * @param aOutput On return, the ciphertext * * @panic KCryptoPanic If the input data is too long. * See ECryptoPanicInputTooLarge * @panic KCryptoPanic If the supplied output descriptor is not large enough to store the result. * See ECryptoPanicOutputDescriptorOverflow */ virtual void EncryptL(const TDesC8& aInput, TDes8& aOutput) const = 0;protected: /** Default constructor */ IMPORT_C CEncryptor(void);private: CEncryptor(const CEncryptor&); CEncryptor& operator=(const CEncryptor&); };/** * Abstract base class for all public key decryptors.* */class CDecryptor : public CBase, public MCryptoSystem {public: /** * Decrypts the specified ciphertext into plaintext * * @param aInput The ciphertext to be decrypted * @param aOutput On return, the plaintext * * @panic KCryptoPanic If the input data is too long. * See ECryptoPanicInputTooLarge * @panic KCryptoPanic If the supplied output descriptor is not large enough to store the result. * See ECryptoPanicOutputDescriptorOverflow */ virtual void DecryptL(const TDesC8& aInput, TDes8& aOutput) const = 0;protected: /** Default constructor */ IMPORT_C CDecryptor(void);private: CDecryptor(const CDecryptor&); CDecryptor& operator=(const CDecryptor&); };/*** Implementation of RSA encryption as described in PKCS#1 v1.5.* */class CRSAPKCS1v15Encryptor : public CEncryptor {public: /** * Creates a new RSA encryptor object using PKCS#1 v1.5 padding. * * @param aKey The RSA encryption key * @return A pointer to a new CRSAPKCS1v15Encryptor object * * @leave KErrKeyNotWeakEnough If the key size is larger than that allowed by the * cipher strength restrictions of the crypto library. * See TCrypto::IsAsymmetricWeakEnoughL() * @leave KErrKeySize If the key length is too small */ IMPORT_C static CRSAPKCS1v15Encryptor* NewL(const CRSAPublicKey& aKey); /** * Creates a new RSA encryptor object using PKCS#1 v1.5 padding. * * The returned pointer is put onto the cleanup stack. * * @param aKey The RSA encryption key * @return A pointer to a new CRSAPKCS1v15Encryptor object * * @leave KErrKeyNotWeakEnough If the key size is larger than that allowed by the * cipher strength restrictions of the crypto library. * See TCrypto::IsAsymmetricWeakEnoughL() * @leave KErrKeySize If the key length is too small */ IMPORT_C static CRSAPKCS1v15Encryptor* NewLC(const CRSAPublicKey& aKey); void EncryptL(const TDesC8& aInput, TDes8& aOutput) const; TInt MaxInputLength(void) const; TInt MaxOutputLength(void) const; /** The destructor frees all resources owned by the object, prior to its destruction. */ virtual ~CRSAPKCS1v15Encryptor(void);protected: /** @internalAll */ CRSAPKCS1v15Encryptor(const CRSAPublicKey& aKey); /** @internalAll */ void ConstructL(void);protected: /** The RSA public key */ const CRSAPublicKey& iPublicKey; /** The PKCS#1 v1.5 encryption padding */ CPaddingPKCS1Encryption* iPadding;private: CRSAPKCS1v15Encryptor(const CRSAPKCS1v15Encryptor&); CRSAPKCS1v15Encryptor& operator=(const CRSAPKCS1v15Encryptor&); };/** * Implementation of RSA decryption as described in PKCS#1 v1.5.**/class CRSAPKCS1v15Decryptor : public CDecryptor {public: /** * Creates a new RSA decryptor object using PKCS#1 v1.5 padding. * * @param aKey The RSA private key for decryption * * @leave KErrKeyNotWeakEnough If the key size is larger than that allowed by the * cipher strength restrictions of the crypto library. * See TCrypto::IsAsymmetricWeakEnoughL() * @leave KErrKeySize If the key length is too small */ IMPORT_C static CRSAPKCS1v15Decryptor* NewL(const CRSAPrivateKey& aKey); /** * Creates a new RSA decryptor object using PKCS#1 v1.5 padding * * The returned pointer is put onto the cleanup stack. * * @param aKey The RSA private key for decryption * * @leave KErrKeyNotWeakEnough If the key size is larger than that allowed by the * cipher strength restrictions of the crypto library. * See TCrypto::IsAsymmetricWeakEnoughL() * @leave KErrKeySize If the key length is too small * @leave KErrNotSupported If the RSA private key is not a supported TRSAPrivateKeyType */ IMPORT_C static CRSAPKCS1v15Decryptor* NewLC(const CRSAPrivateKey& aKey); void DecryptL(const TDesC8& aInput, TDes8& aOutput) const; TInt MaxInputLength(void) const; TInt MaxOutputLength(void) const; /** The destructor frees all resources owned by the object, prior to its destruction. */ virtual ~CRSAPKCS1v15Decryptor(void);protected: /** @internalAll */ CRSAPKCS1v15Decryptor(const CRSAPrivateKey& aKey); /** @internalAll */ void ConstructL(void);protected: /** The RSA private key */ const CRSAPrivateKey& iPrivateKey; /** The PKCS#1 v1.5 encryption padding */ CPaddingPKCS1Encryption* iPadding;private: CRSAPKCS1v15Decryptor(const CRSAPKCS1v15Decryptor&); CRSAPKCS1v15Decryptor& operator=(const CRSAPKCS1v15Decryptor&); };/** * Mixin class defining operations common to all public key signature systems.**/class MSignatureSystem {public: /** * Gets the maximum size of input accepted by this object. * * @return The maximum length allowed in bytes */ virtual TInt MaxInputLength(void) const = 0;protected: /** Constructor */ IMPORT_C MSignatureSystem(void);private: MSignatureSystem(const MSignatureSystem&); MSignatureSystem& operator=(const MSignatureSystem&); };/** * Abstract base class for all public key signers.** The template parameter, CSignature, should be a class that encapsulates the* concept of a digital signature. Derived signature classes must own their* respective signatures (and hence be CBase derived). There are no other* restrictions on the formation of the signature classes.* */template <class CSignature> class CSigner : public CBase, public MSignatureSystem {public: /** * Digitally signs the specified input message * * @param aInput The raw data to sign, typically a hash of the actual message * @return A pointer to a new CSignature object * * @panic ECryptoPanicInputTooLarge If aInput is larger than MaxInputLength(), * which is likely to happen if the caller * has passed in something that has not been * hashed. */ virtual CSignature* SignL(const TDesC8& aInput) const = 0;protected: /** @internalAll */ CSigner(void);private: CSigner(const CSigner&); CSigner& operator=(const CSigner&); };/** * Abstract class for all public key verifiers.** The template parameter, CSignature, should be a class that encapsulates the* concept of a digital signature. Derived signature classes must own their* respective signatures (and hence be CBase derived). There are no other* restrictions on the formation of the signature classes.* */template <class CSignature> class CVerifier : public CBase, public MSignatureSystem {public: /** * Verifies the specified digital signature * * @param aInput The message digest that was originally signed * @param aSignature The signature to be verified * * @return Whether the signature is the result of signing * aInput with the supplied key */ virtual TBool VerifyL(const TDesC8& aInput, const CSignature& aSignature) const = 0;protected: /** @internalAll */ CVerifier(void);private: CVerifier(const CVerifier&); CVerifier& operator=(const CVerifier&); };/* Template nastiness for CVerifier and CSigner in asymmetric.inl */#include <asymmetric.inl>/** * An encapsulation of a RSA signature.* */class CRSASignature : public CBase {public: /** * Creates a new CRSASignature object from the integer value * output of a previous RSA signing operation. * * @param aS The integer value output from a previous RSA signing operation * @return A pointer to the new CRSASignature object. */ IMPORT_C static CRSASignature* NewL(RInteger& aS); /** * Creates a new CRSASignature object from the integer value * output of a previous RSA signing operation. * * The returned pointer is put onto the cleanup stack. * * @param aS The integer value output from a previous RSA signing operation * @return A pointer to the new CRSASignature object. */ IMPORT_C static CRSASignature* NewLC(RInteger& aS); /** * Gets the integer value of the RSA signature * * @return The integer value of the RSA signature */ IMPORT_C const TInteger& S(void) const; /** * Whether this RSASignature is identical to a specified RSASignature * * @param aSig The RSASignature for comparison * @return ETrue, if the two signatures are identical; EFalse, otherwise. */ IMPORT_C TBool operator== (const CRSASignature& aSig) const; /** Destructor */ /** The destructor frees all resources owned by the object, prior to its destruction. */ IMPORT_C virtual ~CRSASignature(void);protected: /** * Second phase constructor * * @see CRSASignature::NewL() * * @param aS The integer value output from a previous RSA signing operation */ IMPORT_C CRSASignature(RInteger& aS); /** Default constructor */ IMPORT_C CRSASignature(void);protected: /** An integer value; the output from a previous RSA signing operation. */ RInteger iS;private: CRSASignature(const CRSASignature&); CRSASignature& operator=(const CRSASignature); };/** * Abstract base class for all RSA Signers.* */class CRSASigner : public CSigner<CRSASignature> {public: /** * Gets the maximum size of output that can be generated by this object. * * @return The maximum output length in bytes */ virtual TInt MaxOutputLength(void) const = 0;protected: /** Default constructor */ IMPORT_C CRSASigner(void);private: CRSASigner(const CRSASigner&); CRSASigner& operator=(const CRSASigner&); };/*** Implementation of RSA signing as described in PKCS#1 v1.5.* * This class creates RSA signatures following the RSA PKCS#1 v1.5 standard (with* the one caveat noted below) and using PKCS#1 v1.5 signature padding. The only* exception is that the SignL() function simply performs a 'raw' PKCS#1 v1.5 sign* operation on whatever it is given. It does <b>not</b> hash or in any way* manipulate the input data before signing. * */class CRSAPKCS1v15Signer : public CRSASigner {public: /** * Creates a new CRSAPKCS1v15Signer object from a specified RSA private key. * * @param aKey The RSA private key to be used for signing * @return A pointer to the new CRSAPKCS1v15Signer object * * @leave KErrKeySize If the key length is too small */ IMPORT_C static CRSAPKCS1v15Signer* NewL(const CRSAPrivateKey& aKey); /** * Creates a new CRSAPKCS1v15Signer object from a specified RSA private key. * * The returned pointer is put onto the cleanup stack. * * @param aKey The RSA private key to be used for signing * @return A pointer to the new CRSAPKCS1v15Signer object * * @leave KErrKeySize If the key length is too small */ IMPORT_C static CRSAPKCS1v15Signer* NewLC(const CRSAPrivateKey& aKey); /** * Digitally signs the specified input message * * @param aInput The raw data to sign, typically a hash of the actual message * @return A pointer to a new CSignature object * * @leave KErrNotSupported If the private key is not a supported TRSAPrivateKeyType * @panic ECryptoPanicInputTooLarge If aInput is larger than MaxInputLength(), * which is likely to happen if the caller * has passed in something that has not been hashed. */ virtual CRSASignature* SignL(const TDesC8& aInput) const; virtual TInt MaxInputLength(void) const; virtual TInt MaxOutputLength(void) const; /** The destructor frees all resources owned by the object, prior to its destruction. * @internalAll */ ~CRSAPKCS1v15Signer(void);protected: /** @internalAll */ CRSAPKCS1v15Signer(const CRSAPrivateKey& aKey); /** @internalAll */ void ConstructL(void);protected: /** The RSA private key to be used for signing */ const CRSAPrivateKey& iPrivateKey; /** The PKCS#1 v1.5 signature padding */ CPaddingPKCS1Signature* iPadding;private: CRSAPKCS1v15Signer(const CRSAPKCS1v15Signer&); CRSAPKCS1v15Signer& operator=(const CRSAPKCS1v15Signer&); };/** * Abstract base class for all RSA Verifiers.**/class CRSAVerifier : public CVerifier<CRSASignature> {public: /** * Gets the maximum size of output that can be generated by this object. * * @return The maximum output length in bytes */ virtual TInt MaxOutputLength(void) const = 0; /** * Performs a decryption operation on a signature using the public key. * * This is the inverse of the sign operation, which performs a encryption * operation on its input data using the private key. Although this can be * used to verify signatures, CRSAVerifier::VerifyL should be used in * preference. This method is however required by some security protocols. * * @param aSignature The signature to be verified * @return A pointer to a new buffer containing the result of the * operation. The pointer is left on the cleanup stack. */ virtual HBufC8* InverseSignLC(const CRSASignature& aSignature) const = 0; IMPORT_C virtual TBool VerifyL(const TDesC8& aInput, const CRSASignature& aSignature) const;protected: /** Default constructor */ IMPORT_C CRSAVerifier(void);private: CRSAVerifier(const CRSAVerifier&); CRSAVerifier& operator=(const CRSAVerifier&); };/*** This class verifies RSA signatures given a message and its supposed* signature. It follows the RSA PKCS#1 v1.5 with PKCS#1 v1.5 padding specification* with the following exception: the VerifyL() function does <b>not</b> hash or* in any way manipulate the input data before checking. Thus in order to verify* RSA signatures in PKCS#1 v1.5 format, the input data needs to follow PKCS#1 v1.5 * specification, i.e. be ASN.1 encoded and prefixed by ASN.1 encoded digestId.* */class CRSAPKCS1v15Verifier : public CRSAVerifier {public: /** * Creates a new CRSAPKCS1v15Verifier object from a specified RSA public key. * * @param aKey The RSA public key to be used for verifying * @return A pointer to the new CRSAPKCS1v15Verifier object * * @leave KErrKeySize If the key length is too small */ IMPORT_C static CRSAPKCS1v15Verifier* NewL(const CRSAPublicKey& aKey); /** * Creates a new CRSAPKCS1v15Verifier object from a specified RSA public key. * * The returned pointer is put onto the cleanup stack. * * @param aKey The RSA public key to be used for verifying * @return A pointer to the new CRSAPKCS1v15Verifier object * * @leave KErrKeySize If the key length is too small */ IMPORT_C static CRSAPKCS1v15Verifier* NewLC(const CRSAPublicKey& aKey); virtual HBufC8* InverseSignLC(const CRSASignature& aSignature) const; virtual TInt MaxInputLength(void) const; virtual TInt MaxOutputLength(void) const; /** The destructor frees all resources owned by the object, prior to its destruction. */ virtual ~CRSAPKCS1v15Verifier(void);protected: /** @internalAll */ CRSAPKCS1v15Verifier(const CRSAPublicKey& aKey); /** @internalAll */ void ConstructL(void);protected: /** The RSA public key to be used for verification */ const CRSAPublicKey& iPublicKey; /** The PKCS#1 v1.5 signature padding */ CPaddingPKCS1Signature* iPadding;private: CRSAPKCS1v15Verifier(const CRSAPKCS1v15Verifier&); CRSAPKCS1v15Verifier& operator=(const CRSAPKCS1v15Verifier&); };/** * An encapsulation of a DSA signature.* */class CDSASignature : public CBase {public: /** * Creates a new CDSASignature object from the specified R and S values. * * @param aR The DSA signature's R value * @param aS The DSA signature's S value * @return A pointer to the new CDSASignature object */ IMPORT_C static CDSASignature* NewL(RInteger& aR, RInteger& aS); /** * Creates a new CDSASignature object from the specified R and S values. * * The returned pointer is put onto the cleanup stack. * * @param aR The DSA signature's R value * @param aS The DSA signature's S value * @return A pointer to the new CDSASignature object */ IMPORT_C static CDSASignature* NewLC(RInteger& aR, RInteger& aS); /** * Gets the DSA signature's R value * * @return The R value */ IMPORT_C const TInteger& R(void) const; /** * Gets the DSA signature's S value * * @return The S value */ IMPORT_C const TInteger& S(void) const; /** * Whether this DSASignature is identical to a specified DSASignature * * @param aSig The DSASignature for comparison * @return ETrue, if the two signatures are identical; EFalse, otherwise. */ IMPORT_C TBool operator== (const CDSASignature& aSig) const; /** The destructor frees all resources owned by the object, prior to its destruction. */ IMPORT_C virtual ~CDSASignature(void);protected: /** * Protected constructor * * @param aR The DSA signature's R value * @param aS The DSA signature's S value */ IMPORT_C CDSASignature(RInteger& aR, RInteger& aS); /** Default constructor */ IMPORT_C CDSASignature(void);protected: /** The DSA signature's R value */ RInteger iR; /** The DSA signature's S value */ RInteger iS;private: CDSASignature(const CDSASignature&); CDSASignature& operator=(const CDSASignature&); };/*** Implementation of DSA signing as specified in FIPS 186-2 change request 1.* */class CDSASigner : public CSigner<CDSASignature> {public: /** * Creates a new CDSASigner object from a specified DSA private key. * * @param aKey The DSA private key to be used for signing * @return A pointer to the new CDSASigner object */ IMPORT_C static CDSASigner* NewL(const CDSAPrivateKey& aKey); /** * Creates a new CDSASigner object from a specified DSA private key. * * The returned pointer is put onto the cleanup stack. * * @param aKey The DSA private key to be used for signing * @return A pointer to the new CDSASigner object */ IMPORT_C static CDSASigner* NewLC(const CDSAPrivateKey& aKey); /** * Digitally signs the specified input message * * Note that in order to be interoperable and compliant with the DSS, aInput * must be the result of a SHA-1 hash. * * @param aInput A SHA-1 hash of the message to sign * @return A pointer to a new CSignature object * * @panic ECryptoPanicInputTooLarge If aInput is larger than MaxInputLength(), * which is likely to happen if the caller * has passed in something that has not been hashed. */ virtual CDSASignature* SignL(const TDesC8& aInput) const; virtual TInt MaxInputLength(void) const;protected: /** @internalAll */ CDSASigner(const CDSAPrivateKey& aKey);protected: /** The DSA private key to be used for signing */ const CDSAPrivateKey& iPrivateKey;private: CDSASigner(const CDSASigner&); CDSASigner& operator=(const CDSASigner&); };/*** Implementation of DSA signature verification as specified in FIPS 186-2 change* request 1.* */class CDSAVerifier : public CVerifier<CDSASignature> {public: /** * Creates a new CDSAVerifier object from a specified DSA public key. * * @param aKey The DSA public key to be used for verifying * @return A pointer to the new CDSAVerifier object */ IMPORT_C static CDSAVerifier* NewL(const CDSAPublicKey& aKey); /** * Creates a new CDSAVerifier object from a specified DSA public key. * * The returned pointer is put onto the cleanup stack. * * @param aKey The DSA public key to be used for verifying * @return A pointer to the new CDSAVerifier object */ IMPORT_C static CDSAVerifier* NewLC(const CDSAPublicKey& aKey); /** * Verifies the specified digital signature * * Note that in order to be interoperable and compliant with the DSS, aInput * must be the result of a SHA-1 hash. * * @param aInput A SHA-1 hash of the received message * @param aSignature The signature to be verified * * @return Whether the signature is the result of signing * aInput with the supplied key */ virtual TBool VerifyL(const TDesC8& aInput, const CDSASignature& aSignature) const; virtual TInt MaxInputLength(void) const;protected: /** @internalAll */ CDSAVerifier(const CDSAPublicKey& aKey);protected: /** The DSA public key to be used for verification */ const CDSAPublicKey& iPublicKey;private: CDSAVerifier(const CDSAVerifier&); CDSAVerifier& operator=(const CDSAVerifier&); };/*** Implementation of Diffie-Hellman key agreement as specified in PKCS#3.* */class CDH : public CBase {public: /** * Creates a new CDH object from a specified DH private key. * * @param aPrivateKey The private key of this party * @return A pointer to the new CDH object */ IMPORT_C static CDH* NewL(const CDHPrivateKey& aPrivateKey); /** * Creates a new CDH object from a specified DH private key. * * The returned pointer is put onto the cleanup stack. * * @param aPrivateKey The private key of this party * @return A pointer to the new CDH object */ IMPORT_C static CDH* NewLC(const CDHPrivateKey& aPrivateKey); /** * Performs the key agreement operation. * * @param aPublicKey The public key of the other party * @return The agreed key */ IMPORT_C HBufC8* AgreeL(const CDHPublicKey& aPublicKey) const;protected: /** * Constructor * * @param aPrivateKey The DH private key */ IMPORT_C CDH(const CDHPrivateKey& aPrivateKey);protected: /** The DH private key */ const CDHPrivateKey& iPrivateKey;private: CDH(const CDH&); CDH& operator=(const CDH&); };#endif // __ASYMMETRIC_H__