source: svn/trunk/newcon3bcm2_21bu/dta/src/bootloader/sha1/sha1o.c @ 2

Last change on this file since 2 was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 5.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2002-2010, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * Filename: sha1.c
11 *
12 ***************************************************************************/
13#include "sha1o.h"
14
15#define OPTIMIZE_ROT 1
16/*
17   Following optimizations were performed :
18   F01 was replaced by shorter version from wikipedia
19   F03 was replaced by shorter version from wikipedia
20   ROTL was replaced by ROT1 ROT5 and ROT30 which at expense of some size
21   save 2 operations per ROTL call
22   All functions were brought in to one file which should enable better
23   optimization by compiler
24*/
25void SHA1Compute_ram( uint8 * image_ptr, int len, uint32 * digest );
26
27#if 0
28static inline uint32 F01( uint32 x, uint32 y, uint32 z )
29{
30        return (x & y) | ( (~x) & z );
31}
32#else
33static inline uint32 F01( uint32 x, uint32 y, uint32 z )
34{
35        return (((y ^ z) & x) ^ z);
36}
37#endif
38#if 0
39static inline uint32 F03( uint32 x, uint32 y, uint32 z )
40{
41        return (x & y) | (x & z) | (y & z);
42}
43#else
44static inline uint32 F03( uint32 x, uint32 y, uint32 z )
45{
46        return (((x | y) & z) | (x & y));
47}
48#endif
49static inline uint32 F24( uint32 x, uint32 y, uint32 z )
50{
51        return (x ^ y ^ z);
52}
53
54#if OPTIMIZE_ROT == 0
55static inline uint32 ROTL( uint32 x, uint32 n )
56{
57        return (x << n) | (x >> (32 - n));
58}
59#else
60static inline uint32 ROTL1( uint32 x )
61{
62        return (x << 1) | (x >> (31));
63}
64
65static inline uint32 ROTL5( uint32 x )
66{
67        return (x << 5) | (x >> (27));
68}
69
70static inline uint32 ROTL30( uint32 x )
71{
72        return (x << 30) | (x >> (2));
73}
74#endif
75
76static inline void WsubT (uint32 block [])
77{
78        uint32 tmp;
79        int i;
80#if OPTIMIZE_ROT == 0
81        tmp = ROTL ((block[0] ^ block [2] ^ block [8] ^ block [13]), 1);
82#else
83        tmp = ROTL1 ((block[0] ^ block [2] ^ block [8] ^ block [13]));
84#endif
85        for (i = 0; i < 15; i++)        {
86                block[i] = block[i+1];
87        }
88       
89        block[15] = tmp;
90}
91
92static inline void TBlock(uint32 * T, uint32 * block, int i)
93{
94                if( i < 16 ) {
95                        *T = block[i];
96                } else {
97                        WsubT(block);
98                        *T = block[15];
99                }
100}
101
102void SHA1Transform( uint32 digest[], uint32 block[] )
103{
104   int i;
105   uint32 a, b, c, d, e, T;
106
107   a = digest[0];
108   b = digest[1];
109   c = digest[2];
110   d = digest[3];
111   e = digest[4];
112
113   for( i = 0; i < 80; i++ ) {
114      TBlock(&T,block,i);
115#if OPTIMIZE_ROT == 0
116      T += ROTL( a, 5 ) + e;
117#else
118      T += ROTL5( a ) + e;
119#endif
120      if( i < 20 ) {
121         T += F01( b, c, d ) + 0x5A827999;
122      } else if( i < 40 ) {
123         T += F24( b, c, d ) + 0x6ED9EBA1;
124      } else if( i < 60 ) {
125         T += F03( b, c, d ) + 0x8F1BBCDC;
126      } else {
127         T += F24( b, c, d ) + 0xCA62C1D6;
128      }
129
130      e = d;
131      d = c;
132#if OPTIMIZE_ROT == 0
133      c = ROTL( b, 30 );
134#else
135      c = ROTL30( b );
136#endif
137      b = a;
138      a = T;
139   }
140
141   digest[0] += a;
142   digest[1] += b;
143   digest[2] += c;
144   digest[3] += d;
145   digest[4] += e;
146}
147
148/*
149   image_ptr must be aligned on 4 bytes boundary since it is accessed as
150   uint32 type.
151   len parameter is specifies message length in bits. To obtain this number
152   multiply message length in bytes by 8. This function works on data of
153   arbitrary length up to 2^31/8 bytes or up to 268435456 bytes.
154 */
155void SHA1Compute_ram( uint8 * image_ptr, int len, uint32 * digest )
156{
157   uint32 data [16]; //tmp;
158   unsigned long temp;
159   int fullLen = len;  /* save full length */
160   int i;
161   
162   digest[0] = 0x67452301;
163   digest[1] = 0xEFCDAB89;
164   digest[2] = 0x98BADCFE;
165   digest[3] = 0x10325476;
166   digest[4] = 0xC3D2E1F0;
167
168   /*
169    * Note: len is in number of bits, not bytes
170    */
171   while( (len / 512) >= 1 ) 
172   {
173      /* Determine if needed */
174      for (i = 0; i < 16; i++)
175      {
176         temp = *((unsigned long *) image_ptr);
177#ifdef SHA1_ENDIAN_SWAP
178         data[i] = (temp << 24) | (temp >> 24) | ((temp >> 8) & 0xff00) | ((temp & 0xff00) << 8);
179#else
180         data[i] = temp;
181#endif
182         image_ptr += 4;
183      }
184      /* end of section */
185     
186      SHA1Transform( digest, data );
187      len -= 512;
188   }
189
190   /* pick up whole words */
191   i = 0;
192   while( (len / 32) >= 1){
193           temp = *((unsigned long *) image_ptr);
194#ifdef SHA1_ENDIAN_SWAP
195           data[i] = (temp << 24) | (temp >> 24) | ((temp >> 8) & 0xff00) | ((temp & 0xff00) << 8);
196#else
197           data[i] = temp;
198#endif
199           i ++;
200           image_ptr += 4;
201           len -= 32;
202   }
203   /* pick up remaining bytes, read 4 bytes but discard unused */
204   if(len > 0){
205           temp = *((unsigned long *) image_ptr);
206#ifdef SHA1_ENDIAN_SWAP
207           temp = (temp << 24) | ((temp >> 8) & 0xff00) | ((temp & 0xff00) << 8);
208#endif
209           temp = (temp >> (32 - len)) << (32 - len);
210           data[i] = temp | (0x80 << (24 - len));
211   }else{
212           data[i] = 0x80000000;
213   }
214   /* fill remainder if possible but leave room for lenght */
215   for(i++; i < 14; i++){
216           data[i] = 0x00000000;
217   }
218   /* at this point i can be 14 or 15 or 16*/
219   if(i != 14){
220           if(i == 15)
221                   data[i] = 0x00000000;
222           SHA1Transform( digest, data );
223           for(i = 0; i < 14; i++){
224                   data[i] = 0x00000000;
225           }
226   }
227   /* 64 bit size */
228   data[i] = 0x00000000;
229   i++;
230   data[i] = fullLen;
231   SHA1Transform( digest, data );
232}
Note: See TracBrowser for help on using the repository browser.