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