wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 06:16:19 2017 +0000
Revision:
13:80fb167dafdf
Parent:
11:cee25a834751
wolfSSL 3.11.1: TLS1.3 Beta

Who changed what in which revision?

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