cyassl re-port with cellular comms, PSK test
Dependencies: VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src
cyassllib/ctaocrypt/src/hc128.c@0:e979170e02e7, 2013-04-26 (annotated)
- Committer:
- ashleymills
- Date:
- Fri Apr 26 16:54:58 2013 +0000
- Revision:
- 0:e979170e02e7
Basic operation of SSL with PSK working for cellular.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ashleymills | 0:e979170e02e7 | 1 | /* hc128.c |
ashleymills | 0:e979170e02e7 | 2 | * |
ashleymills | 0:e979170e02e7 | 3 | * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. |
ashleymills | 0:e979170e02e7 | 4 | * |
ashleymills | 0:e979170e02e7 | 5 | * This file is part of CyaSSL. |
ashleymills | 0:e979170e02e7 | 6 | * |
ashleymills | 0:e979170e02e7 | 7 | * CyaSSL is free software; you can redistribute it and/or modify |
ashleymills | 0:e979170e02e7 | 8 | * it under the terms of the GNU General Public License as published by |
ashleymills | 0:e979170e02e7 | 9 | * the Free Software Foundation; either version 2 of the License, or |
ashleymills | 0:e979170e02e7 | 10 | * (at your option) any later version. |
ashleymills | 0:e979170e02e7 | 11 | * |
ashleymills | 0:e979170e02e7 | 12 | * CyaSSL is distributed in the hope that it will be useful, |
ashleymills | 0:e979170e02e7 | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
ashleymills | 0:e979170e02e7 | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ashleymills | 0:e979170e02e7 | 15 | * GNU General Public License for more details. |
ashleymills | 0:e979170e02e7 | 16 | * |
ashleymills | 0:e979170e02e7 | 17 | * You should have received a copy of the GNU General Public License |
ashleymills | 0:e979170e02e7 | 18 | * along with this program; if not, write to the Free Software |
ashleymills | 0:e979170e02e7 | 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
ashleymills | 0:e979170e02e7 | 20 | */ |
ashleymills | 0:e979170e02e7 | 21 | |
ashleymills | 0:e979170e02e7 | 22 | #ifdef HAVE_CONFIG_H |
ashleymills | 0:e979170e02e7 | 23 | #include <config.h> |
ashleymills | 0:e979170e02e7 | 24 | #endif |
ashleymills | 0:e979170e02e7 | 25 | |
ashleymills | 0:e979170e02e7 | 26 | #ifdef HAVE_HC128 |
ashleymills | 0:e979170e02e7 | 27 | |
ashleymills | 0:e979170e02e7 | 28 | #include <cyassl/ctaocrypt/hc128.h> |
ashleymills | 0:e979170e02e7 | 29 | #ifdef NO_INLINE |
ashleymills | 0:e979170e02e7 | 30 | #include <cyassl/ctaocrypt/hc128.h> |
ashleymills | 0:e979170e02e7 | 31 | #else |
ashleymills | 0:e979170e02e7 | 32 | #include <ctaocrypt/src/misc.c> |
ashleymills | 0:e979170e02e7 | 33 | #endif |
ashleymills | 0:e979170e02e7 | 34 | |
ashleymills | 0:e979170e02e7 | 35 | |
ashleymills | 0:e979170e02e7 | 36 | #ifdef BIG_ENDIAN_ORDER |
ashleymills | 0:e979170e02e7 | 37 | #define LITTLE32(x) ByteReverseWord32(x) |
ashleymills | 0:e979170e02e7 | 38 | #else |
ashleymills | 0:e979170e02e7 | 39 | #define LITTLE32(x) (x) |
ashleymills | 0:e979170e02e7 | 40 | #endif |
ashleymills | 0:e979170e02e7 | 41 | |
ashleymills | 0:e979170e02e7 | 42 | |
ashleymills | 0:e979170e02e7 | 43 | /*h1 function*/ |
ashleymills | 0:e979170e02e7 | 44 | #define h1(ctx, x, y) { \ |
ashleymills | 0:e979170e02e7 | 45 | byte a,c; \ |
ashleymills | 0:e979170e02e7 | 46 | a = (byte) (x); \ |
ashleymills | 0:e979170e02e7 | 47 | c = (byte) ((x) >> 16); \ |
ashleymills | 0:e979170e02e7 | 48 | y = (ctx->T[512+a])+(ctx->T[512+256+c]); \ |
ashleymills | 0:e979170e02e7 | 49 | } |
ashleymills | 0:e979170e02e7 | 50 | |
ashleymills | 0:e979170e02e7 | 51 | /*h2 function*/ |
ashleymills | 0:e979170e02e7 | 52 | #define h2(ctx, x, y) { \ |
ashleymills | 0:e979170e02e7 | 53 | byte a,c; \ |
ashleymills | 0:e979170e02e7 | 54 | a = (byte) (x); \ |
ashleymills | 0:e979170e02e7 | 55 | c = (byte) ((x) >> 16); \ |
ashleymills | 0:e979170e02e7 | 56 | y = (ctx->T[a])+(ctx->T[256+c]); \ |
ashleymills | 0:e979170e02e7 | 57 | } |
ashleymills | 0:e979170e02e7 | 58 | |
ashleymills | 0:e979170e02e7 | 59 | /*one step of HC-128, update P and generate 32 bits keystream*/ |
ashleymills | 0:e979170e02e7 | 60 | #define step_P(ctx,u,v,a,b,c,d,n){ \ |
ashleymills | 0:e979170e02e7 | 61 | word32 tem0,tem1,tem2,tem3; \ |
ashleymills | 0:e979170e02e7 | 62 | h1((ctx),(ctx->X[(d)]),tem3); \ |
ashleymills | 0:e979170e02e7 | 63 | tem0 = rotrFixed((ctx->T[(v)]),23); \ |
ashleymills | 0:e979170e02e7 | 64 | tem1 = rotrFixed((ctx->X[(c)]),10); \ |
ashleymills | 0:e979170e02e7 | 65 | tem2 = rotrFixed((ctx->X[(b)]),8); \ |
ashleymills | 0:e979170e02e7 | 66 | (ctx->T[(u)]) += tem2+(tem0 ^ tem1); \ |
ashleymills | 0:e979170e02e7 | 67 | (ctx->X[(a)]) = (ctx->T[(u)]); \ |
ashleymills | 0:e979170e02e7 | 68 | (n) = tem3 ^ (ctx->T[(u)]) ; \ |
ashleymills | 0:e979170e02e7 | 69 | } |
ashleymills | 0:e979170e02e7 | 70 | |
ashleymills | 0:e979170e02e7 | 71 | /*one step of HC-128, update Q and generate 32 bits keystream*/ |
ashleymills | 0:e979170e02e7 | 72 | #define step_Q(ctx,u,v,a,b,c,d,n){ \ |
ashleymills | 0:e979170e02e7 | 73 | word32 tem0,tem1,tem2,tem3; \ |
ashleymills | 0:e979170e02e7 | 74 | h2((ctx),(ctx->Y[(d)]),tem3); \ |
ashleymills | 0:e979170e02e7 | 75 | tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ |
ashleymills | 0:e979170e02e7 | 76 | tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ |
ashleymills | 0:e979170e02e7 | 77 | tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ |
ashleymills | 0:e979170e02e7 | 78 | (ctx->T[(u)]) += tem2 + (tem0 ^ tem1); \ |
ashleymills | 0:e979170e02e7 | 79 | (ctx->Y[(a)]) = (ctx->T[(u)]); \ |
ashleymills | 0:e979170e02e7 | 80 | (n) = tem3 ^ (ctx->T[(u)]) ; \ |
ashleymills | 0:e979170e02e7 | 81 | } |
ashleymills | 0:e979170e02e7 | 82 | |
ashleymills | 0:e979170e02e7 | 83 | /*16 steps of HC-128, generate 512 bits keystream*/ |
ashleymills | 0:e979170e02e7 | 84 | static void generate_keystream(HC128* ctx, word32* keystream) |
ashleymills | 0:e979170e02e7 | 85 | { |
ashleymills | 0:e979170e02e7 | 86 | word32 cc,dd; |
ashleymills | 0:e979170e02e7 | 87 | cc = ctx->counter1024 & 0x1ff; |
ashleymills | 0:e979170e02e7 | 88 | dd = (cc+16)&0x1ff; |
ashleymills | 0:e979170e02e7 | 89 | |
ashleymills | 0:e979170e02e7 | 90 | if (ctx->counter1024 < 512) |
ashleymills | 0:e979170e02e7 | 91 | { |
ashleymills | 0:e979170e02e7 | 92 | ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; |
ashleymills | 0:e979170e02e7 | 93 | step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]); |
ashleymills | 0:e979170e02e7 | 94 | step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]); |
ashleymills | 0:e979170e02e7 | 95 | step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]); |
ashleymills | 0:e979170e02e7 | 96 | step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]); |
ashleymills | 0:e979170e02e7 | 97 | step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]); |
ashleymills | 0:e979170e02e7 | 98 | step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]); |
ashleymills | 0:e979170e02e7 | 99 | step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]); |
ashleymills | 0:e979170e02e7 | 100 | step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]); |
ashleymills | 0:e979170e02e7 | 101 | step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]); |
ashleymills | 0:e979170e02e7 | 102 | step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]); |
ashleymills | 0:e979170e02e7 | 103 | step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]); |
ashleymills | 0:e979170e02e7 | 104 | step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]); |
ashleymills | 0:e979170e02e7 | 105 | step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]); |
ashleymills | 0:e979170e02e7 | 106 | step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]); |
ashleymills | 0:e979170e02e7 | 107 | step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]); |
ashleymills | 0:e979170e02e7 | 108 | step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]); |
ashleymills | 0:e979170e02e7 | 109 | } |
ashleymills | 0:e979170e02e7 | 110 | else |
ashleymills | 0:e979170e02e7 | 111 | { |
ashleymills | 0:e979170e02e7 | 112 | ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; |
ashleymills | 0:e979170e02e7 | 113 | step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]); |
ashleymills | 0:e979170e02e7 | 114 | step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]); |
ashleymills | 0:e979170e02e7 | 115 | step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]); |
ashleymills | 0:e979170e02e7 | 116 | step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]); |
ashleymills | 0:e979170e02e7 | 117 | step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]); |
ashleymills | 0:e979170e02e7 | 118 | step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]); |
ashleymills | 0:e979170e02e7 | 119 | step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]); |
ashleymills | 0:e979170e02e7 | 120 | step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]); |
ashleymills | 0:e979170e02e7 | 121 | step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]); |
ashleymills | 0:e979170e02e7 | 122 | step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]); |
ashleymills | 0:e979170e02e7 | 123 | step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]); |
ashleymills | 0:e979170e02e7 | 124 | step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]); |
ashleymills | 0:e979170e02e7 | 125 | step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]); |
ashleymills | 0:e979170e02e7 | 126 | step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]); |
ashleymills | 0:e979170e02e7 | 127 | step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]); |
ashleymills | 0:e979170e02e7 | 128 | step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]); |
ashleymills | 0:e979170e02e7 | 129 | } |
ashleymills | 0:e979170e02e7 | 130 | } |
ashleymills | 0:e979170e02e7 | 131 | |
ashleymills | 0:e979170e02e7 | 132 | |
ashleymills | 0:e979170e02e7 | 133 | /* The following defines the initialization functions */ |
ashleymills | 0:e979170e02e7 | 134 | #define f1(x) (rotrFixed((x),7) ^ rotrFixed((x),18) ^ ((x) >> 3)) |
ashleymills | 0:e979170e02e7 | 135 | #define f2(x) (rotrFixed((x),17) ^ rotrFixed((x),19) ^ ((x) >> 10)) |
ashleymills | 0:e979170e02e7 | 136 | |
ashleymills | 0:e979170e02e7 | 137 | /*update table P*/ |
ashleymills | 0:e979170e02e7 | 138 | #define update_P(ctx,u,v,a,b,c,d){ \ |
ashleymills | 0:e979170e02e7 | 139 | word32 tem0,tem1,tem2,tem3; \ |
ashleymills | 0:e979170e02e7 | 140 | tem0 = rotrFixed((ctx->T[(v)]),23); \ |
ashleymills | 0:e979170e02e7 | 141 | tem1 = rotrFixed((ctx->X[(c)]),10); \ |
ashleymills | 0:e979170e02e7 | 142 | tem2 = rotrFixed((ctx->X[(b)]),8); \ |
ashleymills | 0:e979170e02e7 | 143 | h1((ctx),(ctx->X[(d)]),tem3); \ |
ashleymills | 0:e979170e02e7 | 144 | (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ |
ashleymills | 0:e979170e02e7 | 145 | (ctx->X[(a)]) = (ctx->T[(u)]); \ |
ashleymills | 0:e979170e02e7 | 146 | } |
ashleymills | 0:e979170e02e7 | 147 | |
ashleymills | 0:e979170e02e7 | 148 | /*update table Q*/ |
ashleymills | 0:e979170e02e7 | 149 | #define update_Q(ctx,u,v,a,b,c,d){ \ |
ashleymills | 0:e979170e02e7 | 150 | word32 tem0,tem1,tem2,tem3; \ |
ashleymills | 0:e979170e02e7 | 151 | tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ |
ashleymills | 0:e979170e02e7 | 152 | tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ |
ashleymills | 0:e979170e02e7 | 153 | tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ |
ashleymills | 0:e979170e02e7 | 154 | h2((ctx),(ctx->Y[(d)]),tem3); \ |
ashleymills | 0:e979170e02e7 | 155 | (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ |
ashleymills | 0:e979170e02e7 | 156 | (ctx->Y[(a)]) = (ctx->T[(u)]); \ |
ashleymills | 0:e979170e02e7 | 157 | } |
ashleymills | 0:e979170e02e7 | 158 | |
ashleymills | 0:e979170e02e7 | 159 | /*16 steps of HC-128, without generating keystream, */ |
ashleymills | 0:e979170e02e7 | 160 | /*but use the outputs to update P and Q*/ |
ashleymills | 0:e979170e02e7 | 161 | static void setup_update(HC128* ctx) /*each time 16 steps*/ |
ashleymills | 0:e979170e02e7 | 162 | { |
ashleymills | 0:e979170e02e7 | 163 | word32 cc,dd; |
ashleymills | 0:e979170e02e7 | 164 | cc = ctx->counter1024 & 0x1ff; |
ashleymills | 0:e979170e02e7 | 165 | dd = (cc+16)&0x1ff; |
ashleymills | 0:e979170e02e7 | 166 | |
ashleymills | 0:e979170e02e7 | 167 | if (ctx->counter1024 < 512) |
ashleymills | 0:e979170e02e7 | 168 | { |
ashleymills | 0:e979170e02e7 | 169 | ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; |
ashleymills | 0:e979170e02e7 | 170 | update_P(ctx, cc+0, cc+1, 0, 6, 13, 4); |
ashleymills | 0:e979170e02e7 | 171 | update_P(ctx, cc+1, cc+2, 1, 7, 14, 5); |
ashleymills | 0:e979170e02e7 | 172 | update_P(ctx, cc+2, cc+3, 2, 8, 15, 6); |
ashleymills | 0:e979170e02e7 | 173 | update_P(ctx, cc+3, cc+4, 3, 9, 0, 7); |
ashleymills | 0:e979170e02e7 | 174 | update_P(ctx, cc+4, cc+5, 4, 10,1, 8); |
ashleymills | 0:e979170e02e7 | 175 | update_P(ctx, cc+5, cc+6, 5, 11,2, 9); |
ashleymills | 0:e979170e02e7 | 176 | update_P(ctx, cc+6, cc+7, 6, 12,3, 10); |
ashleymills | 0:e979170e02e7 | 177 | update_P(ctx, cc+7, cc+8, 7, 13,4, 11); |
ashleymills | 0:e979170e02e7 | 178 | update_P(ctx, cc+8, cc+9, 8, 14,5, 12); |
ashleymills | 0:e979170e02e7 | 179 | update_P(ctx, cc+9, cc+10,9, 15,6, 13); |
ashleymills | 0:e979170e02e7 | 180 | update_P(ctx, cc+10,cc+11,10,0, 7, 14); |
ashleymills | 0:e979170e02e7 | 181 | update_P(ctx, cc+11,cc+12,11,1, 8, 15); |
ashleymills | 0:e979170e02e7 | 182 | update_P(ctx, cc+12,cc+13,12,2, 9, 0); |
ashleymills | 0:e979170e02e7 | 183 | update_P(ctx, cc+13,cc+14,13,3, 10, 1); |
ashleymills | 0:e979170e02e7 | 184 | update_P(ctx, cc+14,cc+15,14,4, 11, 2); |
ashleymills | 0:e979170e02e7 | 185 | update_P(ctx, cc+15,dd+0, 15,5, 12, 3); |
ashleymills | 0:e979170e02e7 | 186 | } |
ashleymills | 0:e979170e02e7 | 187 | else |
ashleymills | 0:e979170e02e7 | 188 | { |
ashleymills | 0:e979170e02e7 | 189 | ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; |
ashleymills | 0:e979170e02e7 | 190 | update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4); |
ashleymills | 0:e979170e02e7 | 191 | update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5); |
ashleymills | 0:e979170e02e7 | 192 | update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6); |
ashleymills | 0:e979170e02e7 | 193 | update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7); |
ashleymills | 0:e979170e02e7 | 194 | update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8); |
ashleymills | 0:e979170e02e7 | 195 | update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9); |
ashleymills | 0:e979170e02e7 | 196 | update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10); |
ashleymills | 0:e979170e02e7 | 197 | update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11); |
ashleymills | 0:e979170e02e7 | 198 | update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12); |
ashleymills | 0:e979170e02e7 | 199 | update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13); |
ashleymills | 0:e979170e02e7 | 200 | update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14); |
ashleymills | 0:e979170e02e7 | 201 | update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15); |
ashleymills | 0:e979170e02e7 | 202 | update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0); |
ashleymills | 0:e979170e02e7 | 203 | update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1); |
ashleymills | 0:e979170e02e7 | 204 | update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2); |
ashleymills | 0:e979170e02e7 | 205 | update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3); |
ashleymills | 0:e979170e02e7 | 206 | } |
ashleymills | 0:e979170e02e7 | 207 | } |
ashleymills | 0:e979170e02e7 | 208 | |
ashleymills | 0:e979170e02e7 | 209 | |
ashleymills | 0:e979170e02e7 | 210 | /* for the 128-bit key: key[0]...key[15] |
ashleymills | 0:e979170e02e7 | 211 | * key[0] is the least significant byte of ctx->key[0] (K_0); |
ashleymills | 0:e979170e02e7 | 212 | * key[3] is the most significant byte of ctx->key[0] (K_0); |
ashleymills | 0:e979170e02e7 | 213 | * ... |
ashleymills | 0:e979170e02e7 | 214 | * key[12] is the least significant byte of ctx->key[3] (K_3) |
ashleymills | 0:e979170e02e7 | 215 | * key[15] is the most significant byte of ctx->key[3] (K_3) |
ashleymills | 0:e979170e02e7 | 216 | * |
ashleymills | 0:e979170e02e7 | 217 | * for the 128-bit iv: iv[0]...iv[15] |
ashleymills | 0:e979170e02e7 | 218 | * iv[0] is the least significant byte of ctx->iv[0] (IV_0); |
ashleymills | 0:e979170e02e7 | 219 | * iv[3] is the most significant byte of ctx->iv[0] (IV_0); |
ashleymills | 0:e979170e02e7 | 220 | * ... |
ashleymills | 0:e979170e02e7 | 221 | * iv[12] is the least significant byte of ctx->iv[3] (IV_3) |
ashleymills | 0:e979170e02e7 | 222 | * iv[15] is the most significant byte of ctx->iv[3] (IV_3) |
ashleymills | 0:e979170e02e7 | 223 | */ |
ashleymills | 0:e979170e02e7 | 224 | |
ashleymills | 0:e979170e02e7 | 225 | |
ashleymills | 0:e979170e02e7 | 226 | |
ashleymills | 0:e979170e02e7 | 227 | static void Hc128_SetIV(HC128* ctx, const byte* iv) |
ashleymills | 0:e979170e02e7 | 228 | { |
ashleymills | 0:e979170e02e7 | 229 | word32 i; |
ashleymills | 0:e979170e02e7 | 230 | |
ashleymills | 0:e979170e02e7 | 231 | for (i = 0; i < (128 >> 5); i++) |
ashleymills | 0:e979170e02e7 | 232 | ctx->iv[i] = LITTLE32(((word32*)iv)[i]); |
ashleymills | 0:e979170e02e7 | 233 | |
ashleymills | 0:e979170e02e7 | 234 | for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4]; |
ashleymills | 0:e979170e02e7 | 235 | |
ashleymills | 0:e979170e02e7 | 236 | /* expand the key and IV into the table T */ |
ashleymills | 0:e979170e02e7 | 237 | /* (expand the key and IV into the table P and Q) */ |
ashleymills | 0:e979170e02e7 | 238 | |
ashleymills | 0:e979170e02e7 | 239 | for (i = 0; i < 8; i++) ctx->T[i] = ctx->key[i]; |
ashleymills | 0:e979170e02e7 | 240 | for (i = 8; i < 16; i++) ctx->T[i] = ctx->iv[i-8]; |
ashleymills | 0:e979170e02e7 | 241 | |
ashleymills | 0:e979170e02e7 | 242 | for (i = 16; i < (256+16); i++) |
ashleymills | 0:e979170e02e7 | 243 | ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + |
ashleymills | 0:e979170e02e7 | 244 | ctx->T[i-16]+i; |
ashleymills | 0:e979170e02e7 | 245 | |
ashleymills | 0:e979170e02e7 | 246 | for (i = 0; i < 16; i++) ctx->T[i] = ctx->T[256+i]; |
ashleymills | 0:e979170e02e7 | 247 | |
ashleymills | 0:e979170e02e7 | 248 | for (i = 16; i < 1024; i++) |
ashleymills | 0:e979170e02e7 | 249 | ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + |
ashleymills | 0:e979170e02e7 | 250 | ctx->T[i-16]+256+i; |
ashleymills | 0:e979170e02e7 | 251 | |
ashleymills | 0:e979170e02e7 | 252 | /* initialize counter1024, X and Y */ |
ashleymills | 0:e979170e02e7 | 253 | ctx->counter1024 = 0; |
ashleymills | 0:e979170e02e7 | 254 | for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i]; |
ashleymills | 0:e979170e02e7 | 255 | for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i]; |
ashleymills | 0:e979170e02e7 | 256 | |
ashleymills | 0:e979170e02e7 | 257 | /* run the cipher 1024 steps before generating the output */ |
ashleymills | 0:e979170e02e7 | 258 | for (i = 0; i < 64; i++) setup_update(ctx); |
ashleymills | 0:e979170e02e7 | 259 | } |
ashleymills | 0:e979170e02e7 | 260 | |
ashleymills | 0:e979170e02e7 | 261 | |
ashleymills | 0:e979170e02e7 | 262 | void Hc128_SetKey(HC128* ctx, const byte* key, const byte* iv) |
ashleymills | 0:e979170e02e7 | 263 | { |
ashleymills | 0:e979170e02e7 | 264 | word32 i; |
ashleymills | 0:e979170e02e7 | 265 | |
ashleymills | 0:e979170e02e7 | 266 | /* Key size in bits 128 */ |
ashleymills | 0:e979170e02e7 | 267 | for (i = 0; i < (128 >> 5); i++) |
ashleymills | 0:e979170e02e7 | 268 | ctx->key[i] = LITTLE32(((word32*)key)[i]); |
ashleymills | 0:e979170e02e7 | 269 | |
ashleymills | 0:e979170e02e7 | 270 | for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4]; |
ashleymills | 0:e979170e02e7 | 271 | |
ashleymills | 0:e979170e02e7 | 272 | Hc128_SetIV(ctx, iv); |
ashleymills | 0:e979170e02e7 | 273 | } |
ashleymills | 0:e979170e02e7 | 274 | |
ashleymills | 0:e979170e02e7 | 275 | |
ashleymills | 0:e979170e02e7 | 276 | /* The following defines the encryption of data stream */ |
ashleymills | 0:e979170e02e7 | 277 | void Hc128_Process(HC128* ctx, byte* output, const byte* input, word32 msglen) |
ashleymills | 0:e979170e02e7 | 278 | { |
ashleymills | 0:e979170e02e7 | 279 | word32 i, keystream[16]; |
ashleymills | 0:e979170e02e7 | 280 | |
ashleymills | 0:e979170e02e7 | 281 | for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64) |
ashleymills | 0:e979170e02e7 | 282 | { |
ashleymills | 0:e979170e02e7 | 283 | generate_keystream(ctx, keystream); |
ashleymills | 0:e979170e02e7 | 284 | |
ashleymills | 0:e979170e02e7 | 285 | /* unroll loop */ |
ashleymills | 0:e979170e02e7 | 286 | ((word32*)output)[0] = ((word32*)input)[0] ^ LITTLE32(keystream[0]); |
ashleymills | 0:e979170e02e7 | 287 | ((word32*)output)[1] = ((word32*)input)[1] ^ LITTLE32(keystream[1]); |
ashleymills | 0:e979170e02e7 | 288 | ((word32*)output)[2] = ((word32*)input)[2] ^ LITTLE32(keystream[2]); |
ashleymills | 0:e979170e02e7 | 289 | ((word32*)output)[3] = ((word32*)input)[3] ^ LITTLE32(keystream[3]); |
ashleymills | 0:e979170e02e7 | 290 | ((word32*)output)[4] = ((word32*)input)[4] ^ LITTLE32(keystream[4]); |
ashleymills | 0:e979170e02e7 | 291 | ((word32*)output)[5] = ((word32*)input)[5] ^ LITTLE32(keystream[5]); |
ashleymills | 0:e979170e02e7 | 292 | ((word32*)output)[6] = ((word32*)input)[6] ^ LITTLE32(keystream[6]); |
ashleymills | 0:e979170e02e7 | 293 | ((word32*)output)[7] = ((word32*)input)[7] ^ LITTLE32(keystream[7]); |
ashleymills | 0:e979170e02e7 | 294 | ((word32*)output)[8] = ((word32*)input)[8] ^ LITTLE32(keystream[8]); |
ashleymills | 0:e979170e02e7 | 295 | ((word32*)output)[9] = ((word32*)input)[9] ^ LITTLE32(keystream[9]); |
ashleymills | 0:e979170e02e7 | 296 | ((word32*)output)[10] = ((word32*)input)[10] ^ LITTLE32(keystream[10]); |
ashleymills | 0:e979170e02e7 | 297 | ((word32*)output)[11] = ((word32*)input)[11] ^ LITTLE32(keystream[11]); |
ashleymills | 0:e979170e02e7 | 298 | ((word32*)output)[12] = ((word32*)input)[12] ^ LITTLE32(keystream[12]); |
ashleymills | 0:e979170e02e7 | 299 | ((word32*)output)[13] = ((word32*)input)[13] ^ LITTLE32(keystream[13]); |
ashleymills | 0:e979170e02e7 | 300 | ((word32*)output)[14] = ((word32*)input)[14] ^ LITTLE32(keystream[14]); |
ashleymills | 0:e979170e02e7 | 301 | ((word32*)output)[15] = ((word32*)input)[15] ^ LITTLE32(keystream[15]); |
ashleymills | 0:e979170e02e7 | 302 | } |
ashleymills | 0:e979170e02e7 | 303 | |
ashleymills | 0:e979170e02e7 | 304 | if (msglen > 0) |
ashleymills | 0:e979170e02e7 | 305 | { |
ashleymills | 0:e979170e02e7 | 306 | generate_keystream(ctx, keystream); |
ashleymills | 0:e979170e02e7 | 307 | |
ashleymills | 0:e979170e02e7 | 308 | #ifdef BIG_ENDIAN_ORDER |
ashleymills | 0:e979170e02e7 | 309 | { |
ashleymills | 0:e979170e02e7 | 310 | word32 wordsLeft = msglen / sizeof(word32); |
ashleymills | 0:e979170e02e7 | 311 | if (msglen % sizeof(word32)) wordsLeft++; |
ashleymills | 0:e979170e02e7 | 312 | |
ashleymills | 0:e979170e02e7 | 313 | ByteReverseWords(keystream, keystream, wordsLeft * sizeof(word32)); |
ashleymills | 0:e979170e02e7 | 314 | } |
ashleymills | 0:e979170e02e7 | 315 | #endif |
ashleymills | 0:e979170e02e7 | 316 | |
ashleymills | 0:e979170e02e7 | 317 | for (i = 0; i < msglen; i++) |
ashleymills | 0:e979170e02e7 | 318 | output[i] = input[i] ^ ((byte*)keystream)[i]; |
ashleymills | 0:e979170e02e7 | 319 | } |
ashleymills | 0:e979170e02e7 | 320 | |
ashleymills | 0:e979170e02e7 | 321 | } |
ashleymills | 0:e979170e02e7 | 322 | |
ashleymills | 0:e979170e02e7 | 323 | |
ashleymills | 0:e979170e02e7 | 324 | #else /* HAVE_HC128 */ |
ashleymills | 0:e979170e02e7 | 325 | |
ashleymills | 0:e979170e02e7 | 326 | |
ashleymills | 0:e979170e02e7 | 327 | #ifdef _MSC_VER |
ashleymills | 0:e979170e02e7 | 328 | /* 4206 warning for blank file */ |
ashleymills | 0:e979170e02e7 | 329 | #pragma warning(disable: 4206) |
ashleymills | 0:e979170e02e7 | 330 | #endif |
ashleymills | 0:e979170e02e7 | 331 | |
ashleymills | 0:e979170e02e7 | 332 | |
ashleymills | 0:e979170e02e7 | 333 | #endif /* HAVE_HC128 */ |