cyassl re-port with cellular comms, PSK test
Dependencies: VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src
hc128.c
00001 /* hc128.c 00002 * 00003 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #ifdef HAVE_HC128 00027 00028 #include <cyassl/ctaocrypt/hc128.h> 00029 #ifdef NO_INLINE 00030 #include <cyassl/ctaocrypt/hc128.h> 00031 #else 00032 #include <ctaocrypt/src/misc.c> 00033 #endif 00034 00035 00036 #ifdef BIG_ENDIAN_ORDER 00037 #define LITTLE32(x) ByteReverseWord32(x) 00038 #else 00039 #define LITTLE32(x) (x) 00040 #endif 00041 00042 00043 /*h1 function*/ 00044 #define h1(ctx, x, y) { \ 00045 byte a,c; \ 00046 a = (byte) (x); \ 00047 c = (byte) ((x) >> 16); \ 00048 y = (ctx->T[512+a])+(ctx->T[512+256+c]); \ 00049 } 00050 00051 /*h2 function*/ 00052 #define h2(ctx, x, y) { \ 00053 byte a,c; \ 00054 a = (byte) (x); \ 00055 c = (byte) ((x) >> 16); \ 00056 y = (ctx->T[a])+(ctx->T[256+c]); \ 00057 } 00058 00059 /*one step of HC-128, update P and generate 32 bits keystream*/ 00060 #define step_P(ctx,u,v,a,b,c,d,n){ \ 00061 word32 tem0,tem1,tem2,tem3; \ 00062 h1((ctx),(ctx->X[(d)]),tem3); \ 00063 tem0 = rotrFixed((ctx->T[(v)]),23); \ 00064 tem1 = rotrFixed((ctx->X[(c)]),10); \ 00065 tem2 = rotrFixed((ctx->X[(b)]),8); \ 00066 (ctx->T[(u)]) += tem2+(tem0 ^ tem1); \ 00067 (ctx->X[(a)]) = (ctx->T[(u)]); \ 00068 (n) = tem3 ^ (ctx->T[(u)]) ; \ 00069 } 00070 00071 /*one step of HC-128, update Q and generate 32 bits keystream*/ 00072 #define step_Q(ctx,u,v,a,b,c,d,n){ \ 00073 word32 tem0,tem1,tem2,tem3; \ 00074 h2((ctx),(ctx->Y[(d)]),tem3); \ 00075 tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ 00076 tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ 00077 tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ 00078 (ctx->T[(u)]) += tem2 + (tem0 ^ tem1); \ 00079 (ctx->Y[(a)]) = (ctx->T[(u)]); \ 00080 (n) = tem3 ^ (ctx->T[(u)]) ; \ 00081 } 00082 00083 /*16 steps of HC-128, generate 512 bits keystream*/ 00084 static void generate_keystream(HC128* ctx, word32* keystream) 00085 { 00086 word32 cc,dd; 00087 cc = ctx->counter1024 & 0x1ff; 00088 dd = (cc+16)&0x1ff; 00089 00090 if (ctx->counter1024 < 512) 00091 { 00092 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00093 step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]); 00094 step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]); 00095 step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]); 00096 step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]); 00097 step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]); 00098 step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]); 00099 step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]); 00100 step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]); 00101 step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]); 00102 step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]); 00103 step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]); 00104 step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]); 00105 step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]); 00106 step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]); 00107 step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]); 00108 step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]); 00109 } 00110 else 00111 { 00112 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00113 step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]); 00114 step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]); 00115 step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]); 00116 step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]); 00117 step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]); 00118 step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]); 00119 step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]); 00120 step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]); 00121 step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]); 00122 step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]); 00123 step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]); 00124 step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]); 00125 step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]); 00126 step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]); 00127 step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]); 00128 step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]); 00129 } 00130 } 00131 00132 00133 /* The following defines the initialization functions */ 00134 #define f1(x) (rotrFixed((x),7) ^ rotrFixed((x),18) ^ ((x) >> 3)) 00135 #define f2(x) (rotrFixed((x),17) ^ rotrFixed((x),19) ^ ((x) >> 10)) 00136 00137 /*update table P*/ 00138 #define update_P(ctx,u,v,a,b,c,d){ \ 00139 word32 tem0,tem1,tem2,tem3; \ 00140 tem0 = rotrFixed((ctx->T[(v)]),23); \ 00141 tem1 = rotrFixed((ctx->X[(c)]),10); \ 00142 tem2 = rotrFixed((ctx->X[(b)]),8); \ 00143 h1((ctx),(ctx->X[(d)]),tem3); \ 00144 (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ 00145 (ctx->X[(a)]) = (ctx->T[(u)]); \ 00146 } 00147 00148 /*update table Q*/ 00149 #define update_Q(ctx,u,v,a,b,c,d){ \ 00150 word32 tem0,tem1,tem2,tem3; \ 00151 tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ 00152 tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ 00153 tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ 00154 h2((ctx),(ctx->Y[(d)]),tem3); \ 00155 (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ 00156 (ctx->Y[(a)]) = (ctx->T[(u)]); \ 00157 } 00158 00159 /*16 steps of HC-128, without generating keystream, */ 00160 /*but use the outputs to update P and Q*/ 00161 static void setup_update(HC128* ctx) /*each time 16 steps*/ 00162 { 00163 word32 cc,dd; 00164 cc = ctx->counter1024 & 0x1ff; 00165 dd = (cc+16)&0x1ff; 00166 00167 if (ctx->counter1024 < 512) 00168 { 00169 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00170 update_P(ctx, cc+0, cc+1, 0, 6, 13, 4); 00171 update_P(ctx, cc+1, cc+2, 1, 7, 14, 5); 00172 update_P(ctx, cc+2, cc+3, 2, 8, 15, 6); 00173 update_P(ctx, cc+3, cc+4, 3, 9, 0, 7); 00174 update_P(ctx, cc+4, cc+5, 4, 10,1, 8); 00175 update_P(ctx, cc+5, cc+6, 5, 11,2, 9); 00176 update_P(ctx, cc+6, cc+7, 6, 12,3, 10); 00177 update_P(ctx, cc+7, cc+8, 7, 13,4, 11); 00178 update_P(ctx, cc+8, cc+9, 8, 14,5, 12); 00179 update_P(ctx, cc+9, cc+10,9, 15,6, 13); 00180 update_P(ctx, cc+10,cc+11,10,0, 7, 14); 00181 update_P(ctx, cc+11,cc+12,11,1, 8, 15); 00182 update_P(ctx, cc+12,cc+13,12,2, 9, 0); 00183 update_P(ctx, cc+13,cc+14,13,3, 10, 1); 00184 update_P(ctx, cc+14,cc+15,14,4, 11, 2); 00185 update_P(ctx, cc+15,dd+0, 15,5, 12, 3); 00186 } 00187 else 00188 { 00189 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00190 update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4); 00191 update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5); 00192 update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6); 00193 update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7); 00194 update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8); 00195 update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9); 00196 update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10); 00197 update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11); 00198 update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12); 00199 update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13); 00200 update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14); 00201 update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15); 00202 update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0); 00203 update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1); 00204 update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2); 00205 update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3); 00206 } 00207 } 00208 00209 00210 /* for the 128-bit key: key[0]...key[15] 00211 * key[0] is the least significant byte of ctx->key[0] (K_0); 00212 * key[3] is the most significant byte of ctx->key[0] (K_0); 00213 * ... 00214 * key[12] is the least significant byte of ctx->key[3] (K_3) 00215 * key[15] is the most significant byte of ctx->key[3] (K_3) 00216 * 00217 * for the 128-bit iv: iv[0]...iv[15] 00218 * iv[0] is the least significant byte of ctx->iv[0] (IV_0); 00219 * iv[3] is the most significant byte of ctx->iv[0] (IV_0); 00220 * ... 00221 * iv[12] is the least significant byte of ctx->iv[3] (IV_3) 00222 * iv[15] is the most significant byte of ctx->iv[3] (IV_3) 00223 */ 00224 00225 00226 00227 static void Hc128_SetIV(HC128* ctx, const byte* iv) 00228 { 00229 word32 i; 00230 00231 for (i = 0; i < (128 >> 5); i++) 00232 ctx->iv[i] = LITTLE32(((word32*)iv)[i]); 00233 00234 for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4]; 00235 00236 /* expand the key and IV into the table T */ 00237 /* (expand the key and IV into the table P and Q) */ 00238 00239 for (i = 0; i < 8; i++) ctx->T[i] = ctx->key[i]; 00240 for (i = 8; i < 16; i++) ctx->T[i] = ctx->iv[i-8]; 00241 00242 for (i = 16; i < (256+16); i++) 00243 ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + 00244 ctx->T[i-16]+i; 00245 00246 for (i = 0; i < 16; i++) ctx->T[i] = ctx->T[256+i]; 00247 00248 for (i = 16; i < 1024; i++) 00249 ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + 00250 ctx->T[i-16]+256+i; 00251 00252 /* initialize counter1024, X and Y */ 00253 ctx->counter1024 = 0; 00254 for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i]; 00255 for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i]; 00256 00257 /* run the cipher 1024 steps before generating the output */ 00258 for (i = 0; i < 64; i++) setup_update(ctx); 00259 } 00260 00261 00262 void Hc128_SetKey(HC128* ctx, const byte* key, const byte* iv) 00263 { 00264 word32 i; 00265 00266 /* Key size in bits 128 */ 00267 for (i = 0; i < (128 >> 5); i++) 00268 ctx->key[i] = LITTLE32(((word32*)key)[i]); 00269 00270 for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4]; 00271 00272 Hc128_SetIV(ctx, iv); 00273 } 00274 00275 00276 /* The following defines the encryption of data stream */ 00277 void Hc128_Process(HC128* ctx, byte* output, const byte* input, word32 msglen) 00278 { 00279 word32 i, keystream[16]; 00280 00281 for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64) 00282 { 00283 generate_keystream(ctx, keystream); 00284 00285 /* unroll loop */ 00286 ((word32*)output)[0] = ((word32*)input)[0] ^ LITTLE32(keystream[0]); 00287 ((word32*)output)[1] = ((word32*)input)[1] ^ LITTLE32(keystream[1]); 00288 ((word32*)output)[2] = ((word32*)input)[2] ^ LITTLE32(keystream[2]); 00289 ((word32*)output)[3] = ((word32*)input)[3] ^ LITTLE32(keystream[3]); 00290 ((word32*)output)[4] = ((word32*)input)[4] ^ LITTLE32(keystream[4]); 00291 ((word32*)output)[5] = ((word32*)input)[5] ^ LITTLE32(keystream[5]); 00292 ((word32*)output)[6] = ((word32*)input)[6] ^ LITTLE32(keystream[6]); 00293 ((word32*)output)[7] = ((word32*)input)[7] ^ LITTLE32(keystream[7]); 00294 ((word32*)output)[8] = ((word32*)input)[8] ^ LITTLE32(keystream[8]); 00295 ((word32*)output)[9] = ((word32*)input)[9] ^ LITTLE32(keystream[9]); 00296 ((word32*)output)[10] = ((word32*)input)[10] ^ LITTLE32(keystream[10]); 00297 ((word32*)output)[11] = ((word32*)input)[11] ^ LITTLE32(keystream[11]); 00298 ((word32*)output)[12] = ((word32*)input)[12] ^ LITTLE32(keystream[12]); 00299 ((word32*)output)[13] = ((word32*)input)[13] ^ LITTLE32(keystream[13]); 00300 ((word32*)output)[14] = ((word32*)input)[14] ^ LITTLE32(keystream[14]); 00301 ((word32*)output)[15] = ((word32*)input)[15] ^ LITTLE32(keystream[15]); 00302 } 00303 00304 if (msglen > 0) 00305 { 00306 generate_keystream(ctx, keystream); 00307 00308 #ifdef BIG_ENDIAN_ORDER 00309 { 00310 word32 wordsLeft = msglen / sizeof(word32); 00311 if (msglen % sizeof(word32)) wordsLeft++; 00312 00313 ByteReverseWords(keystream, keystream, wordsLeft * sizeof(word32)); 00314 } 00315 #endif 00316 00317 for (i = 0; i < msglen; i++) 00318 output[i] = input[i] ^ ((byte*)keystream)[i]; 00319 } 00320 00321 } 00322 00323 00324 #else /* HAVE_HC128 */ 00325 00326 00327 #ifdef _MSC_VER 00328 /* 4206 warning for blank file */ 00329 #pragma warning(disable: 4206) 00330 #endif 00331 00332 00333 #endif /* HAVE_HC128 */
Generated on Thu Jul 14 2022 00:25:23 by 1.7.2