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