00001
00013 #include "dkcSNOW20.h"
00014 #include "snow2tab.h"
00015
00016 #include <stdlib.h>
00017
00018
00019
00020
00021 #ifdef ORDER_DCBA //little endian win32
00022 #define snow2_key_shake(key,begin_offset) \
00023 (((uint32)*(key+begin_offset))<<24) | \
00024 (((uint32)*(key+1+begin_offset))<<16) | \
00025 (((uint32)*(key+2+begin_offset))<<8) | \
00026 (((uint32)*(key+3+begin_offset))) \
00027
00028 #else if defined(ORDER_ABCD) // big endian motorola
00029
00030 #define snow2_key_shake(key,begin_offset) \
00031 (((uint32)*(key+begin_offset))<<24) | \
00032 (((uint32)*(key+1+begin_offset))<<16) | \
00033 (((uint32)*(key+2+begin_offset))<<8) | \
00034 (((uint32)*(key+3+begin_offset))) \
00035 #else if defined(ORDER_BADC) // vix ?
00036
00037 #endif
00038
00039
00040
00041 static DKC_INLINE void update(DKC_SNOW2 *p){
00042 uint32 r1,r2,*snow_ptr;
00043 r1 = p->r1;
00044 r2 = p->r2;
00045 snow_ptr = p->snow_ptr;
00046
00047
00048 p->outfrom_fsm = (r1 + *(snow_ptr+15)) ^ r2;
00049 p->next_r1 = *(snow_ptr+5) + r2;
00050 p->next_r2 = snow_T0[dkcmGETBYTE(r1,0) & 0xff]
00051 ^ snow_T1[dkcmGETBYTE(r1,1) & 0xff]
00052 ^ snow_T2[dkcmGETBYTE(r1,2) & 0xff]
00053 ^ snow_T3[dkcmGETBYTE(r1,3) & 0xff];
00054 }
00055
00056
00057 #define ainv_mul(w) (((w)>>8)^(snow_alphainv_mul[w&0xff]))
00058 #define a_mul(w) (((w)<<8)^(snow_alpha_mul[w>>24]))
00059
00060 union snow_union{
00062 uint32 sw[dkcdSNOW2_BOX_SIZE * 2];
00063 struct{
00064 uint32 s0;
00065 uint32 s1;
00066 uint32 s2;
00067 uint32 s3;
00068 uint32 s4;
00069 uint32 s5;
00070 uint32 s6;
00071 uint32 s7;
00072 uint32 s8;
00073 uint32 s9;
00074 uint32 s10;
00075 uint32 s11;
00076 uint32 s12;
00077 uint32 s13;
00078 uint32 s14;
00079 uint32 s15;
00080 }w;
00081 };
00082
00083
00084 #define snow_byte(n,w) (dkcmGETBYTE(w,n) & 0xff)
00085
00086 DKC_INLINE int WINAPI dkcSNOW2EncryptBlock512NoDestDOE(DKC_SNOW2 *p,uint32 *keystream_block){
00087 uint32 *snow_ptr = p->snow_ptr;
00088 uint32 fsmtmp,*sw = p->sw;
00089 uint32 r1 = p->r1;
00090 uint32 r2 = p->r2;
00091 dkcmNOT_ASSERT(snow_ptr != p->sw);
00092 if(snow_ptr != p->sw){
00093 return edk_LogicError;
00094 }
00095 sw[0] =a_mul(sw[0] )^ sw[2] ^ainv_mul(sw[11] );
00096 fsmtmp=r2+ sw[5] ;
00097 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00098 r1=fsmtmp;
00099 keystream_block[0]=(r1+ sw[0] )^r2^ sw[1] ;
00100
00101 sw[1] =a_mul(sw[1] )^ sw[3] ^ainv_mul(sw[12]);
00102 fsmtmp=r2+ sw[6] ;
00103 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00104 r1=fsmtmp;
00105 keystream_block[1]=(r1+ sw[1] )^r2^ sw[2] ;
00106
00107 sw[2] =a_mul(sw[2] )^ sw[4] ^ainv_mul(sw[13] );
00108 fsmtmp=r2+ sw[7] ;
00109 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00110 r1=fsmtmp;
00111 keystream_block[2]=(r1+ sw[2] )^r2^ sw[3] ;
00112
00113 sw[3] =a_mul(sw[3] )^ sw[5] ^ainv_mul(sw[14] );
00114 fsmtmp=r2+ sw[8] ;
00115 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00116 r1=fsmtmp;
00117 keystream_block[3]=(r1+ sw[3] )^r2^ sw[4] ;
00118
00119 sw[4 ]=a_mul(sw[4] )^ sw[6] ^ainv_mul(sw[15] );
00120 fsmtmp=r2+ sw[9] ;
00121 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00122 r1=fsmtmp;
00123 keystream_block[4]=(r1+ sw[4] )^r2^ sw[5] ;
00124
00125 sw[5] =a_mul(sw[5] )^ sw[7] ^ainv_mul(sw[0] );
00126 fsmtmp=r2+ sw[10] ;
00127 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00128 r1=fsmtmp;
00129 keystream_block[5]=(r1+ sw[5] )^r2^ sw[6] ;
00130
00131 sw[6] =a_mul(sw[6] )^ sw[8] ^ainv_mul(sw[1] );
00132 fsmtmp=r2+ sw[11] ;
00133 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00134 r1=fsmtmp;
00135 keystream_block[6]=(r1+ sw[6] )^r2^ sw[7] ;
00136
00137 sw[7] =a_mul(sw[7] )^ sw[9] ^ainv_mul(sw[2] );
00138 fsmtmp=r2+ sw[12 ];
00139 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00140 r1=fsmtmp;
00141 keystream_block[7]=(r1+ sw[7] )^r2^ sw[8] ;
00142
00143 sw[8] =a_mul(sw[8] )^ sw[10] ^ainv_mul(sw[3] );
00144 fsmtmp=r2+ sw[13] ;
00145 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00146 r1=fsmtmp;
00147 keystream_block[8]=(r1+ sw[8] )^r2^ sw[9] ;
00148
00149 sw[9] =a_mul(sw[9] )^ sw[11] ^ainv_mul(sw[4] );
00150 fsmtmp=r2+ sw[14] ;
00151 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00152 r1=fsmtmp;
00153 keystream_block[9]=(r1+ sw[9] )^r2^ sw[10] ;
00154
00155 sw[10] =a_mul(sw[10] )^ sw[12] ^ainv_mul(sw[5] );
00156 fsmtmp=r2+ sw[15] ;
00157 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00158 r1=fsmtmp;
00159 keystream_block[10]=(r1+ sw[10] )^r2^ sw[11] ;
00160
00161 sw[11] =a_mul(sw[11] )^ sw[13] ^ainv_mul(sw[6] );
00162 fsmtmp=r2+ sw[0] ;
00163 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00164 r1=fsmtmp;
00165 keystream_block[11]=(r1+ sw[11] )^r2^ sw[12] ;
00166
00167 sw[12] =a_mul(sw[12] )^ sw[14] ^ainv_mul(sw[7] );
00168 fsmtmp=r2+ sw[1 ];
00169 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00170 r1=fsmtmp;
00171 keystream_block[12]=(r1+ sw[12] )^r2^ sw[13] ;
00172
00173 sw[13] =a_mul(sw[13] )^ sw[15] ^ainv_mul(sw[8] );
00174 fsmtmp=r2+ sw[2] ;
00175 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00176 r1=fsmtmp;
00177 keystream_block[13]=(r1+ sw[13] )^r2^ sw[14] ;
00178
00179 sw[14] =a_mul(sw[14] )^ sw[0] ^ainv_mul(sw[9] );
00180 fsmtmp=r2+ sw[3] ;
00181 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00182 r1=fsmtmp;
00183 keystream_block[14]=(r1+ sw[14] )^r2^ sw[15] ;
00184
00185 sw[15] =a_mul(sw[15] )^ sw[1] ^ainv_mul(sw[10] );
00186 fsmtmp=r2+ sw[4] ;
00187 r2=snow_T0[snow_byte(0,r1)]^snow_T1[snow_byte(1,r1)]^snow_T2[snow_byte(2,r1)]^snow_T3[snow_byte(3,r1)];
00188 r1=fsmtmp;
00189 keystream_block[15]=(r1+ sw[15] )^r2^ sw[0] ;
00190
00191 p->r1 = r1;
00192 p->r2 = r2;
00193 p->snow_ptr = snow_ptr;
00194
00195 return edk_SUCCEEDED;
00196 }
00197 static DKC_INLINE void snow_clock(DKC_SNOW2 *p) {
00198 register uint32 p1,p2,p3;
00199 uint32 *snow_ptr = p->snow_ptr;
00200
00201 p1=*(snow_ptr+11);
00202 p2=*(snow_ptr+2);
00203 p3=*(snow_ptr);
00204
00205 *(snow_ptr)
00206 = *(snow_ptr+dkcdSNOW2_BOX_SIZE)
00207 = ainv_mul(p1) ^ p2 ^ a_mul(p3);
00208 if(snow_ptr==p->sw+15){
00209 snow_ptr=p->sw;
00210 }else{
00211 snow_ptr++;
00212 }
00213
00214 p->r1=p->next_r1;
00215 p->r2=p->next_r2;
00216 p->snow_ptr = snow_ptr;
00217
00218 update(p);
00219
00220 }
00221
00222 static DKC_INLINE void feedback(DKC_SNOW2 *p) {
00223 register uint32 p1,p2,p3;
00224 uint32 *snow_ptr = p->snow_ptr;
00225
00226 p1=*(snow_ptr+11);
00227 p2=*(snow_ptr+2);
00228 p3=*(snow_ptr);
00229
00230 *snow_ptr
00231 = *(snow_ptr + dkcdSNOW2_BOX_SIZE)
00232 = ainv_mul(p1) ^ p2 ^ a_mul(p3) ^ p->outfrom_fsm;
00233 if(snow_ptr==p->sw+15){
00234 snow_ptr = p->sw;
00235 }else{
00236 snow_ptr++;
00237 }
00238
00239 p->r1=p->next_r1;
00240 p->r2=p->next_r2;
00241 p->snow_ptr = snow_ptr;
00242
00243 update(p);
00244 }
00245
00246 int WINAPI dkcSNOW2Init(DKC_SNOW2 *p,uint8 *key,size_t keysize,uint32 IV3,uint32 IV2,uint32 IV1,uint32 IV0)
00247 {
00248 int i;
00249
00250
00251
00252
00253 if(NULL==p || NULL==key){
00254 return edk_ArgumentException;
00255 }
00256 switch(keysize)
00257 {
00258 case 16:
00259 p->sw[15] = snow2_key_shake(key,0);
00260 p->sw[14] = snow2_key_shake(key,4);
00261 p->sw[13] = snow2_key_shake(key,8);
00262 p->sw[12] = snow2_key_shake(key,12);
00263 p->sw[11] = ~p->sw[15];
00264 p->sw[10] = ~p->sw[14];
00265 p->sw[9] = ~p->sw[13];
00266 p->sw[8] = ~p->sw[12];
00267 p->sw[7] = p->sw[15];
00268 p->sw[6] = p->sw[14];
00269 p->sw[5] = p->sw[13];
00270 p->sw[4] = p->sw[12];
00271 p->sw[3] =~p->sw[15];
00272 p->sw[2] =~p->sw[14];
00273 p->sw[1] =~p->sw[13];
00274 p->sw[0] =~p->sw[12];
00275 break;
00276 case 32:
00277 p->sw[15] = snow2_key_shake(key,0);
00278 p->sw[14] = snow2_key_shake(key,4);
00279 p->sw[13] = snow2_key_shake(key,8);
00280 p->sw[12] = snow2_key_shake(key,12);
00281 p->sw[11] = snow2_key_shake(key,16);
00282 p->sw[10] = snow2_key_shake(key,20);
00283 p->sw[9] = snow2_key_shake(key,24);
00284 p->sw[8] = snow2_key_shake(key,28);
00285 p->sw[7] =~p->sw[15];
00286 p->sw[6] =~p->sw[14];
00287 p->sw[5] =~p->sw[13];
00288 p->sw[4] =~p->sw[12];
00289 p->sw[3] =~p->sw[11];
00290 p->sw[2] =~p->sw[10];
00291 p->sw[1] =~p->sw[9];
00292 p->sw[0] =~p->sw[8];
00293 break;
00294 default:
00295 return edk_ArgumentException;
00296 }
00297
00298
00299
00300 p->sw[15]^=IV0;
00301 p->sw[12]^=IV1;
00302 p->sw[10]^=IV2;
00303 p->sw[9] ^=IV3;
00304
00305 p->snow_ptr = p->sw;
00306
00307 p->r1=0;
00308 p->r2=0;
00309
00310
00311 for(i=0;i<dkcdSNOW2_BOX_SIZE;i++)
00312 {
00313 p->sw[i+dkcdSNOW2_BOX_SIZE]=p->sw[dkcdSNOW2_BOX_SIZE];
00314 }
00315
00316 update(p);
00317
00318 for(i=0;i<dkcdSNOW2_BOX_SIZE * 2;i++){
00319 feedback(p);
00320 }
00321 return edk_SUCCEEDED;
00322 }
00323
00324
00325 DKC_SNOW2 *WINAPI dkcAllocSNOW2(BYTE *key,size_t keysize,
00326 uint32 IV3,uint32 IV2,uint32 IV1,uint32 IV0)
00327 {
00328 DKC_SNOW2 *p;
00329 int r;
00330 p = dkcAllocate(sizeof(DKC_SNOW2));
00331 if(NULL==p){
00332 return NULL;
00333 }
00334 r = dkcSNOW2Init(p,key,keysize,IV3,IV2,IV1,IV0);
00335 if(DKUTIL_FAILED(r)){
00336 goto Error;
00337 }
00338 return p;
00339 Error:
00340 dkcFreeSNOW2(&p);
00341 return NULL;
00342 }
00343
00344
00345
00346 int WINAPI dkcFreeSNOW2(DKC_SNOW2 **pp){
00347 int r;
00348 r = dkcFree(pp);
00349 return r;
00350 }
00351
00352 DKC_INLINE uint32 WINAPI dkcSNOW2_4Byte(DKC_SNOW2 *p){
00353 snow_clock(p);
00354 return (p->outfrom_fsm ^ *(p->snow_ptr));
00355
00356 }
00357
00358
00359 uint32 WINAPI dkcSNOW2Process(DKC_SNOW2 *p, uint32 u)
00360 {
00361 u ^= dkcSNOW2_4Byte(p);
00362 return u;
00363 }