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

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:b86d15c6ba29 1 /* chacha.c
Vanger 0:b86d15c6ba29 2 *
Vanger 0:b86d15c6ba29 3 * Copyright (C) 2006-2014 wolfSSL Inc.
Vanger 0:b86d15c6ba29 4 *
Vanger 0:b86d15c6ba29 5 * This file is part of CyaSSL.
Vanger 0:b86d15c6ba29 6 *
Vanger 0:b86d15c6ba29 7 * CyaSSL is free software; you can redistribute it and/or modify
Vanger 0:b86d15c6ba29 8 * it under the terms of the GNU General Public License as published by
Vanger 0:b86d15c6ba29 9 * the Free Software Foundation; either version 2 of the License, or
Vanger 0:b86d15c6ba29 10 * (at your option) any later version.
Vanger 0:b86d15c6ba29 11 *
Vanger 0:b86d15c6ba29 12 * CyaSSL is distributed in the hope that it will be useful,
Vanger 0:b86d15c6ba29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Vanger 0:b86d15c6ba29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Vanger 0:b86d15c6ba29 15 * GNU General Public License for more details.
Vanger 0:b86d15c6ba29 16 *
Vanger 0:b86d15c6ba29 17 * You should have received a copy of the GNU General Public License
Vanger 0:b86d15c6ba29 18 * along with this program; if not, write to the Free Software
Vanger 0:b86d15c6ba29 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Vanger 0:b86d15c6ba29 20 *
Vanger 0:b86d15c6ba29 21 * based from
Vanger 0:b86d15c6ba29 22 * chacha-ref.c version 20080118
Vanger 0:b86d15c6ba29 23 * D. J. Bernstein
Vanger 0:b86d15c6ba29 24 * Public domain.
Vanger 0:b86d15c6ba29 25 */
Vanger 0:b86d15c6ba29 26
Vanger 0:b86d15c6ba29 27
Vanger 0:b86d15c6ba29 28 #ifdef HAVE_CONFIG_H
Vanger 0:b86d15c6ba29 29 #include <config.h>
Vanger 0:b86d15c6ba29 30 #endif
Vanger 0:b86d15c6ba29 31
Vanger 0:b86d15c6ba29 32 #include <cyassl/ctaocrypt/settings.h>
Vanger 0:b86d15c6ba29 33
Vanger 0:b86d15c6ba29 34 #ifdef HAVE_CHACHA
Vanger 0:b86d15c6ba29 35
Vanger 0:b86d15c6ba29 36 #include <cyassl/ctaocrypt/chacha.h>
Vanger 0:b86d15c6ba29 37 #include <cyassl/ctaocrypt/error-crypt.h>
Vanger 0:b86d15c6ba29 38 #include <cyassl/ctaocrypt/logging.h>
Vanger 0:b86d15c6ba29 39 #ifdef NO_INLINE
Vanger 0:b86d15c6ba29 40 #include <cyassl/ctaocrypt/misc.h>
Vanger 0:b86d15c6ba29 41 #else
Vanger 0:b86d15c6ba29 42 #include <ctaocrypt/src/misc.c>
Vanger 0:b86d15c6ba29 43 #endif
Vanger 0:b86d15c6ba29 44
Vanger 0:b86d15c6ba29 45 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 46 #include <stdio.h>
Vanger 0:b86d15c6ba29 47 #endif
Vanger 0:b86d15c6ba29 48
Vanger 0:b86d15c6ba29 49 #ifdef BIG_ENDIAN_ORDER
Vanger 0:b86d15c6ba29 50 #define LITTLE32(x) ByteReverseWord32(x)
Vanger 0:b86d15c6ba29 51 #else
Vanger 0:b86d15c6ba29 52 #define LITTLE32(x) (x)
Vanger 0:b86d15c6ba29 53 #endif
Vanger 0:b86d15c6ba29 54
Vanger 0:b86d15c6ba29 55 /* Number of rounds */
Vanger 0:b86d15c6ba29 56 #define ROUNDS 20
Vanger 0:b86d15c6ba29 57
Vanger 0:b86d15c6ba29 58 #define U32C(v) (v##U)
Vanger 0:b86d15c6ba29 59 #define U32V(v) ((word32)(v) & U32C(0xFFFFFFFF))
Vanger 0:b86d15c6ba29 60 #define U8TO32_LITTLE(p) LITTLE32(((word32*)(p))[0])
Vanger 0:b86d15c6ba29 61
Vanger 0:b86d15c6ba29 62 #define ROTATE(v,c) rotlFixed(v, c)
Vanger 0:b86d15c6ba29 63 #define XOR(v,w) ((v) ^ (w))
Vanger 0:b86d15c6ba29 64 #define PLUS(v,w) (U32V((v) + (w)))
Vanger 0:b86d15c6ba29 65 #define PLUSONE(v) (PLUS((v),1))
Vanger 0:b86d15c6ba29 66
Vanger 0:b86d15c6ba29 67 #define QUARTERROUND(a,b,c,d) \
Vanger 0:b86d15c6ba29 68 x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
Vanger 0:b86d15c6ba29 69 x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \
Vanger 0:b86d15c6ba29 70 x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
Vanger 0:b86d15c6ba29 71 x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
Vanger 0:b86d15c6ba29 72
Vanger 0:b86d15c6ba29 73
Vanger 0:b86d15c6ba29 74 /**
Vanger 0:b86d15c6ba29 75 * Set up iv(nonce). Earlier versions used 64 bits instead of 96, this version
Vanger 0:b86d15c6ba29 76 * uses the typical AEAD 96 bit nonce and can do record sizes of 256 GB.
Vanger 0:b86d15c6ba29 77 */
Vanger 0:b86d15c6ba29 78 int Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter)
Vanger 0:b86d15c6ba29 79 {
Vanger 0:b86d15c6ba29 80 word32 temp[3]; /* used for alignment of memory */
Vanger 0:b86d15c6ba29 81 XMEMSET(temp, 0, 12);
Vanger 0:b86d15c6ba29 82
Vanger 0:b86d15c6ba29 83 if (ctx == NULL)
Vanger 0:b86d15c6ba29 84 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 85
Vanger 0:b86d15c6ba29 86 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 87 word32 i;
Vanger 0:b86d15c6ba29 88 printf("NONCE : ");
Vanger 0:b86d15c6ba29 89 for (i = 0; i < 12; i++) {
Vanger 0:b86d15c6ba29 90 printf("%02x", inIv[i]);
Vanger 0:b86d15c6ba29 91 }
Vanger 0:b86d15c6ba29 92 printf("\n\n");
Vanger 0:b86d15c6ba29 93 #endif
Vanger 0:b86d15c6ba29 94
Vanger 0:b86d15c6ba29 95 XMEMCPY(temp, inIv, 12);
Vanger 0:b86d15c6ba29 96
Vanger 0:b86d15c6ba29 97 ctx->X[12] = counter; /* block counter */
Vanger 0:b86d15c6ba29 98 ctx->X[13] = temp[0]; /* fixed variable from nonce */
Vanger 0:b86d15c6ba29 99 ctx->X[14] = temp[1]; /* counter from nonce */
Vanger 0:b86d15c6ba29 100 ctx->X[15] = temp[2]; /* counter from nonce */
Vanger 0:b86d15c6ba29 101
Vanger 0:b86d15c6ba29 102 return 0;
Vanger 0:b86d15c6ba29 103 }
Vanger 0:b86d15c6ba29 104
Vanger 0:b86d15c6ba29 105 /* "expand 32-byte k" as unsigned 32 byte */
Vanger 0:b86d15c6ba29 106 static const word32 sigma[4] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};
Vanger 0:b86d15c6ba29 107 /* "expand 16-byte k" as unsigned 16 byte */
Vanger 0:b86d15c6ba29 108 static const word32 tau[4] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574};
Vanger 0:b86d15c6ba29 109
Vanger 0:b86d15c6ba29 110 /**
Vanger 0:b86d15c6ba29 111 * Key setup. 8 word iv (nonce)
Vanger 0:b86d15c6ba29 112 */
Vanger 0:b86d15c6ba29 113 int Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz)
Vanger 0:b86d15c6ba29 114 {
Vanger 0:b86d15c6ba29 115 const word32* constants;
Vanger 0:b86d15c6ba29 116 const byte* k;
Vanger 0:b86d15c6ba29 117
Vanger 0:b86d15c6ba29 118 if (ctx == NULL)
Vanger 0:b86d15c6ba29 119 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 120
Vanger 0:b86d15c6ba29 121 #ifdef XSTREAM_ALIGN
Vanger 0:b86d15c6ba29 122 word32 alignKey[keySz / 4];
Vanger 0:b86d15c6ba29 123 if ((cyassl_word)key % 4) {
Vanger 0:b86d15c6ba29 124 CYASSL_MSG("ChachaSetKey unaligned key");
Vanger 0:b86d15c6ba29 125 XMEMCPY(alignKey, key, sizeof(alignKey));
Vanger 0:b86d15c6ba29 126 k = (byte*)alignKey;
Vanger 0:b86d15c6ba29 127 }
Vanger 0:b86d15c6ba29 128 else {
Vanger 0:b86d15c6ba29 129 k = key;
Vanger 0:b86d15c6ba29 130 }
Vanger 0:b86d15c6ba29 131 #else
Vanger 0:b86d15c6ba29 132 k = key;
Vanger 0:b86d15c6ba29 133 #endif /* XSTREAM_ALIGN */
Vanger 0:b86d15c6ba29 134
Vanger 0:b86d15c6ba29 135 #ifdef CHACHA_AEAD_TEST
Vanger 0:b86d15c6ba29 136 word32 i;
Vanger 0:b86d15c6ba29 137 printf("ChaCha key used :\n");
Vanger 0:b86d15c6ba29 138 for (i = 0; i < keySz; i++) {
Vanger 0:b86d15c6ba29 139 printf("%02x", key[i]);
Vanger 0:b86d15c6ba29 140 if ((i + 1) % 8 == 0)
Vanger 0:b86d15c6ba29 141 printf("\n");
Vanger 0:b86d15c6ba29 142 }
Vanger 0:b86d15c6ba29 143 printf("\n\n");
Vanger 0:b86d15c6ba29 144 #endif
Vanger 0:b86d15c6ba29 145
Vanger 0:b86d15c6ba29 146 ctx->X[4] = U8TO32_LITTLE(k + 0);
Vanger 0:b86d15c6ba29 147 ctx->X[5] = U8TO32_LITTLE(k + 4);
Vanger 0:b86d15c6ba29 148 ctx->X[6] = U8TO32_LITTLE(k + 8);
Vanger 0:b86d15c6ba29 149 ctx->X[7] = U8TO32_LITTLE(k + 12);
Vanger 0:b86d15c6ba29 150 if (keySz == 32) {
Vanger 0:b86d15c6ba29 151 k += 16;
Vanger 0:b86d15c6ba29 152 constants = sigma;
Vanger 0:b86d15c6ba29 153 }
Vanger 0:b86d15c6ba29 154 else {
Vanger 0:b86d15c6ba29 155 /* key size of 128 */
Vanger 0:b86d15c6ba29 156 if (keySz != 16)
Vanger 0:b86d15c6ba29 157 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 158
Vanger 0:b86d15c6ba29 159 constants = tau;
Vanger 0:b86d15c6ba29 160 }
Vanger 0:b86d15c6ba29 161 ctx->X[ 8] = U8TO32_LITTLE(k + 0);
Vanger 0:b86d15c6ba29 162 ctx->X[ 9] = U8TO32_LITTLE(k + 4);
Vanger 0:b86d15c6ba29 163 ctx->X[10] = U8TO32_LITTLE(k + 8);
Vanger 0:b86d15c6ba29 164 ctx->X[11] = U8TO32_LITTLE(k + 12);
Vanger 0:b86d15c6ba29 165 ctx->X[ 0] = U8TO32_LITTLE(constants + 0);
Vanger 0:b86d15c6ba29 166 ctx->X[ 1] = U8TO32_LITTLE(constants + 1);
Vanger 0:b86d15c6ba29 167 ctx->X[ 2] = U8TO32_LITTLE(constants + 2);
Vanger 0:b86d15c6ba29 168 ctx->X[ 3] = U8TO32_LITTLE(constants + 3);
Vanger 0:b86d15c6ba29 169
Vanger 0:b86d15c6ba29 170 return 0;
Vanger 0:b86d15c6ba29 171 }
Vanger 0:b86d15c6ba29 172
Vanger 0:b86d15c6ba29 173 /**
Vanger 0:b86d15c6ba29 174 * Converts word into bytes with rotations having been done.
Vanger 0:b86d15c6ba29 175 */
Vanger 0:b86d15c6ba29 176 static INLINE void Chacha_wordtobyte(word32 output[16], const word32 input[16])
Vanger 0:b86d15c6ba29 177 {
Vanger 0:b86d15c6ba29 178 word32 x[16];
Vanger 0:b86d15c6ba29 179 word32 i;
Vanger 0:b86d15c6ba29 180
Vanger 0:b86d15c6ba29 181 for (i = 0; i < 16; i++) {
Vanger 0:b86d15c6ba29 182 x[i] = input[i];
Vanger 0:b86d15c6ba29 183 }
Vanger 0:b86d15c6ba29 184
Vanger 0:b86d15c6ba29 185 for (i = (ROUNDS); i > 0; i -= 2) {
Vanger 0:b86d15c6ba29 186 QUARTERROUND(0, 4, 8, 12)
Vanger 0:b86d15c6ba29 187 QUARTERROUND(1, 5, 9, 13)
Vanger 0:b86d15c6ba29 188 QUARTERROUND(2, 6, 10, 14)
Vanger 0:b86d15c6ba29 189 QUARTERROUND(3, 7, 11, 15)
Vanger 0:b86d15c6ba29 190 QUARTERROUND(0, 5, 10, 15)
Vanger 0:b86d15c6ba29 191 QUARTERROUND(1, 6, 11, 12)
Vanger 0:b86d15c6ba29 192 QUARTERROUND(2, 7, 8, 13)
Vanger 0:b86d15c6ba29 193 QUARTERROUND(3, 4, 9, 14)
Vanger 0:b86d15c6ba29 194 }
Vanger 0:b86d15c6ba29 195
Vanger 0:b86d15c6ba29 196 for (i = 0; i < 16; i++) {
Vanger 0:b86d15c6ba29 197 x[i] = PLUS(x[i], input[i]);
Vanger 0:b86d15c6ba29 198 }
Vanger 0:b86d15c6ba29 199
Vanger 0:b86d15c6ba29 200 for (i = 0; i < 16; i++) {
Vanger 0:b86d15c6ba29 201 output[i] = LITTLE32(x[i]);
Vanger 0:b86d15c6ba29 202 }
Vanger 0:b86d15c6ba29 203 }
Vanger 0:b86d15c6ba29 204
Vanger 0:b86d15c6ba29 205 /**
Vanger 0:b86d15c6ba29 206 * Encrypt a stream of bytes
Vanger 0:b86d15c6ba29 207 */
Vanger 0:b86d15c6ba29 208 static void Chacha_encrypt_bytes(ChaCha* ctx, const byte* m, byte* c,
Vanger 0:b86d15c6ba29 209 word32 bytes)
Vanger 0:b86d15c6ba29 210 {
Vanger 0:b86d15c6ba29 211 byte* output;
Vanger 0:b86d15c6ba29 212 word32 temp[16]; /* used to make sure aligned */
Vanger 0:b86d15c6ba29 213 word32 i;
Vanger 0:b86d15c6ba29 214
Vanger 0:b86d15c6ba29 215 output = (byte*)temp;
Vanger 0:b86d15c6ba29 216
Vanger 0:b86d15c6ba29 217 if (!bytes) return;
Vanger 0:b86d15c6ba29 218 for (;;) {
Vanger 0:b86d15c6ba29 219 Chacha_wordtobyte(temp, ctx->X);
Vanger 0:b86d15c6ba29 220 ctx->X[12] = PLUSONE(ctx->X[12]);
Vanger 0:b86d15c6ba29 221 if (bytes <= 64) {
Vanger 0:b86d15c6ba29 222 for (i = 0; i < bytes; ++i) {
Vanger 0:b86d15c6ba29 223 c[i] = m[i] ^ output[i];
Vanger 0:b86d15c6ba29 224 }
Vanger 0:b86d15c6ba29 225 return;
Vanger 0:b86d15c6ba29 226 }
Vanger 0:b86d15c6ba29 227 for (i = 0; i < 64; ++i) {
Vanger 0:b86d15c6ba29 228 c[i] = m[i] ^ output[i];
Vanger 0:b86d15c6ba29 229 }
Vanger 0:b86d15c6ba29 230 bytes -= 64;
Vanger 0:b86d15c6ba29 231 c += 64;
Vanger 0:b86d15c6ba29 232 m += 64;
Vanger 0:b86d15c6ba29 233 }
Vanger 0:b86d15c6ba29 234 }
Vanger 0:b86d15c6ba29 235
Vanger 0:b86d15c6ba29 236 /**
Vanger 0:b86d15c6ba29 237 * API to encrypt/decrypt a message of any size.
Vanger 0:b86d15c6ba29 238 */
Vanger 0:b86d15c6ba29 239 int Chacha_Process(ChaCha* ctx, byte* output, const byte* input, word32 msglen)
Vanger 0:b86d15c6ba29 240 {
Vanger 0:b86d15c6ba29 241 if (ctx == NULL)
Vanger 0:b86d15c6ba29 242 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 243
Vanger 0:b86d15c6ba29 244 Chacha_encrypt_bytes(ctx, input, output, msglen);
Vanger 0:b86d15c6ba29 245
Vanger 0:b86d15c6ba29 246 return 0;
Vanger 0:b86d15c6ba29 247 }
Vanger 0:b86d15c6ba29 248
Vanger 0:b86d15c6ba29 249 #endif /* HAVE_CHACHA*/
Vanger 0:b86d15c6ba29 250