diff -r 000000000000 -r bde4ae8d615e os/security/crypto/weakcrypto/source/padding/padding.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/security/crypto/weakcrypto/source/padding/padding.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,362 @@ +/* +* Copyright (c) 1999-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: +* +*/ + + +#include +#include +#include +#include +#include + +/* CPadding */ +CPadding::CPadding(void) : iBlockBytes(-1) + { + } + +EXPORT_C CPadding::CPadding(TInt aBlockBytes) : iBlockBytes(aBlockBytes) + { + __ASSERT_ALWAYS(aBlockBytes > 0, User::Invariant()); + } + +EXPORT_C void CPadding::SetBlockSize(TInt aBlockBytes) + { + __ASSERT_ALWAYS(aBlockBytes > 0, User::Invariant()); + iBlockBytes = aBlockBytes; + } + +EXPORT_C TInt CPadding::BlockSize(void) const + { + return iBlockBytes; + } + +EXPORT_C TInt CPadding::MaxPaddedLength(TInt /*aInputBytes*/) const + { + return BlockSize(); + } + +EXPORT_C TInt CPadding::MaxUnPaddedLength(TInt aInputBytes) const + { + return aInputBytes - MinPaddingLength(); + } + +EXPORT_C void CPadding::PadL(const TDesC8& aInput, TDes8& aOutput) + { + // Check that the input is small enough to fit inside one padded block + __ASSERT_DEBUG(aInput.Length() <= BlockSize() - MinPaddingLength(), + User::Panic(KCryptoPanic, ECryptoPanicPadInputTooLarge)); + + // Check that the output descriptor supplied is large enough to store the result + __ASSERT_DEBUG(aOutput.MaxLength() >= MaxPaddedLength(aInput.Length()), + User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow)); + + // Call the virtual function, implemented by derived classes + DoPadL(aInput, aOutput); + } + +/* CPaddingNone */ +EXPORT_C CPaddingNone* CPaddingNone::NewL(TInt aBlockBytes) + { + __ASSERT_ALWAYS(aBlockBytes > 0, User::Leave(KErrArgument)); + return new(ELeave)CPaddingNone(aBlockBytes); + } + +EXPORT_C CPaddingNone* CPaddingNone::NewLC(TInt aBlockBytes) + { + CPaddingNone* self = CPaddingNone::NewL(aBlockBytes); + CleanupStack::PushL(self); + return self; + } + +EXPORT_C CPaddingNone::CPaddingNone(TInt aBlockBytes):CPadding(aBlockBytes) + { + } + +void CPaddingNone::DoPadL(const TDesC8& aInput,TDes8& aOutput) + { + aOutput.Append(aInput); + } + +void CPaddingNone::UnPadL(const TDesC8& aInput,TDes8& aOutput) + { + __ASSERT_DEBUG(aOutput.MaxLength() >= MaxPaddedLength(aInput.Length()), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow)); + aOutput.Append(aInput); + } + +TInt CPaddingNone::MinPaddingLength(void) const + { + return 0; + } + +TInt CPaddingNone::MaxPaddedLength(TInt aInputSize) const + { + return aInputSize; + } + +/* CPaddingSSLv3 */ +EXPORT_C CPaddingSSLv3* CPaddingSSLv3::NewL(TInt aBlockBytes) + { + __ASSERT_ALWAYS(aBlockBytes > 0, User::Leave(KErrArgument)); + return new(ELeave)CPaddingSSLv3(aBlockBytes); + } + +EXPORT_C CPaddingSSLv3* CPaddingSSLv3::NewLC(TInt aBlockBytes) + { + CPaddingSSLv3* self = CPaddingSSLv3::NewL(aBlockBytes); + CleanupStack::PushL(self); + return self; + } + +EXPORT_C CPaddingSSLv3::CPaddingSSLv3(TInt aBlockBytes):CPadding(aBlockBytes) + { + } + +void CPaddingSSLv3::DoPadL(const TDesC8& aInput,TDes8& aOutput) + { + TInt paddingBytes=BlockSize()-(aInput.Length()%BlockSize()); + aOutput.Append(aInput); + aOutput.SetLength(aOutput.Length()+paddingBytes); + for (TInt i=1;i<=paddingBytes;i++) + { + aOutput[aOutput.Length()-i]=(TUint8)(paddingBytes-1); + } + } + +void CPaddingSSLv3::UnPadL(const TDesC8& aInput,TDes8& aOutput) + { + TInt paddingLen = aInput[aInput.Length()-1] + 1; + + if (paddingLen > aInput.Length()) + { + User::Leave(KErrInvalidPadding); + } + + TInt outlen = aInput.Length() - paddingLen; + + __ASSERT_DEBUG(aOutput.MaxLength() >= outlen, User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow)); + + aOutput.Append(aInput.Left(outlen)); + } + +TInt CPaddingSSLv3::MinPaddingLength(void) const + { + //if aInputBytes is 1 less than the blocksize then we get 1 byte of padding + return 1; + } + +TInt CPaddingSSLv3::MaxPaddedLength(TInt aInputBytes) const + { + TUint padBytes = BlockSize() - (aInputBytes % BlockSize()); + return padBytes + aInputBytes; + } + +/* CPaddingPKCS1Signature */ +EXPORT_C CPaddingPKCS1Signature* CPaddingPKCS1Signature::NewL(TInt aBlockBytes) + { + return new(ELeave)CPaddingPKCS1Signature(aBlockBytes); + } + +EXPORT_C CPaddingPKCS1Signature* CPaddingPKCS1Signature::NewLC(TInt aBlockBytes) + { + CPaddingPKCS1Signature* self = CPaddingPKCS1Signature::NewL(aBlockBytes); + CleanupStack::PushL(self); + return self; + } + +EXPORT_C CPaddingPKCS1Signature::CPaddingPKCS1Signature(TInt aBlockBytes) + : CPadding(aBlockBytes) + { + } + +void CPaddingPKCS1Signature::DoPadL(const TDesC8& aInput,TDes8& aOutput) + { + aOutput.SetLength(BlockSize()); + TInt i; + TInt j; + aOutput[0]=0; + TInt startOfData=BlockSize()-aInput.Length(); + // PKCS1 also specifies a block type 0 for private key operations but + // does not recommend its use. This block type (0) is compatible with + // unpadded data though so you can create PKCS1 type 0 blocks using + // CPaddingNone. + aOutput[1]=1; // Block type 1 (private key operation) + for (i=2;i<(startOfData-1);i++) + { + aOutput[i]=0xff; + } + j=0; + aOutput[startOfData-1]=0; // separator + for (i=startOfData;i= len, User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow)); + + aOutput.SetLength(len); + TInt i=0; + while (dataStart , 0x00 + } + +/* CPaddingPKCS1Encryption */ +EXPORT_C CPaddingPKCS1Encryption* CPaddingPKCS1Encryption::NewL( + TInt aBlockBytes) + { + return new(ELeave)CPaddingPKCS1Encryption(aBlockBytes); + } + +EXPORT_C CPaddingPKCS1Encryption* CPaddingPKCS1Encryption::NewLC( + TInt aBlockBytes) + { + CPaddingPKCS1Encryption* self = CPaddingPKCS1Encryption::NewL(aBlockBytes); + CleanupStack::PushL(self); + return self; + } + +EXPORT_C CPaddingPKCS1Encryption::CPaddingPKCS1Encryption(TInt aBlockBytes) + : CPadding(aBlockBytes) + { + } + +void CPaddingPKCS1Encryption::DoPadL(const TDesC8& aInput,TDes8& aOutput) + { + aOutput.SetLength(BlockSize()); + + aOutput[0]=0; + TInt startOfData=BlockSize()-aInput.Length(); + aOutput[1]=2; // Block type 2 (public key operation) + TBuf8<256> rnd(256); + GenerateRandomBytesL(rnd); + + TInt i = 2; + TInt j = 0; + for (; i<(startOfData-1);) + { + if (rnd[j]) + { + aOutput[i++]=rnd[j]; + } + if (++j==256) + { + GenerateRandomBytesL(rnd); + j=0; + } + } + + j=0; + aOutput[startOfData-1]=0; // separator + for (i=startOfData;i= len, User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow)); + + aOutput.SetLength(len); + TInt i=0; + while (dataStart, 0x00 + } +