1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcrypto/source/pkcs5kdf/pkcs5kdf.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,115 @@
1.4 +/*
1.5 +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +/**
1.23 + @file
1.24 +*/
1.25 +
1.26 +#include "pkcs5kdf.h"
1.27 +
1.28 +/* Before complaining about the variable names in this file,
1.29 + * read the pkcs5 spec and all will become clear.
1.30 + */
1.31 +
1.32 +EXPORT_C void TPKCS5KDF::DeriveKeyL(TDes8& aKey, const TDesC8& aPasswd, const TDesC8& aSalt,
1.33 + const TUint aIterations)
1.34 +{
1.35 + CSHA1* sha1 = CSHA1::NewL();
1.36 + CleanupStack::PushL(sha1);
1.37 + CHMAC* hmac = CHMAC::NewL(aPasswd, sha1);
1.38 + CleanupStack::Pop(sha1); //hmac now owns it
1.39 + CleanupStack::PushL(hmac);
1.40 +
1.41 + TUint hashBytes = hmac->HashSize();
1.42 + TUint c = aIterations;
1.43 + TUint l = aKey.Length() / hashBytes;
1.44 + if(aKey.Length() % hashBytes != 0) //round up if mod !=0
1.45 + {
1.46 + l+=1;
1.47 + }
1.48 + TUint r = aKey.Length() - (l-1) * hashBytes; //r == length of last block
1.49 +
1.50 + HBufC8* TiTemp = HBufC8::NewLC(hashBytes);
1.51 + TUint32* Ti = (TUint32*)(TiTemp->Ptr());
1.52 + aKey.SetLength(0); //we've already saved the length we want
1.53 +
1.54 + HBufC8* STemp = HBufC8::NewLC(aSalt.Length() + sizeof(TUint32));
1.55 + TUint32* S = (TUint32*)(STemp->Ptr());
1.56 +
1.57 + HBufC8* UiTemp = HBufC8::NewLC(hashBytes);
1.58 + TUint32* Ui = (TUint32*)(UiTemp->Ptr());
1.59 +
1.60 + const TUint32* salt = (TUint32*)(aSalt.Ptr());
1.61 + TUint saltBytes = aSalt.Length();
1.62 +
1.63 + for(TUint i = 1; i<=l; i++)
1.64 + {
1.65 + F(*hmac, Ti, S, Ui, hashBytes, salt, saltBytes, c, i);
1.66 + if(i == l)
1.67 + aKey.Append((TUint8*)Ti, r);
1.68 + else
1.69 + aKey.Append((TUint8*)Ti, hashBytes);
1.70 + }
1.71 +
1.72 + CleanupStack::PopAndDestroy(UiTemp);
1.73 + CleanupStack::PopAndDestroy(STemp);
1.74 + CleanupStack::PopAndDestroy(TiTemp);
1.75 + CleanupStack::PopAndDestroy(hmac);
1.76 + }
1.77 +
1.78 +void TPKCS5KDF::F(CMessageDigest& aDigest, TUint32* aAccumulator,
1.79 + TUint32* S, TUint32* Ui, TUint aHashBytes, const TUint32* aSalt,
1.80 + TUint aSaltBytes, TUint c, TUint i)
1.81 + {
1.82 + TUint8 itmp[4];
1.83 + itmp[0] = (TUint8)((i >> 24) & 0xff);
1.84 + itmp[1] = (TUint8)((i >> 16) & 0xff);
1.85 + itmp[2] = (TUint8)((i >> 8) & 0xff);
1.86 + itmp[3] = (TUint8)(i & 0xff);
1.87 + TUint8* endOfS = Mem::Copy(S, aSalt, aSaltBytes);
1.88 + Mem::Copy((TUint32*)endOfS, (TUint32*)&itmp, 4);
1.89 +
1.90 + TPtr8 sptr((TUint8*)S, aSaltBytes+4);
1.91 + sptr.SetLength(aSaltBytes+4);
1.92 + Mem::Copy(aAccumulator, (TUint32*)((aDigest.Final(sptr)).Ptr()),aHashBytes);
1.93 + Mem::Copy(Ui, aAccumulator, aHashBytes);
1.94 +
1.95 + for(TUint j=1; j<c; j++)
1.96 + {
1.97 + TPtr8 uiptr((TUint8*)Ui, aHashBytes);
1.98 + uiptr.SetLength(aHashBytes);
1.99 + Mem::Copy(Ui, (TUint32*)((aDigest.Final(uiptr)).Ptr()), aHashBytes);
1.100 + XORString(Ui, aAccumulator, aHashBytes);
1.101 + }
1.102 + }
1.103 +
1.104 +inline void TPKCS5KDF::XORString(const TUint32* aOp1, TUint32* aOp2,
1.105 + TUint aLength)
1.106 + {
1.107 + const TUint32* i = aOp1;
1.108 +
1.109 + //this will overflow the whole final word if aLength % 4 != 0
1.110 + //but I can't see this mattering cuz all memory allocation is on a word by word basis
1.111 + //i don't want to do this byte by byte as it'll be way slower
1.112 + //also, every sane digest is going to be a multiple of 4 -- so this isn't a problem
1.113 + for( ; aOp1 != (TUint32*)((TUint8*)i + aLength); )
1.114 + {
1.115 + *aOp2++ ^= *aOp1++;
1.116 + }
1.117 + }
1.118 +