00001
00023 #include "dkcHC256.h"
00024
00025 #include <stdlib.h>
00026
00027
00028
00029
00030
00031
00032 #ifndef _MSC_VER
00033 #define rotr(x,n) (((x)>>(n))|((x)<<(32-(n))))
00034 #else
00035 #define rotr(x,n) _lrotr(x,n)
00036 #endif
00037
00038
00039 static DKC_INLINE uint32 h1(uint32 *Q,uint32 x){
00040 DKC_4BYTE_UNION_LITTLE_ENDIAN_BASE a;
00041 a.dword = x;
00042 return Q[a.w.byte0] +
00043 Q[256+a.w.byte1] +
00044 Q[512+a.w.byte2] +
00045 Q[768+a.w.byte3];
00046 }
00047
00048 static DKC_INLINE uint32 h2(uint32 *P,uint32 x){
00049 DKC_4BYTE_UNION_LITTLE_ENDIAN_BASE a;
00050 a.dword = x;
00051 return P[a.w.byte0] +
00052 P[256+a.w.byte1] +
00053 P[512+a.w.byte2] +
00054 P[768+a.w.byte3];
00055 }
00056
00057 static DKC_INLINE uint32 g1(uint32 *Q,uint32 x,uint32 y){
00058 uint32 a,b,c;
00059 a = rotr((x),10);
00060 b = rotr((y),23);
00061 c = ((x)^(y))&0x3ff;
00062 return (a^b) + Q[c];
00063 }
00064 static DKC_INLINE uint32 g2(uint32 *P,uint32 x,uint32 y){
00065 uint32 a,b,c;
00066 a = rotr((x),10);
00067 b = rotr((y),23);
00068 c = ((x)^(y))&0x3ff;
00069 return (a^b) + P[c];
00070 }
00071
00072 #define feedback_1(u,v,b,c) { \
00073 uint32 tem0,tem1,tem2; \
00074 tem0 = rotr((v),23); \
00075 tem1 = rotr((c),10); \
00076 tem2 = ((v) ^ (c)) & 0x3ff; \
00077 (u) += (b)+(tem0^tem1)+Q[tem2]; \
00078 }
00079
00080 #define feedback_2(u,v,b,c) { \
00081 uint32 tem0,tem1,tem2; \
00082 tem0 = rotr((v),23); \
00083 tem1 = rotr((c),10); \
00084 tem2 = ((v) ^ (c)) & 0x3ff; \
00085 (u) += (b)+(tem0^tem1)+P[tem2]; \
00086 }
00087 static DKC_INLINE uint32 fb1(uint32 *Q,uint32 u,uint32 v,uint32 b,uint32 c){
00088 uint32 tem0,tem1,tem2;
00089 tem0 = rotr((v),23);
00090 tem1 = rotr((c),10);
00091 tem2 = ((v) ^ (c)) & 0x3ff;
00092 (u) += (b)+(tem0^tem1)+Q[tem2];
00093 return u;
00094 }
00095 static DKC_INLINE uint32 fb2(uint32 *P,uint32 u,uint32 v,uint32 b,uint32 c){
00096 uint32 tem0,tem1,tem2;
00097 tem0 = rotr((v),23);
00098 tem1 = rotr((c),10);
00099 tem2 = ((v) ^ (c)) & 0x3ff;
00100 (u) += (b)+(tem0^tem1)+P[tem2];
00101 return u;
00102 }
00103 static DKC_INLINE void fb1_(uint32 *Q,uint32 *u,uint32 v,uint32 b,uint32 c){
00104 uint32 tem0,tem1,tem2;
00105 tem0 = rotr((v),23);
00106 tem1 = rotr((c),10);
00107 tem2 = ((v) ^ (c)) & 0x3ff;
00108 (*u) += (b)+(tem0^tem1)+Q[tem2];
00109 }
00110 static DKC_INLINE void fb2_(uint32 *P,uint32 *u,uint32 v,uint32 b,uint32 c){
00111 uint32 tem0,tem1,tem2;
00112 tem0 = rotr((v),23);
00113 tem1 = rotr((c),10);
00114 tem2 = ((v) ^ (c)) & 0x3ff;
00115 (*u) += (b)+(tem0^tem1)+P[tem2];
00116 }
00117 #define f1(x) (rotr((x),7) ^ rotr((x),18) ^ ((x) >> 3))
00118 #define f2(x) (rotr((x),17) ^ rotr((x),19) ^ ((x) >> 10))
00119 #define f(a,b,c,d) (f2((a)) + b + f1((c)) + d)
00120
00121 void initialization(DKC_HC256 *p,uint32 key[], uint32 iv[])
00122 {
00123 uint32 i,j;
00124 uint32 *P = p->P;
00125 uint32 *Q = p->Q;
00126
00127
00128 for (i = 0; i < 8; i++) P[i] = key[i];
00129 for (i = 8; i < 16; i++) P[i] = iv[i-8];
00130
00131 for (i = 16; i < 528; i++)
00132 P[i] = f(P[i-2],P[i-7],P[i-15],P[i-16])+i;
00133 for (i = 0; i < 16; i++)
00134 P[i] = P[i+512];
00135 for (i = 16; i < 1024; i++)
00136 P[i] = f(P[i-2],P[i-7],P[i-15],P[i-16])+512+i;
00137
00138 for (i = 0; i < 16; i++)
00139 Q[i] = P[1024-16+i];
00140 for (i = 16; i < 32; i++)
00141 Q[i] = f(Q[i-2],Q[i-7],Q[i-15],Q[i-16])+1520+i;
00142 for (i = 0; i < 16; i++)
00143 Q[i] = Q[i+16];
00144 for (i = 16; i < 1024;i++)
00145 Q[i] = f(Q[i-2],Q[i-7],Q[i-15],Q[i-16])+1536+i;
00146
00147
00148 for (i = 0; i < 2; i++) {
00149 #if 1
00150 for (j = 0; j < 10; j++)
00151 fb1_(Q,&P[j],P[j+1],P[(j-10)&0x3ff],P[(j-3)&0x3ff]);
00152 for (j = 10; j < 1023; j++)
00153 fb1_(Q,&P[j],P[j+1],P[j-10],P[j-3]);
00154 fb1_(Q,&P[1023],P[0],P[1013],P[1020]);
00155 for (j = 0; j < 10; j++)
00156 fb2_(P,&Q[j],Q[j+1],Q[(j-10)&0x3ff],Q[(j-3)&0x3ff]);
00157 for (j = 10; j < 1023; j++)
00158 fb2_(P,&Q[j],Q[j+1],Q[j-10],Q[j-3]);
00159 fb2_(P,&Q[1023],Q[0],Q[1013],Q[1020]);
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 #else
00173 for (j = 0; j < 10; j++)
00174 feedback_1(P[j],P[j+1],P[(j-10)&0x3ff],P[(j-3)&0x3ff]);
00175 for (j = 10; j < 1023; j++)
00176 feedback_1(P[j],P[j+1],P[j-10],P[j-3]);
00177 feedback_1(P[1023],P[0],P[1013],P[1020]);
00178 for (j = 0; j < 10; j++)
00179 feedback_2(Q[j],Q[j+1],Q[(j-10)&0x3ff],Q[(j-3)&0x3ff]);
00180 for (j = 10; j < 1023; j++)
00181 feedback_2(Q[j],Q[j+1],Q[j-10],Q[j-3]);
00182 feedback_2(Q[1023],Q[0],Q[1013],Q[1020]);
00183 #endif
00184 }
00185
00186
00187 p->counter2048 = 0;
00188 for (i = 0; i < 16; i++) p->X[i] = P[1008+i];
00189 for (i = 0; i < 16; i++) p->Y[i] = Q[1008+i];
00190 }
00191
00192
00193
00194 DKC_INLINE uint32 dkcHC256Process(DKC_HC256 *p,uint32 u)
00195 {
00196 unsigned long i,i3, i10, i12, i1023;
00197 unsigned long output;
00198
00199 i = p->counter2048 & 0x3ff;
00200 i3 = (i - 3) & 0x3ff;
00201 i10 = (i - 10) & 0x3ff;
00202 i12 = (i - 12) & 0x3ff;
00203 i1023 = (i - 1023) & 0x3ff;
00204
00205 if (p->counter2048 < 1024) {
00206 p->P[i] = p->P[i] + p->P[i10] + g1(p->Q,p->P[i3],p->P[i1023]);
00207 output = h1(p->Q,p->P[i12]) ^ p->P[i];
00208 }
00209 else {
00210 p->Q[i] = p->Q[i] + p->Q[i10] + g2(p->P,p->Q[i3],p->Q[i1023]);
00211 output = h2(p->P,p->Q[i12]) ^ p->Q[i];
00212
00213 }
00214 p->counter2048 = (p->counter2048+1) & 0x7ff;
00215 return (output);
00216 }
00217
00218
00219 static DKC_INLINE void step_A(DKC_HC256 *p,uint32 u,uint32 v,
00220 uint32 a,uint32 b,uint32 c,uint32 d,uint32 *m)
00221 {
00222 uint32 tem0,tem1,tem2,tem3;
00223 tem0 = rotr((v),23);
00224 tem1 = rotr((c),10);
00225 tem2 = ((v) ^ (c)) & 0x3ff;
00226 (u) += (b)+(tem0^tem1) + p->Q[tem2];
00227 (a) = (u);
00228 tem3 = h1(p->P,d);
00229
00230
00231 *m = tem3 ^ (u) ;
00232 }
00233 static DKC_INLINE void step_B(DKC_HC256 *p,uint32 u,uint32 v,
00234 uint32 a,uint32 b,uint32 c,uint32 d,uint32 *m){
00235 uint32 tem0,tem1,tem2,tem3;
00236 tem0 = rotr((v),23);
00237 tem1 = rotr((c),10);
00238 tem2 = ((v) ^ (c)) & 0x3ff;
00239 (u) += (b)+(tem0^tem1)+p->P[tem2];
00240 (a) = (u);
00241 tem3 = h2(p->P,d);
00242
00243
00244 *m = tem3 ^ (u) ;
00245 }
00246
00247
00248 static DKC_INLINE void get_encrypt_array(DKC_HC256 *p,uint32 data[])
00249 {
00250 uint32 cc,dd,counter2048 = p->counter2048;
00251 uint32 *P = p->P,*Q = p->Q,*X =p->X, *Y = p->Y;
00252
00253 cc = counter2048 & 0x3ff;
00254 dd = (cc+16) & 0x3ff;
00255
00256 if (counter2048 < 1024)
00257 {
00258 counter2048 = (counter2048 + 16) & 0x7ff;
00259 step_A(p,P[cc+0], P[cc+1], X[0], X[6], X[13],X[4], &data[0]);
00260 step_A(p,P[cc+1], P[cc+2], X[1], X[7], X[14],X[5], &data[1]);
00261 step_A(p,P[cc+2], P[cc+3], X[2], X[8], X[15],X[6], &data[2]);
00262 step_A(p,P[cc+3], P[cc+4], X[3], X[9], X[0], X[7], &data[3]);
00263 step_A(p,P[cc+4], P[cc+5], X[4], X[10],X[1], X[8], &data[4]);
00264 step_A(p,P[cc+5], P[cc+6], X[5], X[11],X[2], X[9], &data[5]);
00265 step_A(p,P[cc+6], P[cc+7], X[6], X[12],X[3], X[10],&data[6]);
00266 step_A(p,P[cc+7], P[cc+8], X[7], X[13],X[4], X[11],&data[7]);
00267 step_A(p,P[cc+8], P[cc+9], X[8], X[14],X[5], X[12],&data[8]);
00268 step_A(p,P[cc+9], P[cc+10],X[9], X[15],X[6], X[13],&data[9]);
00269 step_A(p,P[cc+10],P[cc+11],X[10],X[0], X[7], X[14],&data[10]);
00270 step_A(p,P[cc+11],P[cc+12],X[11],X[1], X[8], X[15],&data[11]);
00271 step_A(p,P[cc+12],P[cc+13],X[12],X[2], X[9], X[0], &data[12]);
00272 step_A(p,P[cc+13],P[cc+14],X[13],X[3], X[10],X[1], &data[13]);
00273 step_A(p,P[cc+14],P[cc+15],X[14],X[4], X[11],X[2], &data[14]);
00274 step_A(p,P[cc+15],P[dd+0], X[15],X[5], X[12],X[3], &data[15]);
00275 }
00276 else
00277 {
00278 counter2048 = (counter2048 + 16) & 0x7ff;
00279 step_B(p,Q[cc+0], Q[cc+1], Y[0], Y[6], Y[13],Y[4], &data[0]);
00280 step_B(p,Q[cc+1], Q[cc+2], Y[1], Y[7], Y[14],Y[5], &data[1]);
00281 step_B(p,Q[cc+2], Q[cc+3], Y[2], Y[8], Y[15],Y[6], &data[2]);
00282 step_B(p,Q[cc+3], Q[cc+4], Y[3], Y[9], Y[0], Y[7], &data[3]);
00283 step_B(p,Q[cc+4], Q[cc+5], Y[4], Y[10],Y[1], Y[8], &data[4]);
00284 step_B(p,Q[cc+5], Q[cc+6], Y[5], Y[11],Y[2], Y[9], &data[5]);
00285 step_B(p,Q[cc+6], Q[cc+7], Y[6], Y[12],Y[3], Y[10],&data[6]);
00286 step_B(p,Q[cc+7], Q[cc+8], Y[7], Y[13],Y[4], Y[11],&data[7]);
00287 step_B(p,Q[cc+8], Q[cc+9], Y[8], Y[14],Y[5], Y[12],&data[8]);
00288 step_B(p,Q[cc+9], Q[cc+10],Y[9], Y[15],Y[6], Y[13],&data[9]);
00289 step_B(p,Q[cc+10],Q[cc+11],Y[10],Y[0], Y[7], Y[14],&data[10]);
00290 step_B(p,Q[cc+11],Q[cc+12],Y[11],Y[1], Y[8], Y[15],&data[11]);
00291 step_B(p,Q[cc+12],Q[cc+13],Y[12],Y[2], Y[9], Y[0], &data[12]);
00292 step_B(p,Q[cc+13],Q[cc+14],Y[13],Y[3], Y[10],Y[1], &data[13]);
00293 step_B(p,Q[cc+14],Q[cc+15],Y[14],Y[4], Y[11],Y[2], &data[14]);
00294 step_B(p,Q[cc+15],Q[dd+0], Y[15],Y[5], Y[12],Y[3], &data[15]);
00295 }
00296
00297 p->counter2048 = counter2048;
00298 }
00299
00300 static DKC_INLINE int store(DKC_HC256 *p){
00301
00302 dkcmNOT_ASSERT(0 != p->store_size);
00303 if(0 != p->store_size) return edk_LogicError;
00304 get_encrypt_array(p,p->u_store.a32);
00305 p->store_size = 64;
00306 return edk_SUCCEEDED;
00307 }
00308
00309 DKC_INLINE DKC_HC256 *WINAPI dkcAllocHC256(BYTE *key,size_t size,uint32 *iv,size_t ivsize){
00310 DKC_HC256 *p;
00311
00312
00313
00314 if(size != dkcdHC256_KEY_SIZE || ivsize != dkcdHC256_IV_SIZE){
00315 return NULL;
00316 }
00317
00318 p = dkcAllocate(sizeof(DKC_HC256));
00319 if(NULL==p){
00320 return NULL;
00321 }
00322
00323 initialization(p,(uint32 *)key,iv);
00324 store(p);
00325
00326 return p;
00327 }
00328
00329 DKC_INLINE DKC_HC256 *dkcAllocHC256Const(const uint8 *key,size_t size,const uint32 *iv,size_t ivsize)
00330 {
00331 DKC_HC256 *p=NULL;
00332 uint32 *piv = malloc(ivsize);
00333 uint8 *pt;
00334 if(!piv) return NULL;
00335 pt = malloc(size);
00336 if(pt){
00337 memcpy(pt,key,size);
00338 memcpy(piv,iv,ivsize);
00339 p = dkcAllocHC256(pt,size,piv,ivsize);
00340 free(pt);
00341 free(piv);
00342 }
00343 return p;
00344 }
00345
00346 DKC_INLINE int WINAPI dkcFreeHC256(DKC_HC256 **p){
00347 return dkcFree(p);
00348 }
00349
00350
00351 #define get_offset(p) (64 - p->store_size)
00352
00353 DKC_INLINE uint8 WINAPI dkcHC256_Byte(DKC_HC256 *p){
00354 int r = 0;
00355 size_t offset;
00356
00357 if(p->store_size <=0){
00358 r = store(p);
00359 dkcmNOT_ASSERT(DKUTIL_FAILED(r));
00360 }
00361 offset = get_offset(p);
00362 p->store_size--;
00363 return p->u_store.a8[offset];
00364
00365 }
00366
00367 int WINAPI dkcHC256EncryptDOE(DKC_HC256 *p,uint8 *dest,size_t dsize,const uint8 *src,size_t ssize)
00368 {
00369 if(ssize > dsize){
00370 return edk_ArgumentException;
00371 }
00372 if(dest != src){
00373 memcpy(dest,src,ssize);
00374 }
00375 return dkcHC256EncryptNoDestDOE(p,dest,ssize);
00376
00377 }
00378
00380 int WINAPI dkcHC256EncryptNoDestDOE(DKC_HC256 *p,uint8 *inout,size_t size)
00381 {
00382
00383 size_t i;
00384 int r;
00385 size_t count,rest;
00386 uint64 *io64;
00387
00388
00389 if(size <= 0) return edk_SUCCEEDED;
00390 for(i=0;;){
00391 if((size > 64) && ( p->store_size == 0 || 64==p->store_size)){
00392 break;
00393 }
00394 for(;i<size;i++){
00395 inout[i] ^= dkcHC256_Byte(p);
00396 if(p->store_size == 0){
00397 break;
00398 }
00399 }
00400 break;
00401 }
00402 size-=i;
00403 inout+=i;
00404 if(size <= 0) return edk_SUCCEEDED;
00405
00406 count = size / 64;
00407 rest = size % 64;
00408 if(64!=p->store_size){
00409 r = store(p);
00410 dkcmNOT_ASSERT(DKUTIL_FAILED(r));
00411 }
00412 io64 = (uint64 *)inout;
00413 for(;i<count;i++){
00414
00415 io64[0] ^= p->u_store.a64[0];
00416 io64[1] ^= p->u_store.a64[1];
00417 io64[2] ^= p->u_store.a64[2];
00418 io64[3] ^= p->u_store.a64[3];
00419 io64[4] ^= p->u_store.a64[4];
00420 io64[5] ^= p->u_store.a64[5];
00421 io64[6] ^= p->u_store.a64[6];
00422 io64[7] ^= p->u_store.a64[7];
00423
00424 io64+=8;
00425 p->store_size = 0;
00426 store(p);
00427 }
00428 inout =(uint8*)io64;
00429 return dkcHC256EncryptNoDestDOE(p,inout,rest);
00430
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547