sl@0: /* sl@0: * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "rsaimpl.h" sl@0: #include "rsafunction.h" sl@0: #include "pluginconfig.h" sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: using namespace SoftwareCrypto; sl@0: sl@0: /* CRSAImpl */ sl@0: CRSAImpl::CRSAImpl( sl@0: TUid aCryptoMode, sl@0: TUid aPadding) : sl@0: CAsymmetricCipherImpl(aCryptoMode, aPadding) sl@0: { sl@0: } sl@0: sl@0: CRSAImpl* CRSAImpl::NewL(const CKey& aKey, TUid aCryptoMode, TUid aPadding) sl@0: { sl@0: CRSAImpl* self = CRSAImpl::NewLC(aKey, aCryptoMode, aPadding); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CRSAImpl* CRSAImpl::NewLC(const CKey& aKey, TUid aCryptoMode, TUid aPadding) sl@0: { sl@0: CRSAImpl* self = new(ELeave) CRSAImpl(aCryptoMode, aPadding); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aKey); sl@0: return self; sl@0: } sl@0: sl@0: CRSAImpl::~CRSAImpl() sl@0: { sl@0: } sl@0: sl@0: TInt CRSAImpl::GetMaximumOutputLengthL() const sl@0: { sl@0: const TInteger& N = iKey->GetBigIntL(KRsaKeyParameterNUid); sl@0: sl@0: if (iCryptoMode.iUid == KCryptoModeDecrypt) sl@0: return N.ByteCount() - iPadding->MinPaddingLength(); sl@0: else sl@0: return N.ByteCount(); sl@0: } sl@0: sl@0: TInt CRSAImpl::GetMaximumInputLengthL() const sl@0: { sl@0: const TInteger& N = iKey->GetBigIntL(KRsaKeyParameterNUid); sl@0: sl@0: if (iCryptoMode.iUid == KCryptoModeEncrypt) sl@0: return N.ByteCount() - iPadding->MinPaddingLength(); sl@0: else sl@0: return N.ByteCount(); sl@0: } sl@0: sl@0: void CRSAImpl::ConstructL(const CKey& aKey) sl@0: { sl@0: const TInteger& N = aKey.GetBigIntL(KRsaKeyParameterNUid); sl@0: TCrypto::IsAsymmetricWeakEnoughL(N.BitCount()); sl@0: CAsymmetricCipherImpl::ConstructL(aKey); sl@0: sl@0: if (! IsValidKeyLengthL(N.ByteCount())) sl@0: { sl@0: User::Leave(KErrKeySize); sl@0: } sl@0: } sl@0: sl@0: CExtendedCharacteristics* CRSAImpl::CreateExtendedCharacteristicsL() sl@0: { sl@0: // All Symbian software plug-ins have unlimited concurrency, cannot be reserved sl@0: // for exclusive use and are not CERTIFIED to be standards compliant. sl@0: return CExtendedCharacteristics::NewL(KMaxTInt, EFalse); sl@0: } sl@0: sl@0: const CExtendedCharacteristics* CRSAImpl::GetExtendedCharacteristicsL() sl@0: { sl@0: return CRSAImpl::CreateExtendedCharacteristicsL(); sl@0: } sl@0: sl@0: TUid CRSAImpl::ImplementationUid() const sl@0: { sl@0: return KCryptoPluginRsaCipherUid; sl@0: } sl@0: sl@0: void CRSAImpl::EncryptL(const TDesC8& aInput, TDes8& aOutput) const sl@0: { sl@0: __ASSERT_DEBUG(aOutput.MaxLength() >= GetMaximumOutputLengthL(), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow)); sl@0: __ASSERT_DEBUG(aInput.Length() <= GetMaximumInputLengthL(), User::Panic(KCryptoPanic, ECryptoPanicInputTooLarge)); sl@0: sl@0: HBufC8* buf = HBufC8::NewLC(GetMaximumOutputLengthL()); sl@0: TPtr8 ptr = buf->Des(); sl@0: sl@0: iPadding->PadL(aInput, ptr); sl@0: RInteger input = RInteger::NewL(ptr); sl@0: CleanupStack::PushL(input); sl@0: sl@0: RInteger output; sl@0: RSAFunction::EncryptL(*iKey, input, output); sl@0: CleanupStack::PushL(output); sl@0: sl@0: aOutput.Append(*(output.BufferLC())); sl@0: CleanupStack::PopAndDestroy(4, buf); //BufferLC, output, input, buf sl@0: } sl@0: sl@0: void CRSAImpl::DecryptL(const TDesC8& aInput, TDes8& aOutput) const sl@0: { sl@0: __ASSERT_DEBUG(aOutput.MaxLength() >= GetMaximumOutputLengthL(), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow)); sl@0: __ASSERT_DEBUG(aInput.Length() <= GetMaximumInputLengthL(), User::Panic(KCryptoPanic, ECryptoPanicInputTooLarge)); sl@0: sl@0: RInteger input = RInteger::NewL(aInput); sl@0: CleanupStack::PushL(input); sl@0: sl@0: RInteger output; sl@0: sl@0: RSAFunction::DecryptL(*iKey, input, output); sl@0: CleanupStack::PushL(output); sl@0: sl@0: TPtrC8 ptr = *(output.BufferLC()); sl@0: iPadding->UnPadL(ptr, aOutput); sl@0: sl@0: CleanupStack::PopAndDestroy(3, &input); //BufferLC(), output, input sl@0: } sl@0: sl@0: void CRSAImpl::ProcessL(const TDesC8& aInput, TDes8& aOutput) sl@0: { sl@0: if (iCryptoMode.iUid == KCryptoModeEncrypt) sl@0: { sl@0: EncryptL(aInput, aOutput); sl@0: } sl@0: else sl@0: { sl@0: DecryptL(aInput, aOutput); sl@0: } sl@0: } sl@0: sl@0: TBool CRSAImpl::IsValidKeyLengthL(TInt aKeyBytes) const sl@0: { sl@0: if (aKeyBytes < 1) sl@0: return EFalse; sl@0: sl@0: switch (iCryptoMode.iUid) sl@0: { sl@0: case KCryptoModeEncrypt: sl@0: // Check if GetMaximumInputLengthL() makes sense, sl@0: // if not the key length must be too small sl@0: if (GetMaximumInputLengthL() <= 0) sl@0: return EFalse; sl@0: break; sl@0: sl@0: case KCryptoModeDecrypt: sl@0: // Check if GetMaximumOutputLengthL() makes sense, sl@0: // if not the key length must be too small sl@0: if (GetMaximumOutputLengthL() <= 0) sl@0: return EFalse; sl@0: break; sl@0: } sl@0: return ETrue; sl@0: } sl@0: