wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Thu Apr 28 00:57:21 2016 +0000
Revision:
4:1b0d80432c79
wolfSSL 3.9.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 4:1b0d80432c79 1 /* chacha.c
wolfSSL 4:1b0d80432c79 2 *
wolfSSL 4:1b0d80432c79 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 4:1b0d80432c79 4 *
wolfSSL 4:1b0d80432c79 5 * This file is part of wolfSSL.
wolfSSL 4:1b0d80432c79 6 *
wolfSSL 4:1b0d80432c79 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 4:1b0d80432c79 8 * it under the terms of the GNU General Public License as published by
wolfSSL 4:1b0d80432c79 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 4:1b0d80432c79 10 * (at your option) any later version.
wolfSSL 4:1b0d80432c79 11 *
wolfSSL 4:1b0d80432c79 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 4:1b0d80432c79 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 4:1b0d80432c79 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 4:1b0d80432c79 15 * GNU General Public License for more details.
wolfSSL 4:1b0d80432c79 16 *
wolfSSL 4:1b0d80432c79 17 * You should have received a copy of the GNU General Public License
wolfSSL 4:1b0d80432c79 18 * along with this program; if not, write to the Free Software
wolfSSL 4:1b0d80432c79 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 4:1b0d80432c79 20 */
wolfSSL 4:1b0d80432c79 21
wolfSSL 4:1b0d80432c79 22
wolfSSL 4:1b0d80432c79 23
wolfSSL 4:1b0d80432c79 24 #ifdef HAVE_CONFIG_H
wolfSSL 4:1b0d80432c79 25 #include <config.h>
wolfSSL 4:1b0d80432c79 26 #endif
wolfSSL 4:1b0d80432c79 27
wolfSSL 4:1b0d80432c79 28 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 4:1b0d80432c79 29
wolfSSL 4:1b0d80432c79 30 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
wolfSSL 4:1b0d80432c79 31
wolfSSL 4:1b0d80432c79 32 #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
wolfSSL 4:1b0d80432c79 33 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 4:1b0d80432c79 34 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 4:1b0d80432c79 35 #include <wolfssl/wolfcrypt/chacha.h>
wolfSSL 4:1b0d80432c79 36 #include <wolfssl/wolfcrypt/poly1305.h>
wolfSSL 4:1b0d80432c79 37
wolfSSL 4:1b0d80432c79 38 #ifdef NO_INLINE
wolfSSL 4:1b0d80432c79 39 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 4:1b0d80432c79 40 #else
wolfSSL 4:1b0d80432c79 41 #include <wolfcrypt/src/misc.c>
wolfSSL 4:1b0d80432c79 42 #endif
wolfSSL 4:1b0d80432c79 43
wolfSSL 4:1b0d80432c79 44 #ifdef CHACHA_AEAD_TEST
wolfSSL 4:1b0d80432c79 45 #include <stdio.h>
wolfSSL 4:1b0d80432c79 46 #endif
wolfSSL 4:1b0d80432c79 47
wolfSSL 4:1b0d80432c79 48 #define CHACHA20_POLY1305_AEAD_INITIAL_COUNTER 0
wolfSSL 4:1b0d80432c79 49 #define CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT 16
wolfSSL 4:1b0d80432c79 50
wolfSSL 4:1b0d80432c79 51 static void word32ToLittle64(const word32 inLittle32, byte outLittle64[8]);
wolfSSL 4:1b0d80432c79 52 static int calculateAuthTag(
wolfSSL 4:1b0d80432c79 53 const byte inAuthKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
wolfSSL 4:1b0d80432c79 54 const byte* inAAD, const word32 inAADLen,
wolfSSL 4:1b0d80432c79 55 const byte *inCiphertext, const word32 inCiphertextLen,
wolfSSL 4:1b0d80432c79 56 byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);
wolfSSL 4:1b0d80432c79 57
wolfSSL 4:1b0d80432c79 58 int wc_ChaCha20Poly1305_Encrypt(
wolfSSL 4:1b0d80432c79 59 const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
wolfSSL 4:1b0d80432c79 60 const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
wolfSSL 4:1b0d80432c79 61 const byte* inAAD, const word32 inAADLen,
wolfSSL 4:1b0d80432c79 62 const byte* inPlaintext, const word32 inPlaintextLen,
wolfSSL 4:1b0d80432c79 63 byte* outCiphertext,
wolfSSL 4:1b0d80432c79 64 byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE])
wolfSSL 4:1b0d80432c79 65 {
wolfSSL 4:1b0d80432c79 66 int err;
wolfSSL 4:1b0d80432c79 67 byte poly1305Key[CHACHA20_POLY1305_AEAD_KEYSIZE];
wolfSSL 4:1b0d80432c79 68 ChaCha chaChaCtx;
wolfSSL 4:1b0d80432c79 69
wolfSSL 4:1b0d80432c79 70 /* Validate function arguments */
wolfSSL 4:1b0d80432c79 71
wolfSSL 4:1b0d80432c79 72 if (!inKey || !inIV ||
wolfSSL 4:1b0d80432c79 73 !inPlaintext || !inPlaintextLen ||
wolfSSL 4:1b0d80432c79 74 !outCiphertext ||
wolfSSL 4:1b0d80432c79 75 !outAuthTag)
wolfSSL 4:1b0d80432c79 76 {
wolfSSL 4:1b0d80432c79 77 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 78 }
wolfSSL 4:1b0d80432c79 79
wolfSSL 4:1b0d80432c79 80 XMEMSET(poly1305Key, 0, sizeof(poly1305Key));
wolfSSL 4:1b0d80432c79 81
wolfSSL 4:1b0d80432c79 82 /* Create the Poly1305 key */
wolfSSL 4:1b0d80432c79 83 err = wc_Chacha_SetKey(&chaChaCtx, inKey, CHACHA20_POLY1305_AEAD_KEYSIZE);
wolfSSL 4:1b0d80432c79 84 if (err != 0) return err;
wolfSSL 4:1b0d80432c79 85
wolfSSL 4:1b0d80432c79 86 err = wc_Chacha_SetIV(&chaChaCtx, inIV,
wolfSSL 4:1b0d80432c79 87 CHACHA20_POLY1305_AEAD_INITIAL_COUNTER);
wolfSSL 4:1b0d80432c79 88 if (err != 0) return err;
wolfSSL 4:1b0d80432c79 89
wolfSSL 4:1b0d80432c79 90 err = wc_Chacha_Process(&chaChaCtx, poly1305Key, poly1305Key,
wolfSSL 4:1b0d80432c79 91 CHACHA20_POLY1305_AEAD_KEYSIZE);
wolfSSL 4:1b0d80432c79 92 if (err != 0) return err;
wolfSSL 4:1b0d80432c79 93
wolfSSL 4:1b0d80432c79 94 /* Encrypt the plaintext using ChaCha20 */
wolfSSL 4:1b0d80432c79 95 err = wc_Chacha_Process(&chaChaCtx, outCiphertext, inPlaintext,
wolfSSL 4:1b0d80432c79 96 inPlaintextLen);
wolfSSL 4:1b0d80432c79 97 /* Calculate the Poly1305 auth tag */
wolfSSL 4:1b0d80432c79 98 if (err == 0)
wolfSSL 4:1b0d80432c79 99 err = calculateAuthTag(poly1305Key,
wolfSSL 4:1b0d80432c79 100 inAAD, inAADLen,
wolfSSL 4:1b0d80432c79 101 outCiphertext, inPlaintextLen,
wolfSSL 4:1b0d80432c79 102 outAuthTag);
wolfSSL 4:1b0d80432c79 103 ForceZero(poly1305Key, sizeof(poly1305Key));
wolfSSL 4:1b0d80432c79 104
wolfSSL 4:1b0d80432c79 105 return err;
wolfSSL 4:1b0d80432c79 106 }
wolfSSL 4:1b0d80432c79 107
wolfSSL 4:1b0d80432c79 108
wolfSSL 4:1b0d80432c79 109 int wc_ChaCha20Poly1305_Decrypt(
wolfSSL 4:1b0d80432c79 110 const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
wolfSSL 4:1b0d80432c79 111 const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
wolfSSL 4:1b0d80432c79 112 const byte* inAAD, const word32 inAADLen,
wolfSSL 4:1b0d80432c79 113 const byte* inCiphertext, const word32 inCiphertextLen,
wolfSSL 4:1b0d80432c79 114 const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],
wolfSSL 4:1b0d80432c79 115 byte* outPlaintext)
wolfSSL 4:1b0d80432c79 116 {
wolfSSL 4:1b0d80432c79 117 int err;
wolfSSL 4:1b0d80432c79 118 byte poly1305Key[CHACHA20_POLY1305_AEAD_KEYSIZE];
wolfSSL 4:1b0d80432c79 119 ChaCha chaChaCtx;
wolfSSL 4:1b0d80432c79 120 byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];
wolfSSL 4:1b0d80432c79 121
wolfSSL 4:1b0d80432c79 122 /* Validate function arguments */
wolfSSL 4:1b0d80432c79 123
wolfSSL 4:1b0d80432c79 124 if (!inKey || !inIV ||
wolfSSL 4:1b0d80432c79 125 !inCiphertext || !inCiphertextLen ||
wolfSSL 4:1b0d80432c79 126 !inAuthTag ||
wolfSSL 4:1b0d80432c79 127 !outPlaintext)
wolfSSL 4:1b0d80432c79 128 {
wolfSSL 4:1b0d80432c79 129 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 130 }
wolfSSL 4:1b0d80432c79 131
wolfSSL 4:1b0d80432c79 132 XMEMSET(calculatedAuthTag, 0, sizeof(calculatedAuthTag));
wolfSSL 4:1b0d80432c79 133 XMEMSET(poly1305Key, 0, sizeof(poly1305Key));
wolfSSL 4:1b0d80432c79 134
wolfSSL 4:1b0d80432c79 135 /* Create the Poly1305 key */
wolfSSL 4:1b0d80432c79 136 err = wc_Chacha_SetKey(&chaChaCtx, inKey, CHACHA20_POLY1305_AEAD_KEYSIZE);
wolfSSL 4:1b0d80432c79 137 if (err != 0) return err;
wolfSSL 4:1b0d80432c79 138
wolfSSL 4:1b0d80432c79 139 err = wc_Chacha_SetIV(&chaChaCtx, inIV,
wolfSSL 4:1b0d80432c79 140 CHACHA20_POLY1305_AEAD_INITIAL_COUNTER);
wolfSSL 4:1b0d80432c79 141 if (err != 0) return err;
wolfSSL 4:1b0d80432c79 142
wolfSSL 4:1b0d80432c79 143 err = wc_Chacha_Process(&chaChaCtx, poly1305Key, poly1305Key,
wolfSSL 4:1b0d80432c79 144 CHACHA20_POLY1305_AEAD_KEYSIZE);
wolfSSL 4:1b0d80432c79 145 if (err != 0) return err;
wolfSSL 4:1b0d80432c79 146
wolfSSL 4:1b0d80432c79 147 /* Calculate the Poly1305 auth tag */
wolfSSL 4:1b0d80432c79 148 err = calculateAuthTag(poly1305Key,
wolfSSL 4:1b0d80432c79 149 inAAD, inAADLen,
wolfSSL 4:1b0d80432c79 150 inCiphertext, inCiphertextLen,
wolfSSL 4:1b0d80432c79 151 calculatedAuthTag);
wolfSSL 4:1b0d80432c79 152
wolfSSL 4:1b0d80432c79 153 /* Compare the calculated auth tag with the received one */
wolfSSL 4:1b0d80432c79 154 if (err == 0 && ConstantCompare(inAuthTag, calculatedAuthTag,
wolfSSL 4:1b0d80432c79 155 CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) != 0)
wolfSSL 4:1b0d80432c79 156 {
wolfSSL 4:1b0d80432c79 157 err = MAC_CMP_FAILED_E;
wolfSSL 4:1b0d80432c79 158 }
wolfSSL 4:1b0d80432c79 159
wolfSSL 4:1b0d80432c79 160 /* Decrypt the received ciphertext */
wolfSSL 4:1b0d80432c79 161 if (err == 0)
wolfSSL 4:1b0d80432c79 162 err = wc_Chacha_Process(&chaChaCtx, outPlaintext, inCiphertext,
wolfSSL 4:1b0d80432c79 163 inCiphertextLen);
wolfSSL 4:1b0d80432c79 164 ForceZero(poly1305Key, sizeof(poly1305Key));
wolfSSL 4:1b0d80432c79 165
wolfSSL 4:1b0d80432c79 166 return err;
wolfSSL 4:1b0d80432c79 167 }
wolfSSL 4:1b0d80432c79 168
wolfSSL 4:1b0d80432c79 169
wolfSSL 4:1b0d80432c79 170 static int calculateAuthTag(
wolfSSL 4:1b0d80432c79 171 const byte inAuthKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
wolfSSL 4:1b0d80432c79 172 const byte *inAAD, const word32 inAADLen,
wolfSSL 4:1b0d80432c79 173 const byte *inCiphertext, const word32 inCiphertextLen,
wolfSSL 4:1b0d80432c79 174 byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE])
wolfSSL 4:1b0d80432c79 175 {
wolfSSL 4:1b0d80432c79 176 int err;
wolfSSL 4:1b0d80432c79 177 Poly1305 poly1305Ctx;
wolfSSL 4:1b0d80432c79 178 byte padding[CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1];
wolfSSL 4:1b0d80432c79 179 word32 paddingLen;
wolfSSL 4:1b0d80432c79 180 byte little64[8];
wolfSSL 4:1b0d80432c79 181
wolfSSL 4:1b0d80432c79 182 XMEMSET(padding, 0, sizeof(padding));
wolfSSL 4:1b0d80432c79 183
wolfSSL 4:1b0d80432c79 184 /* Initialize Poly1305 */
wolfSSL 4:1b0d80432c79 185
wolfSSL 4:1b0d80432c79 186 err = wc_Poly1305SetKey(&poly1305Ctx, inAuthKey,
wolfSSL 4:1b0d80432c79 187 CHACHA20_POLY1305_AEAD_KEYSIZE);
wolfSSL 4:1b0d80432c79 188 if (err)
wolfSSL 4:1b0d80432c79 189 {
wolfSSL 4:1b0d80432c79 190 return err;
wolfSSL 4:1b0d80432c79 191 }
wolfSSL 4:1b0d80432c79 192
wolfSSL 4:1b0d80432c79 193 /* Create the authTag by MAC'ing the following items: */
wolfSSL 4:1b0d80432c79 194
wolfSSL 4:1b0d80432c79 195 /* -- AAD */
wolfSSL 4:1b0d80432c79 196
wolfSSL 4:1b0d80432c79 197 if (inAAD && inAADLen)
wolfSSL 4:1b0d80432c79 198 {
wolfSSL 4:1b0d80432c79 199 err = wc_Poly1305Update(&poly1305Ctx, inAAD, inAADLen);
wolfSSL 4:1b0d80432c79 200
wolfSSL 4:1b0d80432c79 201 /* -- padding1: pad the AAD to 16 bytes */
wolfSSL 4:1b0d80432c79 202
wolfSSL 4:1b0d80432c79 203 paddingLen = -(int)inAADLen & (CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1);
wolfSSL 4:1b0d80432c79 204 if (paddingLen)
wolfSSL 4:1b0d80432c79 205 {
wolfSSL 4:1b0d80432c79 206 err += wc_Poly1305Update(&poly1305Ctx, padding, paddingLen);
wolfSSL 4:1b0d80432c79 207 }
wolfSSL 4:1b0d80432c79 208
wolfSSL 4:1b0d80432c79 209 if (err)
wolfSSL 4:1b0d80432c79 210 {
wolfSSL 4:1b0d80432c79 211 return err;
wolfSSL 4:1b0d80432c79 212 }
wolfSSL 4:1b0d80432c79 213 }
wolfSSL 4:1b0d80432c79 214
wolfSSL 4:1b0d80432c79 215 /* -- Ciphertext */
wolfSSL 4:1b0d80432c79 216
wolfSSL 4:1b0d80432c79 217 err = wc_Poly1305Update(&poly1305Ctx, inCiphertext, inCiphertextLen);
wolfSSL 4:1b0d80432c79 218 if (err)
wolfSSL 4:1b0d80432c79 219 {
wolfSSL 4:1b0d80432c79 220 return err;
wolfSSL 4:1b0d80432c79 221 }
wolfSSL 4:1b0d80432c79 222
wolfSSL 4:1b0d80432c79 223 /* -- padding2: pad the ciphertext to 16 bytes */
wolfSSL 4:1b0d80432c79 224
wolfSSL 4:1b0d80432c79 225 paddingLen = -(int)inCiphertextLen &
wolfSSL 4:1b0d80432c79 226 (CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1);
wolfSSL 4:1b0d80432c79 227 if (paddingLen)
wolfSSL 4:1b0d80432c79 228 {
wolfSSL 4:1b0d80432c79 229 err = wc_Poly1305Update(&poly1305Ctx, padding, paddingLen);
wolfSSL 4:1b0d80432c79 230 if (err)
wolfSSL 4:1b0d80432c79 231 {
wolfSSL 4:1b0d80432c79 232 return err;
wolfSSL 4:1b0d80432c79 233 }
wolfSSL 4:1b0d80432c79 234 }
wolfSSL 4:1b0d80432c79 235
wolfSSL 4:1b0d80432c79 236 /* -- AAD length as a 64-bit little endian integer */
wolfSSL 4:1b0d80432c79 237
wolfSSL 4:1b0d80432c79 238 word32ToLittle64(inAADLen, little64);
wolfSSL 4:1b0d80432c79 239
wolfSSL 4:1b0d80432c79 240 err = wc_Poly1305Update(&poly1305Ctx, little64, sizeof(little64));
wolfSSL 4:1b0d80432c79 241 if (err)
wolfSSL 4:1b0d80432c79 242 {
wolfSSL 4:1b0d80432c79 243 return err;
wolfSSL 4:1b0d80432c79 244 }
wolfSSL 4:1b0d80432c79 245
wolfSSL 4:1b0d80432c79 246 /* -- Ciphertext length as a 64-bit little endian integer */
wolfSSL 4:1b0d80432c79 247
wolfSSL 4:1b0d80432c79 248 word32ToLittle64(inCiphertextLen, little64);
wolfSSL 4:1b0d80432c79 249
wolfSSL 4:1b0d80432c79 250 err = wc_Poly1305Update(&poly1305Ctx, little64, sizeof(little64));
wolfSSL 4:1b0d80432c79 251 if (err)
wolfSSL 4:1b0d80432c79 252 {
wolfSSL 4:1b0d80432c79 253 return err;
wolfSSL 4:1b0d80432c79 254 }
wolfSSL 4:1b0d80432c79 255
wolfSSL 4:1b0d80432c79 256 /* Finalize the auth tag */
wolfSSL 4:1b0d80432c79 257
wolfSSL 4:1b0d80432c79 258 err = wc_Poly1305Final(&poly1305Ctx, outAuthTag);
wolfSSL 4:1b0d80432c79 259
wolfSSL 4:1b0d80432c79 260 return err;
wolfSSL 4:1b0d80432c79 261 }
wolfSSL 4:1b0d80432c79 262
wolfSSL 4:1b0d80432c79 263
wolfSSL 4:1b0d80432c79 264 static void word32ToLittle64(const word32 inLittle32, byte outLittle64[8])
wolfSSL 4:1b0d80432c79 265 {
wolfSSL 4:1b0d80432c79 266 XMEMSET(outLittle64, 0, 8);
wolfSSL 4:1b0d80432c79 267
wolfSSL 4:1b0d80432c79 268 outLittle64[0] = (byte)(inLittle32 & 0x000000FF);
wolfSSL 4:1b0d80432c79 269 outLittle64[1] = (byte)((inLittle32 & 0x0000FF00) >> 8);
wolfSSL 4:1b0d80432c79 270 outLittle64[2] = (byte)((inLittle32 & 0x00FF0000) >> 16);
wolfSSL 4:1b0d80432c79 271 outLittle64[3] = (byte)((inLittle32 & 0xFF000000) >> 24);
wolfSSL 4:1b0d80432c79 272 }
wolfSSL 4:1b0d80432c79 273
wolfSSL 4:1b0d80432c79 274
wolfSSL 4:1b0d80432c79 275 #endif /* HAVE_CHACHA && HAVE_POLY1305 */
wolfSSL 4:1b0d80432c79 276