cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:59:36 2013 +0000
Revision:
1:b211d97b0068
Parent:
0:e979170e02e7
nothing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:e979170e02e7 1 /* rabbit.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 #ifndef NO_RABBIT
ashleymills 0:e979170e02e7 27
ashleymills 0:e979170e02e7 28 #include <cyassl/ctaocrypt/rabbit.h>
ashleymills 0:e979170e02e7 29 #ifdef NO_INLINE
ashleymills 0:e979170e02e7 30 #include <cyassl/ctaocrypt/misc.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 #define U32V(x) ((word32)(x) & 0xFFFFFFFFU)
ashleymills 0:e979170e02e7 43
ashleymills 0:e979170e02e7 44
ashleymills 0:e979170e02e7 45 /* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
ashleymills 0:e979170e02e7 46 /* the upper 32 bits XOR the lower 32 bits */
ashleymills 0:e979170e02e7 47 static word32 RABBIT_g_func(word32 x)
ashleymills 0:e979170e02e7 48 {
ashleymills 0:e979170e02e7 49 /* Temporary variables */
ashleymills 0:e979170e02e7 50 word32 a, b, h, l;
ashleymills 0:e979170e02e7 51
ashleymills 0:e979170e02e7 52 /* Construct high and low argument for squaring */
ashleymills 0:e979170e02e7 53 a = x&0xFFFF;
ashleymills 0:e979170e02e7 54 b = x>>16;
ashleymills 0:e979170e02e7 55
ashleymills 0:e979170e02e7 56 /* Calculate high and low result of squaring */
ashleymills 0:e979170e02e7 57 h = (((U32V(a*a)>>17) + U32V(a*b))>>15) + b*b;
ashleymills 0:e979170e02e7 58 l = x*x;
ashleymills 0:e979170e02e7 59
ashleymills 0:e979170e02e7 60 /* Return high XOR low */
ashleymills 0:e979170e02e7 61 return U32V(h^l);
ashleymills 0:e979170e02e7 62 }
ashleymills 0:e979170e02e7 63
ashleymills 0:e979170e02e7 64
ashleymills 0:e979170e02e7 65 /* Calculate the next internal state */
ashleymills 0:e979170e02e7 66 static void RABBIT_next_state(RabbitCtx* ctx)
ashleymills 0:e979170e02e7 67 {
ashleymills 0:e979170e02e7 68 /* Temporary variables */
ashleymills 0:e979170e02e7 69 word32 g[8], c_old[8], i;
ashleymills 0:e979170e02e7 70
ashleymills 0:e979170e02e7 71 /* Save old counter values */
ashleymills 0:e979170e02e7 72 for (i=0; i<8; i++)
ashleymills 0:e979170e02e7 73 c_old[i] = ctx->c[i];
ashleymills 0:e979170e02e7 74
ashleymills 0:e979170e02e7 75 /* Calculate new counter values */
ashleymills 0:e979170e02e7 76 ctx->c[0] = U32V(ctx->c[0] + 0x4D34D34D + ctx->carry);
ashleymills 0:e979170e02e7 77 ctx->c[1] = U32V(ctx->c[1] + 0xD34D34D3 + (ctx->c[0] < c_old[0]));
ashleymills 0:e979170e02e7 78 ctx->c[2] = U32V(ctx->c[2] + 0x34D34D34 + (ctx->c[1] < c_old[1]));
ashleymills 0:e979170e02e7 79 ctx->c[3] = U32V(ctx->c[3] + 0x4D34D34D + (ctx->c[2] < c_old[2]));
ashleymills 0:e979170e02e7 80 ctx->c[4] = U32V(ctx->c[4] + 0xD34D34D3 + (ctx->c[3] < c_old[3]));
ashleymills 0:e979170e02e7 81 ctx->c[5] = U32V(ctx->c[5] + 0x34D34D34 + (ctx->c[4] < c_old[4]));
ashleymills 0:e979170e02e7 82 ctx->c[6] = U32V(ctx->c[6] + 0x4D34D34D + (ctx->c[5] < c_old[5]));
ashleymills 0:e979170e02e7 83 ctx->c[7] = U32V(ctx->c[7] + 0xD34D34D3 + (ctx->c[6] < c_old[6]));
ashleymills 0:e979170e02e7 84 ctx->carry = (ctx->c[7] < c_old[7]);
ashleymills 0:e979170e02e7 85
ashleymills 0:e979170e02e7 86 /* Calculate the g-values */
ashleymills 0:e979170e02e7 87 for (i=0;i<8;i++)
ashleymills 0:e979170e02e7 88 g[i] = RABBIT_g_func(U32V(ctx->x[i] + ctx->c[i]));
ashleymills 0:e979170e02e7 89
ashleymills 0:e979170e02e7 90 /* Calculate new state values */
ashleymills 0:e979170e02e7 91 ctx->x[0] = U32V(g[0] + rotlFixed(g[7],16) + rotlFixed(g[6], 16));
ashleymills 0:e979170e02e7 92 ctx->x[1] = U32V(g[1] + rotlFixed(g[0], 8) + g[7]);
ashleymills 0:e979170e02e7 93 ctx->x[2] = U32V(g[2] + rotlFixed(g[1],16) + rotlFixed(g[0], 16));
ashleymills 0:e979170e02e7 94 ctx->x[3] = U32V(g[3] + rotlFixed(g[2], 8) + g[1]);
ashleymills 0:e979170e02e7 95 ctx->x[4] = U32V(g[4] + rotlFixed(g[3],16) + rotlFixed(g[2], 16));
ashleymills 0:e979170e02e7 96 ctx->x[5] = U32V(g[5] + rotlFixed(g[4], 8) + g[3]);
ashleymills 0:e979170e02e7 97 ctx->x[6] = U32V(g[6] + rotlFixed(g[5],16) + rotlFixed(g[4], 16));
ashleymills 0:e979170e02e7 98 ctx->x[7] = U32V(g[7] + rotlFixed(g[6], 8) + g[5]);
ashleymills 0:e979170e02e7 99 }
ashleymills 0:e979170e02e7 100
ashleymills 0:e979170e02e7 101
ashleymills 0:e979170e02e7 102 /* IV setup */
ashleymills 0:e979170e02e7 103 static void RabbitSetIV(Rabbit* ctx, const byte* iv)
ashleymills 0:e979170e02e7 104 {
ashleymills 0:e979170e02e7 105 /* Temporary variables */
ashleymills 0:e979170e02e7 106 word32 i0, i1, i2, i3, i;
ashleymills 0:e979170e02e7 107
ashleymills 0:e979170e02e7 108 /* Generate four subvectors */
ashleymills 0:e979170e02e7 109 i0 = LITTLE32(*(word32*)(iv+0));
ashleymills 0:e979170e02e7 110 i2 = LITTLE32(*(word32*)(iv+4));
ashleymills 0:e979170e02e7 111 i1 = (i0>>16) | (i2&0xFFFF0000);
ashleymills 0:e979170e02e7 112 i3 = (i2<<16) | (i0&0x0000FFFF);
ashleymills 0:e979170e02e7 113
ashleymills 0:e979170e02e7 114 /* Modify counter values */
ashleymills 0:e979170e02e7 115 ctx->workCtx.c[0] = ctx->masterCtx.c[0] ^ i0;
ashleymills 0:e979170e02e7 116 ctx->workCtx.c[1] = ctx->masterCtx.c[1] ^ i1;
ashleymills 0:e979170e02e7 117 ctx->workCtx.c[2] = ctx->masterCtx.c[2] ^ i2;
ashleymills 0:e979170e02e7 118 ctx->workCtx.c[3] = ctx->masterCtx.c[3] ^ i3;
ashleymills 0:e979170e02e7 119 ctx->workCtx.c[4] = ctx->masterCtx.c[4] ^ i0;
ashleymills 0:e979170e02e7 120 ctx->workCtx.c[5] = ctx->masterCtx.c[5] ^ i1;
ashleymills 0:e979170e02e7 121 ctx->workCtx.c[6] = ctx->masterCtx.c[6] ^ i2;
ashleymills 0:e979170e02e7 122 ctx->workCtx.c[7] = ctx->masterCtx.c[7] ^ i3;
ashleymills 0:e979170e02e7 123
ashleymills 0:e979170e02e7 124 /* Copy state variables */
ashleymills 0:e979170e02e7 125 for (i=0; i<8; i++)
ashleymills 0:e979170e02e7 126 ctx->workCtx.x[i] = ctx->masterCtx.x[i];
ashleymills 0:e979170e02e7 127 ctx->workCtx.carry = ctx->masterCtx.carry;
ashleymills 0:e979170e02e7 128
ashleymills 0:e979170e02e7 129 /* Iterate the system four times */
ashleymills 0:e979170e02e7 130 for (i=0; i<4; i++)
ashleymills 0:e979170e02e7 131 RABBIT_next_state(&(ctx->workCtx));
ashleymills 0:e979170e02e7 132 }
ashleymills 0:e979170e02e7 133
ashleymills 0:e979170e02e7 134
ashleymills 0:e979170e02e7 135 /* Key setup */
ashleymills 0:e979170e02e7 136 void RabbitSetKey(Rabbit* ctx, const byte* key, const byte* iv)
ashleymills 0:e979170e02e7 137 {
ashleymills 0:e979170e02e7 138 /* Temporary variables */
ashleymills 0:e979170e02e7 139 word32 k0, k1, k2, k3, i;
ashleymills 0:e979170e02e7 140
ashleymills 0:e979170e02e7 141 /* Generate four subkeys */
ashleymills 0:e979170e02e7 142 k0 = LITTLE32(*(word32*)(key+ 0));
ashleymills 0:e979170e02e7 143 k1 = LITTLE32(*(word32*)(key+ 4));
ashleymills 0:e979170e02e7 144 k2 = LITTLE32(*(word32*)(key+ 8));
ashleymills 0:e979170e02e7 145 k3 = LITTLE32(*(word32*)(key+12));
ashleymills 0:e979170e02e7 146
ashleymills 0:e979170e02e7 147 /* Generate initial state variables */
ashleymills 0:e979170e02e7 148 ctx->masterCtx.x[0] = k0;
ashleymills 0:e979170e02e7 149 ctx->masterCtx.x[2] = k1;
ashleymills 0:e979170e02e7 150 ctx->masterCtx.x[4] = k2;
ashleymills 0:e979170e02e7 151 ctx->masterCtx.x[6] = k3;
ashleymills 0:e979170e02e7 152 ctx->masterCtx.x[1] = U32V(k3<<16) | (k2>>16);
ashleymills 0:e979170e02e7 153 ctx->masterCtx.x[3] = U32V(k0<<16) | (k3>>16);
ashleymills 0:e979170e02e7 154 ctx->masterCtx.x[5] = U32V(k1<<16) | (k0>>16);
ashleymills 0:e979170e02e7 155 ctx->masterCtx.x[7] = U32V(k2<<16) | (k1>>16);
ashleymills 0:e979170e02e7 156
ashleymills 0:e979170e02e7 157 /* Generate initial counter values */
ashleymills 0:e979170e02e7 158 ctx->masterCtx.c[0] = rotlFixed(k2, 16);
ashleymills 0:e979170e02e7 159 ctx->masterCtx.c[2] = rotlFixed(k3, 16);
ashleymills 0:e979170e02e7 160 ctx->masterCtx.c[4] = rotlFixed(k0, 16);
ashleymills 0:e979170e02e7 161 ctx->masterCtx.c[6] = rotlFixed(k1, 16);
ashleymills 0:e979170e02e7 162 ctx->masterCtx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
ashleymills 0:e979170e02e7 163 ctx->masterCtx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
ashleymills 0:e979170e02e7 164 ctx->masterCtx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
ashleymills 0:e979170e02e7 165 ctx->masterCtx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
ashleymills 0:e979170e02e7 166
ashleymills 0:e979170e02e7 167 /* Clear carry bit */
ashleymills 0:e979170e02e7 168 ctx->masterCtx.carry = 0;
ashleymills 0:e979170e02e7 169
ashleymills 0:e979170e02e7 170 /* Iterate the system four times */
ashleymills 0:e979170e02e7 171 for (i=0; i<4; i++)
ashleymills 0:e979170e02e7 172 RABBIT_next_state(&(ctx->masterCtx));
ashleymills 0:e979170e02e7 173
ashleymills 0:e979170e02e7 174 /* Modify the counters */
ashleymills 0:e979170e02e7 175 for (i=0; i<8; i++)
ashleymills 0:e979170e02e7 176 ctx->masterCtx.c[i] ^= ctx->masterCtx.x[(i+4)&0x7];
ashleymills 0:e979170e02e7 177
ashleymills 0:e979170e02e7 178 /* Copy master instance to work instance */
ashleymills 0:e979170e02e7 179 for (i=0; i<8; i++) {
ashleymills 0:e979170e02e7 180 ctx->workCtx.x[i] = ctx->masterCtx.x[i];
ashleymills 0:e979170e02e7 181 ctx->workCtx.c[i] = ctx->masterCtx.c[i];
ashleymills 0:e979170e02e7 182 }
ashleymills 0:e979170e02e7 183 ctx->workCtx.carry = ctx->masterCtx.carry;
ashleymills 0:e979170e02e7 184
ashleymills 0:e979170e02e7 185 if (iv) RabbitSetIV(ctx, iv);
ashleymills 0:e979170e02e7 186 }
ashleymills 0:e979170e02e7 187
ashleymills 0:e979170e02e7 188
ashleymills 0:e979170e02e7 189 /* Encrypt/decrypt a message of any size */
ashleymills 0:e979170e02e7 190 void RabbitProcess(Rabbit* ctx, byte* output, const byte* input, word32 msglen)
ashleymills 0:e979170e02e7 191 {
ashleymills 0:e979170e02e7 192
ashleymills 0:e979170e02e7 193 /* Encrypt/decrypt all full blocks */
ashleymills 0:e979170e02e7 194 while (msglen >= 16) {
ashleymills 0:e979170e02e7 195 /* Iterate the system */
ashleymills 0:e979170e02e7 196 RABBIT_next_state(&(ctx->workCtx));
ashleymills 0:e979170e02e7 197
ashleymills 0:e979170e02e7 198 /* Encrypt/decrypt 16 bytes of data */
ashleymills 0:e979170e02e7 199 *(word32*)(output+ 0) = *(word32*)(input+ 0) ^
ashleymills 0:e979170e02e7 200 LITTLE32(ctx->workCtx.x[0] ^ (ctx->workCtx.x[5]>>16) ^
ashleymills 0:e979170e02e7 201 U32V(ctx->workCtx.x[3]<<16));
ashleymills 0:e979170e02e7 202 *(word32*)(output+ 4) = *(word32*)(input+ 4) ^
ashleymills 0:e979170e02e7 203 LITTLE32(ctx->workCtx.x[2] ^ (ctx->workCtx.x[7]>>16) ^
ashleymills 0:e979170e02e7 204 U32V(ctx->workCtx.x[5]<<16));
ashleymills 0:e979170e02e7 205 *(word32*)(output+ 8) = *(word32*)(input+ 8) ^
ashleymills 0:e979170e02e7 206 LITTLE32(ctx->workCtx.x[4] ^ (ctx->workCtx.x[1]>>16) ^
ashleymills 0:e979170e02e7 207 U32V(ctx->workCtx.x[7]<<16));
ashleymills 0:e979170e02e7 208 *(word32*)(output+12) = *(word32*)(input+12) ^
ashleymills 0:e979170e02e7 209 LITTLE32(ctx->workCtx.x[6] ^ (ctx->workCtx.x[3]>>16) ^
ashleymills 0:e979170e02e7 210 U32V(ctx->workCtx.x[1]<<16));
ashleymills 0:e979170e02e7 211
ashleymills 0:e979170e02e7 212 /* Increment pointers and decrement length */
ashleymills 0:e979170e02e7 213 input += 16;
ashleymills 0:e979170e02e7 214 output += 16;
ashleymills 0:e979170e02e7 215 msglen -= 16;
ashleymills 0:e979170e02e7 216 }
ashleymills 0:e979170e02e7 217
ashleymills 0:e979170e02e7 218 /* Encrypt/decrypt remaining data */
ashleymills 0:e979170e02e7 219 if (msglen) {
ashleymills 0:e979170e02e7 220
ashleymills 0:e979170e02e7 221 word32 i;
ashleymills 0:e979170e02e7 222 byte buffer[16];
ashleymills 0:e979170e02e7 223
ashleymills 0:e979170e02e7 224 /* Iterate the system */
ashleymills 0:e979170e02e7 225 RABBIT_next_state(&(ctx->workCtx));
ashleymills 0:e979170e02e7 226
ashleymills 0:e979170e02e7 227 /* Generate 16 bytes of pseudo-random data */
ashleymills 0:e979170e02e7 228 *(word32*)(buffer+ 0) = LITTLE32(ctx->workCtx.x[0] ^
ashleymills 0:e979170e02e7 229 (ctx->workCtx.x[5]>>16) ^ U32V(ctx->workCtx.x[3]<<16));
ashleymills 0:e979170e02e7 230 *(word32*)(buffer+ 4) = LITTLE32(ctx->workCtx.x[2] ^
ashleymills 0:e979170e02e7 231 (ctx->workCtx.x[7]>>16) ^ U32V(ctx->workCtx.x[5]<<16));
ashleymills 0:e979170e02e7 232 *(word32*)(buffer+ 8) = LITTLE32(ctx->workCtx.x[4] ^
ashleymills 0:e979170e02e7 233 (ctx->workCtx.x[1]>>16) ^ U32V(ctx->workCtx.x[7]<<16));
ashleymills 0:e979170e02e7 234 *(word32*)(buffer+12) = LITTLE32(ctx->workCtx.x[6] ^
ashleymills 0:e979170e02e7 235 (ctx->workCtx.x[3]>>16) ^ U32V(ctx->workCtx.x[1]<<16));
ashleymills 0:e979170e02e7 236
ashleymills 0:e979170e02e7 237 /* Encrypt/decrypt the data */
ashleymills 0:e979170e02e7 238 for (i=0; i<msglen; i++)
ashleymills 0:e979170e02e7 239 output[i] = input[i] ^ buffer[i]; /* scan-build thinks buffer[i] */
ashleymills 0:e979170e02e7 240 /* is garbage, it is not! */
ashleymills 0:e979170e02e7 241 }
ashleymills 0:e979170e02e7 242 }
ashleymills 0:e979170e02e7 243
ashleymills 0:e979170e02e7 244
ashleymills 0:e979170e02e7 245
ashleymills 0:e979170e02e7 246 #endif /* NO_RABBIT */