os/security/crypto/weakcryptospi/source/common/inlines.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/crypto/weakcryptospi/source/common/inlines.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,272 @@
     1.4 +/*
     1.5 +* Copyright (c) 2003-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 + @internalTechnology
    1.25 +*/
    1.26 + 
    1.27 +#ifndef __INLINES_H__
    1.28 +#define __INLINES_H__
    1.29 +
    1.30 +#include <e32base.h>
    1.31 +
    1.32 +#define assert(x) __ASSERT_DEBUG((x), User::Panic(_L("crypto.dll"), 1))
    1.33 +
    1.34 +#if defined(__GCC32__)
    1.35 +typedef long long Int64;
    1.36 +typedef unsigned long long Uint64;
    1.37 +#elif defined(__VC32__)
    1.38 +typedef __int64 Int64;
    1.39 +typedef unsigned __int64 Uint64;
    1.40 +#elif defined(__CW32__)
    1.41 +#pragma longlong on
    1.42 +typedef long long Int64;
    1.43 +typedef unsigned long long Uint64;
    1.44 +#endif
    1.45 +
    1.46 +typedef Uint64 dword;
    1.47 +typedef TUint word;
    1.48 +typedef TUint32 word32;
    1.49 +
    1.50 +const TUint WORD_SIZE = sizeof(TUint); 
    1.51 +const TUint WORD_BYTES = WORD_SIZE;
    1.52 +const TUint BYTE_BITS = 8;
    1.53 +const TUint WORD_BITS = WORD_SIZE*BYTE_BITS;
    1.54 +
    1.55 +//These next two versions of GETBYTE compile to LDR's of words and then shifts
    1.56 +//and ands to get it down to a byte.
    1.57 +//#define GETBYTE(x, y) (TUint)(((x)>>(8*(y)))&255)
    1.58 +//#define GETBYTE(x, y) (TUint)TUint8((x)>>(8*(y)))
    1.59 +
    1.60 +//This next version gets the best assembler on gcc and armv4 (it uses LDRB
    1.61 +//rather than shifts and ands
    1.62 +#define GETBYTE(x, y) (((TUint8 *)&(x))[y])
    1.63 +
    1.64 +#define MAKE_DWORD(lowWord, highWord) ((dword(highWord)<<WORD_BITS) | (lowWord))
    1.65 +#define LOW_WORD(x) (TUint32)(x)
    1.66 +#define HIGH_WORD(x) (TUint32)((x)>>WORD_BITS)
    1.67 +
    1.68 +template <class T> inline void TClassSwap(T& a, T& b)
    1.69 +	{
    1.70 +	T temp(a);
    1.71 +	a = b;
    1.72 +	b = temp;
    1.73 +	}
    1.74 +	
    1.75 +// Returns log2 of aNum where aNum is a power
    1.76 +// of two	
    1.77 +inline TUint8 CryptoLog2(TUint8 aNum)
    1.78 +	{
    1.79 +	switch (aNum)
    1.80 +		{		
    1.81 +		case 1:
    1.82 +			return 0;
    1.83 +		case 1 << 1:
    1.84 +			return 1;
    1.85 +		case 1 << 2:
    1.86 +			return 2;
    1.87 +		case 1 << 3:
    1.88 +			return 3;
    1.89 +		case 1 << 4:
    1.90 +			return 4;
    1.91 +		case 1 << 5:
    1.92 +			return 5;
    1.93 +		case 1 << 6:
    1.94 +			return 6;
    1.95 +		case 1 << 7:
    1.96 +			return 7;
    1.97 +		default:
    1.98 +			ASSERT(EFalse);
    1.99 +		}
   1.100 +	return 0;
   1.101 +	}
   1.102 +	
   1.103 +inline TUint BitsToBytes(TUint bitCount)
   1.104 +	{
   1.105 +	return ((bitCount+7)/(BYTE_BITS));
   1.106 +	}
   1.107 +
   1.108 +inline TUint BytesToWords(TUint byteCount)
   1.109 +	{
   1.110 +	return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
   1.111 +	}
   1.112 +
   1.113 +inline TUint BitsToWords(TUint bitCount)
   1.114 +	{
   1.115 +	return ((bitCount+WORD_BITS-1)/(WORD_BITS));
   1.116 +	}
   1.117 +
   1.118 +inline TUint WordsToBits(TUint wordCount)
   1.119 +	{
   1.120 +	return wordCount * WORD_BITS;
   1.121 +	}
   1.122 +
   1.123 +inline TUint BytesToBits(TUint byteCount)
   1.124 +	{	
   1.125 +	return byteCount * BYTE_BITS;
   1.126 +	}
   1.127 +
   1.128 +inline TUint WordsToBytes(TUint wordCount)
   1.129 +	{
   1.130 +	return wordCount * WORD_BYTES;
   1.131 +	}
   1.132 +
   1.133 +inline void XorWords(TUint32* r, const TUint32* a, TUint n)
   1.134 +	{
   1.135 +	assert(((TUint32)r & 3) == 0); // Catch alignment problems
   1.136 +	
   1.137 +	for (TUint i=0; i<n; i++)
   1.138 +		r[i] ^= a[i];
   1.139 +	}
   1.140 +
   1.141 +inline void XorBuf(TUint8* buf, const TUint8* mask, TUint count)
   1.142 +	{
   1.143 +	if (((TUint)buf | (TUint)mask | count) % WORD_SIZE == 0) 
   1.144 +		{
   1.145 +		XorWords((TUint32*)buf, (const TUint32*)mask, count/WORD_SIZE); 
   1.146 +		}
   1.147 +	else
   1.148 +		{
   1.149 +		for (TUint i=0; i<count; i++)
   1.150 +			buf[i] ^= mask[i];
   1.151 +		}
   1.152 +	}
   1.153 +
   1.154 +// ************** rotate functions ***************
   1.155 +template <class T> inline T rotlFixed(T x, TUint y)
   1.156 +	{
   1.157 +	assert(y < sizeof(T)*8);
   1.158 +	return ( (T)((x<<y) | (x>>(sizeof(T)*8-y))) );
   1.159 +	}
   1.160 +
   1.161 +template <class T> inline T rotrFixed(T x, TUint y)
   1.162 +	{
   1.163 +	assert(y < sizeof(T)*8);
   1.164 +	return ((T)((x>>y) | (x<<(sizeof(T)*8-y))));
   1.165 +	}
   1.166 +
   1.167 +inline TUint32 byteReverse(TUint32 value)
   1.168 +	{
   1.169 +	value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
   1.170 +	return rotlFixed(value, 16U);
   1.171 +	}
   1.172 +
   1.173 +template <class T>
   1.174 +void byteReverse(T* out, const T* in, TUint32 byteCount)
   1.175 +	{
   1.176 +	TUint count = (byteCount+sizeof(T)-1)/sizeof(T);
   1.177 +	for (TUint i=0; i<count; i++)
   1.178 +		out[i] = byteReverse(in[i]);
   1.179 +	}
   1.180 +
   1.181 +template <class T>
   1.182 +inline void GetUserKeyLittleEndian(T *out, TUint32 outlen, const TUint8* in, TUint32 inlen)
   1.183 +	{
   1.184 +	const TUint U = sizeof(T);
   1.185 +	assert(inlen <= outlen*U);
   1.186 +	Mem::Copy(out, in, inlen);
   1.187 +	Mem::FillZ((TUint8*)out+inlen, outlen*U-inlen);
   1.188 +	}
   1.189 +
   1.190 +template <class T>
   1.191 +inline void GetUserKeyBigEndian(T *out, TUint32 outlen, const TUint8* in, TUint32 inlen)
   1.192 +	{
   1.193 +	const TUint U = sizeof(T);
   1.194 +	assert(inlen <= outlen*U);
   1.195 +	Mem::Copy(out, in, inlen);
   1.196 +	Mem::FillZ((TUint8*)out+inlen, outlen*U-inlen);
   1.197 +	byteReverse(out, out, inlen);
   1.198 +	}
   1.199 +
   1.200 +// The following methods have be changed to use byte rather than word accesses,
   1.201 +// as if the input pointer is not be word aligned a fault occurs on arm
   1.202 +// hardware.  This isn't optimal from a performance point of view, but it is
   1.203 +// neccessary because the crypto interfaces (CSymmetricCipher,
   1.204 +// CBlockTransformation) allow clients to pass non-aligned data.
   1.205 +
   1.206 +// Fetch 4 words from user's buffer into "a", "b", "c", "d" in LITTLE-endian order
   1.207 +inline void GetBlockLittleEndian(const TUint8* block, TUint16 &a, TUint16 &b, TUint16 &c, TUint16 &d)
   1.208 +	{
   1.209 +	a = (TUint16)(block[0] | block[1] << 8);
   1.210 +	b = (TUint16)(block[2] | block[3] << 8);
   1.211 +	c = (TUint16)(block[4] | block[5] << 8);
   1.212 +	d = (TUint16)(block[6] | block[7] << 8);
   1.213 +	}
   1.214 +
   1.215 +// Put 4 words back into user's buffer in LITTLE-endian order
   1.216 +inline void PutBlockLittleEndian(TUint8* block, TUint16 a, TUint16 b, TUint16 c, TUint16 d)
   1.217 +	{
   1.218 +	block[0] = (TUint8)(a & 0xff);
   1.219 +	block[1] = (TUint8)(a >> 8);
   1.220 +	block[2] = (TUint8)(b & 0xff);
   1.221 +	block[3] = (TUint8)(b >> 8);
   1.222 +	block[4] = (TUint8)(c & 0xff);
   1.223 +	block[5] = (TUint8)(c >> 8);
   1.224 +	block[6] = (TUint8)(d & 0xff);
   1.225 +	block[7] = (TUint8)(d >> 8);
   1.226 +	}
   1.227 +
   1.228 +// Fetch 1 word from user's buffer in BIG-endian order
   1.229 +inline void GetWordBigEndian(const TUint8* block, TUint32 &a)
   1.230 +	{
   1.231 +	a = block[0] << 24 | block[1] << 16 | block[2] << 8 | block[3];
   1.232 +	}
   1.233 +
   1.234 +// Put 1 word back into user's buffer in BIG-endian order
   1.235 +inline void PutWordBigEndian(TUint8* block, TUint32 a)
   1.236 +	{
   1.237 +	block[0] = (TUint8)(a >> 24);
   1.238 +	block[1] = (TUint8)((a >> 16) & 0xff);
   1.239 +	block[2] = (TUint8)((a >> 8) & 0xff);
   1.240 +	block[3] = (TUint8)(a & 0xff);
   1.241 +	}
   1.242 +
   1.243 +// Fetch 2 words from user's buffer into "a", "b" in BIG-endian order
   1.244 +inline void GetBlockBigEndian(const TUint8* block, TUint32 &a, TUint32& b)
   1.245 +	{
   1.246 +	GetWordBigEndian(block, a);
   1.247 +	GetWordBigEndian(block + 4, b);
   1.248 +	}
   1.249 +
   1.250 +// Put 2 words back into user's buffer in BIG-endian order
   1.251 +inline void PutBlockBigEndian(TUint8* block, TUint32 a, TUint32 b)
   1.252 +	{
   1.253 +	PutWordBigEndian(block, a);
   1.254 +	PutWordBigEndian(block + 4, b);
   1.255 +	}
   1.256 +
   1.257 +// Fetch 4 words from user's buffer into "a", "b", "c", "d" in BIG-endian order
   1.258 +inline void GetBlockBigEndian(const TUint8* block, TUint32& a, TUint32& b, TUint32& c, TUint32& d)
   1.259 +	{
   1.260 +	GetWordBigEndian(block, a);
   1.261 +	GetWordBigEndian(block + 4, b);
   1.262 +	GetWordBigEndian(block + 8, c);
   1.263 +	GetWordBigEndian(block + 12, d);
   1.264 +	}
   1.265 +
   1.266 +// Put 4 words back into user's buffer in BIG-endian order
   1.267 +inline void PutBlockBigEndian(TUint8* block, TUint32 a, TUint32 b, TUint32 c, TUint32 d)
   1.268 +	{
   1.269 +	PutWordBigEndian(block, a);
   1.270 +	PutWordBigEndian(block + 4, b);
   1.271 +	PutWordBigEndian(block + 8, c);
   1.272 +	PutWordBigEndian(block + 12, d);
   1.273 +	}
   1.274 +
   1.275 +#endif // __INLINES_H__