crypto/weakcryptospi/source/pkcs12kdf/pkcs12kdf.cpp
author Mikko Sunikka <mikko.sunikka@nokia.com>
Fri, 06 Nov 2009 13:21:00 +0200
changeset 19 cd501b96611d
permissions -rw-r--r--
Revision: 200945 Kit: 200945
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
19
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     1
/*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     2
* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     3
* All rights reserved.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     4
* This component and the accompanying materials are made available
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     5
* under the terms of the License "Eclipse Public License v1.0"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     6
* which accompanies this distribution, and is available
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     8
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
     9
* Initial Contributors:
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    11
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    12
* Contributors:
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    13
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    14
* Description: 
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    15
*
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    16
*/
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    17
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    18
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    19
#include <hash.h>
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    20
#include <bigint.h>
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    21
#include "pkcs12kdf.h"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    22
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    23
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    24
EXPORT_C HBufC8* PKCS12KDF::GeneratePasswordLC(const TDesC& aDes)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    25
/**
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    26
	Convert the supplied string to a byte string, as described
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    27
	in SB.1 of the PKCS 12 v1.0.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    28
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    29
	Each character is converted to a big endian two-byte value,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    30
	and a terminating NULL character is appended to the end.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    31
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    32
	@param	aDes			String to use as password.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    33
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    34
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    35
	const TInt len = aDes.Length();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    36
	HBufC8* pwdBytes = HBufC8::NewMaxLC((len + 1) * 2);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    37
	TPtr8 pbDes = pwdBytes->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    38
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    39
	TInt i = 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    40
	while (i < len)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    41
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    42
		TUint16 ch = aDes[i];
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    43
		pbDes[i * 2] = ch >> 8;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    44
		pbDes[(i * 2) + 1] = ch;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    45
		++i;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    46
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    47
	pbDes[i * 2] = pbDes[(i * 2) + 1] = 0;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    48
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    49
	return pwdBytes;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    50
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    51
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    52
static TInt CeilDiv(TInt aNumerator, TInt aDenominator)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    53
/**
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    54
	Utility function returns ceil(aNumerator / aDenominator).
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    55
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    56
	@param	aNumerator		The numerator.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    57
	@param	aDenominator	Denominator, which cannot be zero.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    58
	@return					ceil(aNumerator / aDenominator)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    59
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    60
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    61
	TInt result = aNumerator / aDenominator;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    62
	if ((aNumerator % aDenominator) > 0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    63
		++result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    64
	return result;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    65
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    66
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    67
EXPORT_C void PKCS12KDF::DeriveKeyL(
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    68
	TDes8& aKey, TIDByteType aIDType,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    69
	const TDesC8& aPasswd, const TDesC8& aSalt, const TUint aIterations)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    70
/**
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    71
	Generate a key for the supplied password and salt.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    72
	This implementation uses SHA1 as the hashing algorithm.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    73
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    74
	@param	aKey			Descriptor which will hold key.  On entry
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    75
							its length must be set to the expected key length.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    76
	@param	aIDType			Whether this function is being called to generate
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    77
							an (en|de)cryption key, an initialization vector,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    78
							or a key for MAC-ing.  See SB.3 of spec.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    79
	@param	aPasswd			Password string.  To comply with PKCS#12 spec,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    80
							this must have 2-byte big-endian characters with
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    81
							a terminating null character.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    82
	@param	aSalt			Used with aPasswd to generate key.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    83
	@param	aIterations		Number of times to call the hash function for
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    84
							each block in the key.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    85
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    86
	@panic	PKCS#12 16		Password is empty (debug only.)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    87
	@panic	PKCS#12 17		Password does not contain an even number of bytes,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    88
							and so can't use double-byte characters (debug only.)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    89
	@panic	PKCS#12 18		The final two-byte character is not a null terminator,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    90
							or a null terminator occurs before the end (debug only.)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    91
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    92
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    93
	__ASSERT_DEBUG(aPasswd.Length() >= 2, Panic(EDKEmptyPswd));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    94
	__ASSERT_DEBUG((aPasswd.Length() % 2) == 0, Panic(EDKOddPswdByteCount));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    95
	TInt useCharCount = aPasswd.Length() / 2;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    96
	TPtrC16 pswd16(reinterpret_cast<const TUint16*>(aPasswd.Ptr()), useCharCount);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    97
	TInt nullPos = pswd16.Locate(L'\0');
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    98
	__ASSERT_DEBUG(nullPos == (useCharCount - 1), Panic(EDKBadNullTerminator));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
    99
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   100
	// use the same notation as the standard
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   101
	const TUint8 ID = static_cast<TUint8>(aIDType);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   102
	const TInt u = 160;					// chaining variable length for SHA-1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   103
	const TInt v = 512;					// message input length for SHA-1
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   104
	const TInt n = aKey.Length() * 8;	// number of bits required in key
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   105
	const TInt p = aPasswd.Length();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   106
	const TInt s = aSalt.Length();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   107
	const TInt r = aIterations;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   108
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   109
	// (numbered steps are from the standard)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   110
	// 1. Construct a string, D (the "diversifier"), by concatenating
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   111
	// v/8 copies of ID.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   112
	const TInt D_LEN = v / 8;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   113
	HBufC8* D_ = HBufC8::NewMaxLC(D_LEN);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   114
	TPtr8 D = D_->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   115
	D.Fill(ID);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   116
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   117
	// 2. Concatenate copies of the salt together to create a string S
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   118
	// of length v * ceil(s/v) bits (the final copy of the salt may be
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   119
	// truncated to create S).  Note that if the salt is the empty string,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   120
	// then so is S.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   121
	const TInt S_OVER_V_CEIL = CeilDiv(s, v);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   122
	const TInt S_LEN = (v * S_OVER_V_CEIL) / 8;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   123
	HBufC8* S_ = HBufC8::NewMaxLC(S_LEN);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   124
	TPtr8 S = S_->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   125
	S.Repeat(aSalt);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   126
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   127
	// 3. Concatenate copies of the password together to create a string P
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   128
	// of length v * ceil(p/v) bits (the final copy of the password may be
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   129
	// truncated to create P).  Note that if the password is the empty string
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   130
	// then so is P.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   131
	const TInt P_OVER_V_CEIL = CeilDiv(p, v);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   132
	const TInt P_LEN = (v * P_OVER_V_CEIL) / 8;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   133
	HBufC8* P_ = HBufC8::NewMaxLC(P_LEN);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   134
	TPtr8 P = P_->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   135
	P.Repeat(aPasswd);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   136
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   137
	// 4. Set I=S||P to be the concatenation of S and P.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   138
	const TInt I_LEN = S_LEN + P_LEN;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   139
	HBufC8* I_ = HBufC8::NewLC(I_LEN);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   140
	TPtr8 I = I_->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   141
	I.Copy(S);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   142
	I.Append(P);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   143
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   144
	// 5. Set c=ceil(n/u).
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   145
	const TInt c = CeilDiv(n, u);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   146
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   147
	// ahead 7: allocate result buffer A
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   148
	// (Each Ai has SHA1_HASH bytes.)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   149
	HBufC8* A_ = HBufC8::NewLC(c * SHA1_HASH);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   150
	TPtr8 A = A_->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   151
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   152
	// 6. For i=1, 2, ..., c, do the following
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   153
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   154
	// pre-allocate SHA1 object, DI, and B buffers
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   155
	CSHA1* sha1 = CSHA1::NewL();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   156
	CleanupStack::PushL(sha1);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   157
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   158
	const TInt DI_LEN = D_LEN + I_LEN;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   159
	HBufC8* DI_ = HBufC8::NewLC(DI_LEN);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   160
	TPtr8 DI = DI_->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   161
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   162
	const TInt B_LEN = v / 8;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   163
	HBufC8* B_ = HBufC8::NewMaxLC(B_LEN);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   164
	TPtr8 B = B_->Des();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   165
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   166
	for (TInt i = 1; i <= c; ++i)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   167
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   168
		// 6a) Set Ai = H^r(D||I).  (i.e. the rth hash of D||I,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   169
		// H(H(H(...H(D||I))))
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   170
		DI.Copy(D);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   171
		DI.Append(I);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   172
		
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   173
		sha1->Reset();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   174
		TBuf8<SHA1_HASH> Ai(sha1->Final(DI));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   175
		
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   176
		for (TInt iterCount = 2; iterCount <= r; ++iterCount)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   177
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   178
			Ai.Copy(sha1->Final(Ai));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   179
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   180
		
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   181
		// 6b) Concatenate copies of Ai to create a string B of length
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   182
		// v bits (the final copy of Ai may be truncated to create B).
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   183
		B.Repeat(Ai);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   184
		
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   185
		// 6c) Treating I as a concatenation I0, I1, ..., Ik-1 of
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   186
		// v-bit blocks, where k=ceil(s/v)+ceil(p/v), modify I by
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   187
		// setting Ij=(Ij+B+1) mod 2^v for each j.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   188
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   189
		const TInt k = S_OVER_V_CEIL + P_OVER_V_CEIL;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   190
		for (TInt j = 0; j < k; ++j)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   191
			{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   192
			TPtr8 section = I.MidTPtr((v/8) * j, v/8);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   193
			Process6cL(section, B, v);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   194
			}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   195
		
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   196
		// 7. Concatenate A1, A2, ..., Ac together to form a pseudo-random
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   197
		// bit string, A.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   198
		A.Append(Ai);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   199
		
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   200
		// stop building A if already have enough bits for key
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   201
		if (A.Length() >= n / 8)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   202
			break;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   203
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   204
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   205
	// Use the first n bits of A as the output of this entire process.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   206
	aKey.Copy(A.Left(n / 8));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   207
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   208
	CleanupStack::PopAndDestroy(8, D_);	// B_, DI_, sha1, A_, I_, P_, S_, D_
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   209
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   210
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   211
void PKCS12KDF::Process6cL(TDes8& Ij, const TDesC8& B, TInt v)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   212
/**
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   213
	Helper function for DeriveKeyL modifies part of I,
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   214
	as described in step 6c of SB.2.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   215
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   216
	@param	Ij		Section of I (S || P).
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   217
	@param	B		rth hash of D || I.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   218
	@param	v		Number of bits to preserve in result.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   219
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   220
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   221
	// 6c) Treating I as a concatenation I0, I1, ..., Ik-1 of
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   222
	// v-bit blocks, where k=ceil(s/v)+ceil(p/v), modify I by
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   223
	// setting Ij=(Ij+B+1) mod 2^v for each j.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   224
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   225
	RInteger RI_Ij = RInteger::NewL(Ij);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   226
	TCleanupItem ciIj = RI_Ij;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   227
	CleanupStack::PushL(ciIj);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   228
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   229
	RInteger RI_B = RInteger::NewL(B);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   230
	TCleanupItem ciB = RI_B;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   231
	CleanupStack::PushL(ciB);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   232
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   233
	// these additions can leave
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   234
	RI_Ij += RI_B;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   235
	RI_Ij += 1;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   236
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   237
	HBufC8* result = RI_Ij.BufferLC();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   238
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   239
	Ij.Zero();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   240
	TInt resultLen = result->Length();
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   241
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   242
	TInt bytesToPreserve = v / 8;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   243
	TInt leadingZeroes = bytesToPreserve - resultLen;
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   244
	if (leadingZeroes <= 0)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   245
		Ij.Copy(result->Right(bytesToPreserve));
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   246
	else
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   247
		{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   248
		Ij.FillZ(leadingZeroes);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   249
		Ij.Append(*result);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   250
		}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   251
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   252
	CleanupStack::PopAndDestroy(3, &RI_Ij);	// result, ciB, ciIj
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   253
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   254
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   255
#ifdef _DEBUG
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   256
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   257
void PKCS12KDF::Panic(PKCS12KDF::TPanic aPanic)
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   258
/**
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   259
	This function is used in debug builds to halt
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   260
	the current thread when a logic error is detected.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   261
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   262
	The current thread is panicked with category "PKCS12KDF"
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   263
	and the supplied reason.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   264
	
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   265
	@param	aPanic			Converted to numeric value and
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   266
							used for the panic reason.
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   267
 */
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   268
	{
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   269
	_LIT(KPanicCat, "PKCS12KDF");
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   270
	User::Panic(KPanicCat, aPanic);
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   271
	}
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   272
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   273
#endif
cd501b96611d Revision: 200945
Mikko Sunikka <mikko.sunikka@nokia.com>
parents:
diff changeset
   274