os/security/crypto/weakcrypto/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/weakcrypto/source/common/inlines.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,244 @@
     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 +inline TUint BitsToBytes(TUint bitCount)
    1.76 +	{
    1.77 +	return ((bitCount+7)/(BYTE_BITS));
    1.78 +	}
    1.79 +
    1.80 +inline TUint BytesToWords(TUint byteCount)
    1.81 +	{
    1.82 +	return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
    1.83 +	}
    1.84 +
    1.85 +inline TUint BitsToWords(TUint bitCount)
    1.86 +	{
    1.87 +	return ((bitCount+WORD_BITS-1)/(WORD_BITS));
    1.88 +	}
    1.89 +
    1.90 +inline TUint WordsToBits(TUint wordCount)
    1.91 +	{
    1.92 +	return wordCount * WORD_BITS;
    1.93 +	}
    1.94 +
    1.95 +inline TUint BytesToBits(TUint byteCount)
    1.96 +	{
    1.97 +	return byteCount * BYTE_BITS;
    1.98 +	}
    1.99 +
   1.100 +inline TUint WordsToBytes(TUint wordCount)
   1.101 +	{
   1.102 +	return wordCount * WORD_BYTES;
   1.103 +	}
   1.104 +
   1.105 +inline void XorWords(TUint* r, const TUint* a, TUint n)
   1.106 +	{
   1.107 +	assert(((TUint32)r & 3) == 0); // Catch alignment problems
   1.108 +	
   1.109 +	for (TUint i=0; i<n; i++)
   1.110 +		r[i] ^= a[i];
   1.111 +	}
   1.112 +
   1.113 +inline void XorBuf(TUint8* buf, const TUint8* mask, TUint count)
   1.114 +	{
   1.115 +	if (((TUint)buf | (TUint)mask | count) % WORD_SIZE == 0) 
   1.116 +		{
   1.117 +		XorWords((TUint*)buf, (const TUint*)mask, count/WORD_SIZE); 
   1.118 +		}
   1.119 +	else
   1.120 +		{
   1.121 +		for (TUint i=0; i<count; i++)
   1.122 +			buf[i] ^= mask[i];
   1.123 +		}
   1.124 +	}
   1.125 +
   1.126 +// ************** rotate functions ***************
   1.127 +template <class T> inline T rotlFixed(T x, TUint y)
   1.128 +	{
   1.129 +	assert(y < sizeof(T)*8);
   1.130 +	return ( (T)((x<<y) | (x>>(sizeof(T)*8-y))) );
   1.131 +	}
   1.132 +
   1.133 +template <class T> inline T rotrFixed(T x, TUint y)
   1.134 +	{
   1.135 +	assert(y < sizeof(T)*8);
   1.136 +	return ((T)((x>>y) | (x<<(sizeof(T)*8-y))));
   1.137 +	}
   1.138 +
   1.139 +inline TUint32 byteReverse(TUint32 value)
   1.140 +	{
   1.141 +	value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
   1.142 +	return rotlFixed(value, 16U);
   1.143 +	}
   1.144 +
   1.145 +template <class T>
   1.146 +void byteReverse(T* out, const T* in, TUint32 byteCount)
   1.147 +	{
   1.148 +	TUint count = (byteCount+sizeof(T)-1)/sizeof(T);
   1.149 +	for (TUint i=0; i<count; i++)
   1.150 +		out[i] = byteReverse(in[i]);
   1.151 +	}
   1.152 +
   1.153 +template <class T>
   1.154 +inline void GetUserKeyLittleEndian(T *out, TUint32 outlen, const TUint8* in, TUint32 inlen)
   1.155 +	{
   1.156 +	const TUint U = sizeof(T);
   1.157 +	assert(inlen <= outlen*U);
   1.158 +	Mem::Copy(out, in, inlen);
   1.159 +	Mem::FillZ((TUint8*)out+inlen, outlen*U-inlen);
   1.160 +	}
   1.161 +
   1.162 +template <class T>
   1.163 +inline void GetUserKeyBigEndian(T *out, TUint32 outlen, const TUint8* in, TUint32 inlen)
   1.164 +	{
   1.165 +	const TUint U = sizeof(T);
   1.166 +	assert(inlen <= outlen*U);
   1.167 +	Mem::Copy(out, in, inlen);
   1.168 +	Mem::FillZ((TUint8*)out+inlen, outlen*U-inlen);
   1.169 +	byteReverse(out, out, inlen);
   1.170 +	}
   1.171 +
   1.172 +// The following methods have be changed to use byte rather than word accesses,
   1.173 +// as if the input pointer is not be word aligned a fault occurs on arm
   1.174 +// hardware.  This isn't optimal from a performance point of view, but it is
   1.175 +// neccessary because the crypto interfaces (CSymmetricCipher,
   1.176 +// CBlockTransformation) allow clients to pass non-aligned data.
   1.177 +
   1.178 +// Fetch 4 words from user's buffer into "a", "b", "c", "d" in LITTLE-endian order
   1.179 +inline void GetBlockLittleEndian(const TUint8* block, TUint16 &a, TUint16 &b, TUint16 &c, TUint16 &d)
   1.180 +	{
   1.181 +	a = (TUint16)(block[0] | block[1] << 8);
   1.182 +	b = (TUint16)(block[2] | block[3] << 8);
   1.183 +	c = (TUint16)(block[4] | block[5] << 8);
   1.184 +	d = (TUint16)(block[6] | block[7] << 8);
   1.185 +	}
   1.186 +
   1.187 +// Put 4 words back into user's buffer in LITTLE-endian order
   1.188 +inline void PutBlockLittleEndian(TUint8* block, TUint16 a, TUint16 b, TUint16 c, TUint16 d)
   1.189 +	{
   1.190 +	block[0] = (TUint8)(a & 0xff);
   1.191 +	block[1] = (TUint8)(a >> 8);
   1.192 +	block[2] = (TUint8)(b & 0xff);
   1.193 +	block[3] = (TUint8)(b >> 8);
   1.194 +	block[4] = (TUint8)(c & 0xff);
   1.195 +	block[5] = (TUint8)(c >> 8);
   1.196 +	block[6] = (TUint8)(d & 0xff);
   1.197 +	block[7] = (TUint8)(d >> 8);
   1.198 +	}
   1.199 +
   1.200 +// Fetch 1 word from user's buffer in BIG-endian order
   1.201 +inline void GetWordBigEndian(const TUint8* block, TUint32 &a)
   1.202 +	{
   1.203 +	a = block[0] << 24 | block[1] << 16 | block[2] << 8 | block[3];
   1.204 +	}
   1.205 +
   1.206 +// Put 1 word back into user's buffer in BIG-endian order
   1.207 +inline void PutWordBigEndian(TUint8* block, TUint32 a)
   1.208 +	{
   1.209 +	block[0] = (TUint8)(a >> 24);
   1.210 +	block[1] = (TUint8)((a >> 16) & 0xff);
   1.211 +	block[2] = (TUint8)((a >> 8) & 0xff);
   1.212 +	block[3] = (TUint8)(a & 0xff);
   1.213 +	}
   1.214 +
   1.215 +// Fetch 2 words from user's buffer into "a", "b" in BIG-endian order
   1.216 +inline void GetBlockBigEndian(const TUint8* block, TUint32 &a, TUint32& b)
   1.217 +	{
   1.218 +	GetWordBigEndian(block, a);
   1.219 +	GetWordBigEndian(block + 4, b);
   1.220 +	}
   1.221 +
   1.222 +// Put 2 words back into user's buffer in BIG-endian order
   1.223 +inline void PutBlockBigEndian(TUint8* block, TUint32 a, TUint32 b)
   1.224 +	{
   1.225 +	PutWordBigEndian(block, a);
   1.226 +	PutWordBigEndian(block + 4, b);
   1.227 +	}
   1.228 +
   1.229 +// Fetch 4 words from user's buffer into "a", "b", "c", "d" in BIG-endian order
   1.230 +inline void GetBlockBigEndian(const TUint8* block, TUint32& a, TUint32& b, TUint32& c, TUint32& d)
   1.231 +	{
   1.232 +	GetWordBigEndian(block, a);
   1.233 +	GetWordBigEndian(block + 4, b);
   1.234 +	GetWordBigEndian(block + 8, c);
   1.235 +	GetWordBigEndian(block + 12, d);
   1.236 +	}
   1.237 +
   1.238 +// Put 4 words back into user's buffer in BIG-endian order
   1.239 +inline void PutBlockBigEndian(TUint8* block, TUint32 a, TUint32 b, TUint32 c, TUint32 d)
   1.240 +	{
   1.241 +	PutWordBigEndian(block, a);
   1.242 +	PutWordBigEndian(block + 4, b);
   1.243 +	PutWordBigEndian(block + 8, c);
   1.244 +	PutWordBigEndian(block + 12, d);
   1.245 +	}
   1.246 +
   1.247 +#endif // __INLINES_H__