A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.
Dependents: HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL
hc128.c
00001 /* hc128.c 00002 * 00003 * Copyright (C) 2006-2014 wolfSSL Inc. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifdef HAVE_HC128 00029 00030 #include <cyassl/ctaocrypt/hc128.h> 00031 #include <cyassl/ctaocrypt/error-crypt.h> 00032 #include <cyassl/ctaocrypt/logging.h> 00033 #ifdef NO_INLINE 00034 #include <cyassl/ctaocrypt/hc128.h> 00035 #include <cyassl/ctaocrypt/misc.h> 00036 #else 00037 #include <ctaocrypt/src/misc.c> 00038 #endif 00039 00040 00041 #ifdef BIG_ENDIAN_ORDER 00042 #define LITTLE32(x) ByteReverseWord32(x) 00043 #else 00044 #define LITTLE32(x) (x) 00045 #endif 00046 00047 00048 /*h1 function*/ 00049 #define h1(ctx, x, y) { \ 00050 byte a,c; \ 00051 a = (byte) (x); \ 00052 c = (byte) ((x) >> 16); \ 00053 y = (ctx->T[512+a])+(ctx->T[512+256+c]); \ 00054 } 00055 00056 /*h2 function*/ 00057 #define h2(ctx, x, y) { \ 00058 byte a,c; \ 00059 a = (byte) (x); \ 00060 c = (byte) ((x) >> 16); \ 00061 y = (ctx->T[a])+(ctx->T[256+c]); \ 00062 } 00063 00064 /*one step of HC-128, update P and generate 32 bits keystream*/ 00065 #define step_P(ctx,u,v,a,b,c,d,n){ \ 00066 word32 tem0,tem1,tem2,tem3; \ 00067 h1((ctx),(ctx->X[(d)]),tem3); \ 00068 tem0 = rotrFixed((ctx->T[(v)]),23); \ 00069 tem1 = rotrFixed((ctx->X[(c)]),10); \ 00070 tem2 = rotrFixed((ctx->X[(b)]),8); \ 00071 (ctx->T[(u)]) += tem2+(tem0 ^ tem1); \ 00072 (ctx->X[(a)]) = (ctx->T[(u)]); \ 00073 (n) = tem3 ^ (ctx->T[(u)]) ; \ 00074 } 00075 00076 /*one step of HC-128, update Q and generate 32 bits keystream*/ 00077 #define step_Q(ctx,u,v,a,b,c,d,n){ \ 00078 word32 tem0,tem1,tem2,tem3; \ 00079 h2((ctx),(ctx->Y[(d)]),tem3); \ 00080 tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ 00081 tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ 00082 tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ 00083 (ctx->T[(u)]) += tem2 + (tem0 ^ tem1); \ 00084 (ctx->Y[(a)]) = (ctx->T[(u)]); \ 00085 (n) = tem3 ^ (ctx->T[(u)]) ; \ 00086 } 00087 00088 /*16 steps of HC-128, generate 512 bits keystream*/ 00089 static void generate_keystream(HC128* ctx, word32* keystream) 00090 { 00091 word32 cc,dd; 00092 cc = ctx->counter1024 & 0x1ff; 00093 dd = (cc+16)&0x1ff; 00094 00095 if (ctx->counter1024 < 512) 00096 { 00097 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00098 step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]); 00099 step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]); 00100 step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]); 00101 step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]); 00102 step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]); 00103 step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]); 00104 step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]); 00105 step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]); 00106 step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]); 00107 step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]); 00108 step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]); 00109 step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]); 00110 step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]); 00111 step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]); 00112 step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]); 00113 step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]); 00114 } 00115 else 00116 { 00117 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00118 step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]); 00119 step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]); 00120 step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]); 00121 step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]); 00122 step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]); 00123 step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]); 00124 step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]); 00125 step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]); 00126 step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]); 00127 step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]); 00128 step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]); 00129 step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]); 00130 step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]); 00131 step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]); 00132 step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]); 00133 step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]); 00134 } 00135 } 00136 00137 00138 /* The following defines the initialization functions */ 00139 #define f1(x) (rotrFixed((x),7) ^ rotrFixed((x),18) ^ ((x) >> 3)) 00140 #define f2(x) (rotrFixed((x),17) ^ rotrFixed((x),19) ^ ((x) >> 10)) 00141 00142 /*update table P*/ 00143 #define update_P(ctx,u,v,a,b,c,d){ \ 00144 word32 tem0,tem1,tem2,tem3; \ 00145 tem0 = rotrFixed((ctx->T[(v)]),23); \ 00146 tem1 = rotrFixed((ctx->X[(c)]),10); \ 00147 tem2 = rotrFixed((ctx->X[(b)]),8); \ 00148 h1((ctx),(ctx->X[(d)]),tem3); \ 00149 (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ 00150 (ctx->X[(a)]) = (ctx->T[(u)]); \ 00151 } 00152 00153 /*update table Q*/ 00154 #define update_Q(ctx,u,v,a,b,c,d){ \ 00155 word32 tem0,tem1,tem2,tem3; \ 00156 tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ 00157 tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ 00158 tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ 00159 h2((ctx),(ctx->Y[(d)]),tem3); \ 00160 (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ 00161 (ctx->Y[(a)]) = (ctx->T[(u)]); \ 00162 } 00163 00164 /*16 steps of HC-128, without generating keystream, */ 00165 /*but use the outputs to update P and Q*/ 00166 static void setup_update(HC128* ctx) /*each time 16 steps*/ 00167 { 00168 word32 cc,dd; 00169 cc = ctx->counter1024 & 0x1ff; 00170 dd = (cc+16)&0x1ff; 00171 00172 if (ctx->counter1024 < 512) 00173 { 00174 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00175 update_P(ctx, cc+0, cc+1, 0, 6, 13, 4); 00176 update_P(ctx, cc+1, cc+2, 1, 7, 14, 5); 00177 update_P(ctx, cc+2, cc+3, 2, 8, 15, 6); 00178 update_P(ctx, cc+3, cc+4, 3, 9, 0, 7); 00179 update_P(ctx, cc+4, cc+5, 4, 10,1, 8); 00180 update_P(ctx, cc+5, cc+6, 5, 11,2, 9); 00181 update_P(ctx, cc+6, cc+7, 6, 12,3, 10); 00182 update_P(ctx, cc+7, cc+8, 7, 13,4, 11); 00183 update_P(ctx, cc+8, cc+9, 8, 14,5, 12); 00184 update_P(ctx, cc+9, cc+10,9, 15,6, 13); 00185 update_P(ctx, cc+10,cc+11,10,0, 7, 14); 00186 update_P(ctx, cc+11,cc+12,11,1, 8, 15); 00187 update_P(ctx, cc+12,cc+13,12,2, 9, 0); 00188 update_P(ctx, cc+13,cc+14,13,3, 10, 1); 00189 update_P(ctx, cc+14,cc+15,14,4, 11, 2); 00190 update_P(ctx, cc+15,dd+0, 15,5, 12, 3); 00191 } 00192 else 00193 { 00194 ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; 00195 update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4); 00196 update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5); 00197 update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6); 00198 update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7); 00199 update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8); 00200 update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9); 00201 update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10); 00202 update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11); 00203 update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12); 00204 update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13); 00205 update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14); 00206 update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15); 00207 update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0); 00208 update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1); 00209 update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2); 00210 update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3); 00211 } 00212 } 00213 00214 00215 /* for the 128-bit key: key[0]...key[15] 00216 * key[0] is the least significant byte of ctx->key[0] (K_0); 00217 * key[3] is the most significant byte of ctx->key[0] (K_0); 00218 * ... 00219 * key[12] is the least significant byte of ctx->key[3] (K_3) 00220 * key[15] is the most significant byte of ctx->key[3] (K_3) 00221 * 00222 * for the 128-bit iv: iv[0]...iv[15] 00223 * iv[0] is the least significant byte of ctx->iv[0] (IV_0); 00224 * iv[3] is the most significant byte of ctx->iv[0] (IV_0); 00225 * ... 00226 * iv[12] is the least significant byte of ctx->iv[3] (IV_3) 00227 * iv[15] is the most significant byte of ctx->iv[3] (IV_3) 00228 */ 00229 00230 00231 00232 static void Hc128_SetIV(HC128* ctx, const byte* inIv) 00233 { 00234 word32 i; 00235 word32 iv[4]; 00236 00237 if (inIv) 00238 XMEMCPY(iv, inIv, sizeof(iv)); 00239 else 00240 XMEMSET(iv, 0, sizeof(iv)); 00241 00242 for (i = 0; i < (128 >> 5); i++) 00243 ctx->iv[i] = LITTLE32(iv[i]); 00244 00245 for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4]; 00246 00247 /* expand the key and IV into the table T */ 00248 /* (expand the key and IV into the table P and Q) */ 00249 00250 for (i = 0; i < 8; i++) ctx->T[i] = ctx->key[i]; 00251 for (i = 8; i < 16; i++) ctx->T[i] = ctx->iv[i-8]; 00252 00253 for (i = 16; i < (256+16); i++) 00254 ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + 00255 ctx->T[i-16]+i; 00256 00257 for (i = 0; i < 16; i++) ctx->T[i] = ctx->T[256+i]; 00258 00259 for (i = 16; i < 1024; i++) 00260 ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + 00261 ctx->T[i-16]+256+i; 00262 00263 /* initialize counter1024, X and Y */ 00264 ctx->counter1024 = 0; 00265 for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i]; 00266 for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i]; 00267 00268 /* run the cipher 1024 steps before generating the output */ 00269 for (i = 0; i < 64; i++) setup_update(ctx); 00270 } 00271 00272 00273 static INLINE int DoKey(HC128* ctx, const byte* key, const byte* iv) 00274 { 00275 word32 i; 00276 00277 /* Key size in bits 128 */ 00278 for (i = 0; i < (128 >> 5); i++) 00279 ctx->key[i] = LITTLE32(((word32*)key)[i]); 00280 00281 for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4]; 00282 00283 Hc128_SetIV(ctx, iv); 00284 00285 return 0; 00286 } 00287 00288 00289 /* Key setup */ 00290 int Hc128_SetKey(HC128* ctx, const byte* key, const byte* iv) 00291 { 00292 #ifdef XSTREAM_ALIGN 00293 if ((cyassl_word)key % 4) { 00294 int alignKey[4]; 00295 00296 /* iv gets aligned in SetIV */ 00297 CYASSL_MSG("Hc128SetKey unaligned key"); 00298 00299 XMEMCPY(alignKey, key, sizeof(alignKey)); 00300 00301 return DoKey(ctx, (const byte*)alignKey, iv); 00302 } 00303 #endif /* XSTREAM_ALIGN */ 00304 00305 return DoKey(ctx, key, iv); 00306 } 00307 00308 00309 00310 /* The following defines the encryption of data stream */ 00311 static INLINE int DoProcess(HC128* ctx, byte* output, const byte* input, 00312 word32 msglen) 00313 { 00314 word32 i, keystream[16]; 00315 00316 for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64) 00317 { 00318 generate_keystream(ctx, keystream); 00319 00320 /* unroll loop */ 00321 ((word32*)output)[0] = ((word32*)input)[0] ^ LITTLE32(keystream[0]); 00322 ((word32*)output)[1] = ((word32*)input)[1] ^ LITTLE32(keystream[1]); 00323 ((word32*)output)[2] = ((word32*)input)[2] ^ LITTLE32(keystream[2]); 00324 ((word32*)output)[3] = ((word32*)input)[3] ^ LITTLE32(keystream[3]); 00325 ((word32*)output)[4] = ((word32*)input)[4] ^ LITTLE32(keystream[4]); 00326 ((word32*)output)[5] = ((word32*)input)[5] ^ LITTLE32(keystream[5]); 00327 ((word32*)output)[6] = ((word32*)input)[6] ^ LITTLE32(keystream[6]); 00328 ((word32*)output)[7] = ((word32*)input)[7] ^ LITTLE32(keystream[7]); 00329 ((word32*)output)[8] = ((word32*)input)[8] ^ LITTLE32(keystream[8]); 00330 ((word32*)output)[9] = ((word32*)input)[9] ^ LITTLE32(keystream[9]); 00331 ((word32*)output)[10] = ((word32*)input)[10] ^ LITTLE32(keystream[10]); 00332 ((word32*)output)[11] = ((word32*)input)[11] ^ LITTLE32(keystream[11]); 00333 ((word32*)output)[12] = ((word32*)input)[12] ^ LITTLE32(keystream[12]); 00334 ((word32*)output)[13] = ((word32*)input)[13] ^ LITTLE32(keystream[13]); 00335 ((word32*)output)[14] = ((word32*)input)[14] ^ LITTLE32(keystream[14]); 00336 ((word32*)output)[15] = ((word32*)input)[15] ^ LITTLE32(keystream[15]); 00337 } 00338 00339 if (msglen > 0) 00340 { 00341 XMEMSET(keystream, 0, sizeof(keystream)); /* hush the static analysis */ 00342 generate_keystream(ctx, keystream); 00343 00344 #ifdef BIG_ENDIAN_ORDER 00345 { 00346 word32 wordsLeft = msglen / sizeof(word32); 00347 if (msglen % sizeof(word32)) wordsLeft++; 00348 00349 ByteReverseWords(keystream, keystream, wordsLeft * sizeof(word32)); 00350 } 00351 #endif 00352 00353 for (i = 0; i < msglen; i++) 00354 output[i] = input[i] ^ ((byte*)keystream)[i]; 00355 } 00356 00357 return 0; 00358 } 00359 00360 00361 /* Encrypt/decrypt a message of any size */ 00362 int Hc128_Process(HC128* ctx, byte* output, const byte* input, word32 msglen) 00363 { 00364 #ifdef XSTREAM_ALIGN 00365 if ((cyassl_word)input % 4 || (cyassl_word)output % 4) { 00366 #ifndef NO_CYASSL_ALLOC_ALIGN 00367 byte* tmp; 00368 CYASSL_MSG("Hc128Process unaligned"); 00369 00370 tmp = (byte*)XMALLOC(msglen, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00371 if (tmp == NULL) return MEMORY_E; 00372 00373 XMEMCPY(tmp, input, msglen); 00374 DoProcess(ctx, tmp, tmp, msglen); 00375 XMEMCPY(output, tmp, msglen); 00376 00377 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00378 00379 return 0; 00380 #else 00381 return BAD_ALIGN_E; 00382 #endif 00383 } 00384 #endif /* XSTREAM_ALIGN */ 00385 00386 return DoProcess(ctx, output, input, msglen); 00387 } 00388 00389 00390 #else /* HAVE_HC128 */ 00391 00392 00393 #ifdef _MSC_VER 00394 /* 4206 warning for blank file */ 00395 #pragma warning(disable: 4206) 00396 #endif 00397 00398 00399 #endif /* HAVE_HC128 */
Generated on Wed Jul 13 2022 02:33:56 by
