os/security/cryptoplugins/cryptospiplugins/source/softwarecrypto/sha224and256impl.cpp
First public contribution.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * Common implementation of SHA224 and SHA256
16 * RFC 4634 (US Secure Hash Algorithms (SHA and HMAC-SHA))
26 #include <cryptospi/hashplugin.h>
27 #include "pluginconfig.h"
28 #include "sha224and256impl.h"
30 using namespace SoftwareCrypto;
35 * SHA-256 uses a sequence of sixty-four constant 32-bit words.
36 * These words represent the first thirty-two bits of the fractional
37 * parts of the cube roots of the first sixtyfour prime numbers.
39 * FIPS 180-2 Section 4.2.2
43 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
44 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
45 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
46 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
47 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
48 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
49 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
50 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
51 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
52 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
53 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
54 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
55 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
56 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
57 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
58 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
62 * Define the SHA SIGMA and sigma macros
64 * FIPS 180-2 section 4.1.2
67 inline TUint SHA256_SIGMA0(TUint aWord)
69 return (SHA_ROTR<TUint>( 2,aWord) ^ SHA_ROTR<TUint>(13,aWord) ^ SHA_ROTR<TUint>(22,aWord));
72 inline TUint SHA256_SIGMA1(TUint aWord)
74 return (SHA_ROTR<TUint>( 6,aWord) ^ SHA_ROTR<TUint>(11,aWord) ^ SHA_ROTR<TUint>(25,aWord));
77 inline TUint SHA256_sigma0(TUint aWord)
79 return (SHA_ROTR<TUint>( 7,aWord) ^ SHA_ROTR<TUint>(18,aWord) ^ SHA_SHR<TUint>( 3,aWord));
82 inline TUint SHA256_sigma1(TUint aWord)
84 return (SHA_ROTR<TUint>(17,aWord) ^ SHA_ROTR<TUint>(19,aWord) ^ SHA_SHR<TUint>(10,aWord));
89 inline TUint MakeWord(const TUint8* aData)
91 return (aData[0] << 24 | aData[1] << 16 | aData[2] << 8 | aData[3]);
95 CSHA224And256Impl* CSHA224And256Impl::NewL()
97 CSHA224And256Impl* self=new (ELeave) CSHA224And256Impl();
101 CSHA224And256Impl::CSHA224And256Impl() : iHash(KSHA256HashSize)
105 CSHA224And256Impl::CSHA224And256Impl(const CSHA224And256Impl& aSHA256Impl)
106 : iHash(aSHA256Impl.iHash),
115 iNl(aSHA256Impl.iNl),
118 Mem::Copy(iData, aSHA256Impl.iData, KSHA256BlockSize*sizeof(TUint));
121 void CSHA224And256Impl::Reset(const TAny* aValArray)
123 const TUint* values = static_cast<const TUint*>(aValArray);
127 * These words were obtained by taking the first thirty-two bits
128 * of the fractional parts of the square roots of the first eight
131 * FIPS 180-2 Section 5.3.2
145 // This assumes a big-endian architecture
146 void CSHA224And256Impl::Update(const TUint8* aData,TUint aLength)
148 while((aLength / 4) > 0 && (iNl % 4 == 0))
150 iData[iNl>>2] = MakeWord(aData);
154 if(iNl==KSHA256BlockSize)
157 AddLength(KSHA256BlockSize);
167 iData[iNl >> 2] |= *aData << ((3 - iNl&0x03) << 3) ;
170 if(iNl==KSHA256BlockSize)
173 AddLength(KSHA256BlockSize);
178 //This function will panic if the total input length is longer than 2^64 in bits
179 _LIT(KPanicString, "Message length exceeds supported length");
180 inline void CSHA224And256Impl::AddLength(const TUint aLength)
184 __ASSERT_ALWAYS((temp <= iNh), User::Panic(KPanicString, KErrOverflow));
188 static inline void CSHA256_16( const TUint aA,
201 aTemp1 = aH + SHA256_SIGMA1(aE) + SHA_Ch(aE,aF,aG) + aK + aWord;
202 aTemp2 = SHA256_SIGMA0(aA) + SHA_Maj(aA,aB,aC);
204 aH = aTemp1 + aTemp2;
207 static inline void CSHA256_48( const TUint aA,
224 aWord0 = SHA256_sigma1(aWord2) + aWord7 + SHA256_sigma0(aWord15) + aWord16;
225 CSHA256_16(aA, aB, aC, aD, aE, aF, aG, aH, aTemp1, aTemp2, aK, aWord0);
229 * This function actually calculates the hash.
230 * Function is defined in FIPS 180-2 section 6.2.2
232 * This function is the expanded version of the following loop.
233 * for(TUint i = 0; i < 64; ++i)
237 * iData[i] = SHA256_sigma1(iData[i-2]) + iData[i-7] + SHA256_sigma0(iData[i-15]) + iData[i-16];
240 * temp1 = tempH + SHA256_SIGMA1(tempE) + SHA_Ch(tempE,tempF,tempG) + K[i] + iData[i];
241 * temp2 = SHA256_SIGMA0(tempA) + SHA_Maj(tempA,tempB,tempC);
245 * tempE = tempD + temp1;
249 * tempA = temp1 + temp2;
252 void CSHA224And256Impl::Block()
265 CSHA256_16(tempA,tempB,tempC,tempD,tempE,tempF,tempG,tempH,temp1,temp2,K[0],iData[0]);
266 CSHA256_16(tempH,tempA,tempB,tempC,tempD,tempE,tempF,tempG,temp1,temp2,K[1],iData[1]);
267 CSHA256_16(tempG,tempH,tempA,tempB,tempC,tempD,tempE,tempF,temp1,temp2,K[2],iData[2]);
268 CSHA256_16(tempF,tempG,tempH,tempA,tempB,tempC,tempD,tempE,temp1,temp2,K[3],iData[3]);
269 CSHA256_16(tempE,tempF,tempG,tempH,tempA,tempB,tempC,tempD,temp1,temp2,K[4],iData[4]);
270 CSHA256_16(tempD,tempE,tempF,tempG,tempH,tempA,tempB,tempC,temp1,temp2,K[5],iData[5]);
271 CSHA256_16(tempC,tempD,tempE,tempF,tempG,tempH,tempA,tempB,temp1,temp2,K[6],iData[6]);
272 CSHA256_16(tempB,tempC,tempD,tempE,tempF,tempG,tempH,tempA,temp1,temp2,K[7],iData[7]);
274 CSHA256_16(tempA,tempB,tempC,tempD,tempE,tempF,tempG,tempH,temp1,temp2,K[8],iData[8]);
275 CSHA256_16(tempH,tempA,tempB,tempC,tempD,tempE,tempF,tempG,temp1,temp2,K[9],iData[9]);
276 CSHA256_16(tempG,tempH,tempA,tempB,tempC,tempD,tempE,tempF,temp1,temp2,K[10],iData[10]);
277 CSHA256_16(tempF,tempG,tempH,tempA,tempB,tempC,tempD,tempE,temp1,temp2,K[11],iData[11]);
278 CSHA256_16(tempE,tempF,tempG,tempH,tempA,tempB,tempC,tempD,temp1,temp2,K[12],iData[12]);
279 CSHA256_16(tempD,tempE,tempF,tempG,tempH,tempA,tempB,tempC,temp1,temp2,K[13],iData[13]);
280 CSHA256_16(tempC,tempD,tempE,tempF,tempG,tempH,tempA,tempB,temp1,temp2,K[14],iData[14]);
281 CSHA256_16(tempB,tempC,tempD,tempE,tempF,tempG,tempH,tempA,temp1,temp2,K[15],iData[15]);
283 CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
284 K[16], iData[16], iData[14], iData[9], iData[1], iData[0]);
285 CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
286 K[17], iData[17], iData[15], iData[10], iData[2], iData[1]);
287 CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
288 K[18], iData[18], iData[16], iData[11], iData[3], iData[2]);
289 CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
290 K[19], iData[19], iData[17], iData[12], iData[4], iData[3]);
291 CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
292 K[20], iData[20], iData[18], iData[13], iData[5], iData[4]);
293 CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
294 K[21], iData[21], iData[19], iData[14], iData[6], iData[5]);
295 CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
296 K[22], iData[22], iData[20], iData[15], iData[7], iData[6]);
297 CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
298 K[23], iData[23], iData[21], iData[16], iData[8], iData[7]);
300 CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
301 K[24], iData[24], iData[22], iData[17], iData[9], iData[8]);
302 CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
303 K[25], iData[25], iData[23], iData[18], iData[10], iData[9]);
304 CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
305 K[26], iData[26], iData[24], iData[19], iData[11], iData[10]);
306 CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
307 K[27], iData[27], iData[25], iData[20], iData[12], iData[11]);
308 CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
309 K[28], iData[28], iData[26], iData[21], iData[13], iData[12]);
310 CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
311 K[29], iData[29], iData[27], iData[22], iData[14], iData[13]);
312 CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
313 K[30], iData[30], iData[28], iData[23], iData[15], iData[14]);
314 CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
315 K[31], iData[31], iData[29], iData[24], iData[16], iData[15]);
317 CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
318 K[32], iData[32], iData[30], iData[25], iData[17], iData[16]);
319 CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
320 K[33], iData[33], iData[31], iData[26], iData[18], iData[17]);
321 CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
322 K[34], iData[34], iData[32], iData[27], iData[19], iData[18]);
323 CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
324 K[35], iData[35], iData[33], iData[28], iData[20], iData[19]);
325 CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
326 K[36], iData[36], iData[34], iData[29], iData[21], iData[20]);
327 CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
328 K[37], iData[37], iData[35], iData[30], iData[22], iData[21]);
329 CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
330 K[38], iData[38], iData[36], iData[31], iData[23], iData[22]);
331 CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
332 K[39], iData[39], iData[37], iData[32], iData[24], iData[23]);
334 CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
335 K[40], iData[40], iData[38], iData[33], iData[25], iData[24]);
336 CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
337 K[41], iData[41], iData[39], iData[34], iData[26], iData[25]);
338 CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
339 K[42], iData[42], iData[40], iData[35], iData[27], iData[26]);
340 CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
341 K[43], iData[43], iData[41], iData[36], iData[28], iData[27]);
342 CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
343 K[44], iData[44], iData[42], iData[37], iData[29], iData[28]);
344 CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
345 K[45], iData[45], iData[43], iData[38], iData[30], iData[29]);
346 CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
347 K[46], iData[46], iData[44], iData[39], iData[31], iData[30]);
348 CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
349 K[47], iData[47], iData[45], iData[40], iData[32], iData[31]);
351 CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
352 K[48], iData[48], iData[46], iData[41], iData[33], iData[32]);
353 CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
354 K[49], iData[49], iData[47], iData[42], iData[34], iData[33]);
355 CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
356 K[50], iData[50], iData[48], iData[43], iData[35], iData[34]);
357 CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
358 K[51], iData[51], iData[49], iData[44], iData[36], iData[35]);
359 CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
360 K[52], iData[52], iData[50], iData[45], iData[37], iData[36]);
361 CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
362 K[53], iData[53], iData[51], iData[46], iData[38], iData[37]);
363 CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
364 K[54], iData[54], iData[52], iData[47], iData[39], iData[38]);
365 CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
366 K[55], iData[55], iData[53], iData[48], iData[40], iData[39]);
368 CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
369 K[56], iData[56], iData[54], iData[49], iData[41], iData[40]);
370 CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
371 K[57], iData[57], iData[55], iData[50], iData[42], iData[41]);
372 CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
373 K[58], iData[58], iData[56], iData[51], iData[43], iData[42]);
374 CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
375 K[59], iData[59], iData[57], iData[52], iData[44], iData[43]);
376 CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
377 K[60], iData[60], iData[58], iData[53], iData[45], iData[44]);
378 CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
379 K[61], iData[61], iData[59], iData[54], iData[46], iData[45]);
380 CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
381 K[62], iData[62], iData[60], iData[55], iData[47], iData[46]);
382 CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
383 K[63], iData[63], iData[61], iData[56], iData[48], iData[47]);
398 * According to the standard, the message must be padded to an
399 * even 512 bits. The first padding bit must be a '1'. The last
400 * 64 bits represent the length of the original message. All bits
401 * in between should be 0. This helper function will pad the
402 * message according to those rules by filling the iData array
405 void CSHA224And256Impl::PadMessage()
407 const TUint padByte = 0x80;
413 iData[iNl >> 2] |= padByte << ((3 - iNl&0x03) << 3) ;
415 if (iNl >= (KSHA256BlockSize - 2*sizeof(TUint)))
417 if (iNl < (KSHA256BlockSize - sizeof(TUint)))
418 iData[(KSHA256BlockSize >> 2) - 1]=0;
420 Mem::FillZ(iData, KSHA256BlockSize);
424 const TUint offset=(iNl+4)>>2; //+4 to account for the word added in the
425 //switch statement above
426 Mem::FillZ(iData+offset,(KSHA256BlockSize - offset*sizeof(TUint)));
430 TUint64 msgLength = iNh;
432 iData[(KSHA256BlockSize >> 2) - 2] = (msgLength) >> 32;
433 iData[(KSHA256BlockSize >> 2) - 1] = (msgLength & 0xFFFFFFFF);
436 inline void CSHA224And256Impl::CopyWordToHash(TUint aVal, TUint aIndex)
438 TUint value = MakeWord(reinterpret_cast<TUint8*>(&aVal));
439 Mem::Copy(const_cast<TUint8*>(iHash.Ptr())+ (4*aIndex), &value, sizeof(aVal));
442 const TDes8& CSHA224And256Impl::Final()
448 // Generate hash value into iHash
450 CopyWordToHash(iA, 0);
451 CopyWordToHash(iB, 1);
452 CopyWordToHash(iC, 2);
453 CopyWordToHash(iD, 3);
454 CopyWordToHash(iE, 4);
455 CopyWordToHash(iF, 5);
456 CopyWordToHash(iG, 6);
457 CopyWordToHash(iH, 7);
462 void CSHA224And256Impl::RestoreState()
474 Mem::Copy(iData, iDataCopy, KSHA256BlockSize*sizeof(TUint));
477 void CSHA224And256Impl::StoreState()
489 Mem::Copy(iDataCopy, iData, KSHA256BlockSize*sizeof(TUint));
492 // Implemented in hmacimpl.cpp or softwarehashbase.cpp
493 // but required as derived from MHash. No coverage here.
494 #ifdef _BullseyeCoverage
495 #pragma suppress_warnings on
496 #pragma BullseyeCoverage off
497 #pragma suppress_warnings off