wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

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 /* poly1305.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 * Based off the public domain implementations by Andrew Moon
wolfSSL 4:1b0d80432c79 24 * and Daniel J. Bernstein
wolfSSL 4:1b0d80432c79 25 */
wolfSSL 4:1b0d80432c79 26
wolfSSL 4:1b0d80432c79 27 #ifdef HAVE_CONFIG_H
wolfSSL 4:1b0d80432c79 28 #include <config.h>
wolfSSL 4:1b0d80432c79 29 #endif
wolfSSL 4:1b0d80432c79 30
wolfSSL 4:1b0d80432c79 31 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 4:1b0d80432c79 32
wolfSSL 4:1b0d80432c79 33 #ifdef HAVE_POLY1305
wolfSSL 4:1b0d80432c79 34 #include <wolfssl/wolfcrypt/poly1305.h>
wolfSSL 4:1b0d80432c79 35 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 4:1b0d80432c79 36 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 4:1b0d80432c79 37 #ifdef NO_INLINE
wolfSSL 4:1b0d80432c79 38 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 4:1b0d80432c79 39 #else
wolfSSL 4:1b0d80432c79 40 #include <wolfcrypt/src/misc.c>
wolfSSL 4:1b0d80432c79 41 #endif
wolfSSL 4:1b0d80432c79 42 #ifdef CHACHA_AEAD_TEST
wolfSSL 4:1b0d80432c79 43 #include <stdio.h>
wolfSSL 4:1b0d80432c79 44 #endif
wolfSSL 4:1b0d80432c79 45
wolfSSL 4:1b0d80432c79 46 #ifdef _MSC_VER
wolfSSL 4:1b0d80432c79 47 /* 4127 warning constant while(1) */
wolfSSL 4:1b0d80432c79 48 #pragma warning(disable: 4127)
wolfSSL 4:1b0d80432c79 49 #endif
wolfSSL 4:1b0d80432c79 50
wolfSSL 4:1b0d80432c79 51 #if defined(POLY130564)
wolfSSL 4:1b0d80432c79 52
wolfSSL 4:1b0d80432c79 53 #if defined(_MSC_VER)
wolfSSL 4:1b0d80432c79 54 #define POLY1305_NOINLINE __declspec(noinline)
wolfSSL 4:1b0d80432c79 55 #elif defined(__GNUC__)
wolfSSL 4:1b0d80432c79 56 #define POLY1305_NOINLINE __attribute__((noinline))
wolfSSL 4:1b0d80432c79 57 #else
wolfSSL 4:1b0d80432c79 58 #define POLY1305_NOINLINE
wolfSSL 4:1b0d80432c79 59 #endif
wolfSSL 4:1b0d80432c79 60
wolfSSL 4:1b0d80432c79 61 #if defined(_MSC_VER)
wolfSSL 4:1b0d80432c79 62 #include <intrin.h>
wolfSSL 4:1b0d80432c79 63
wolfSSL 4:1b0d80432c79 64 typedef struct word128 {
wolfSSL 4:1b0d80432c79 65 word64 lo;
wolfSSL 4:1b0d80432c79 66 word64 hi;
wolfSSL 4:1b0d80432c79 67 } word128;
wolfSSL 4:1b0d80432c79 68
wolfSSL 4:1b0d80432c79 69 #define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi)
wolfSSL 4:1b0d80432c79 70 #define ADD(out, in) { word64 t = out.lo; out.lo += in.lo;
wolfSSL 4:1b0d80432c79 71 out.hi += (out.lo < t) + in.hi; }
wolfSSL 4:1b0d80432c79 72 #define ADDLO(out, in) { word64 t = out.lo; out.lo += in;
wolfSSL 4:1b0d80432c79 73 out.hi += (out.lo < t); }
wolfSSL 4:1b0d80432c79 74 #define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift)))
wolfSSL 4:1b0d80432c79 75 #define LO(in) (in.lo)
wolfSSL 4:1b0d80432c79 76
wolfSSL 4:1b0d80432c79 77 #elif defined(__GNUC__)
wolfSSL 4:1b0d80432c79 78 #if defined(__SIZEOF_INT128__)
wolfSSL 4:1b0d80432c79 79 typedef unsigned __int128 word128;
wolfSSL 4:1b0d80432c79 80 #else
wolfSSL 4:1b0d80432c79 81 typedef unsigned word128 __attribute__((mode(TI)));
wolfSSL 4:1b0d80432c79 82 #endif
wolfSSL 4:1b0d80432c79 83
wolfSSL 4:1b0d80432c79 84 #define MUL(out, x, y) out = ((word128)x * y)
wolfSSL 4:1b0d80432c79 85 #define ADD(out, in) out += in
wolfSSL 4:1b0d80432c79 86 #define ADDLO(out, in) out += in
wolfSSL 4:1b0d80432c79 87 #define SHR(in, shift) (word64)(in >> (shift))
wolfSSL 4:1b0d80432c79 88 #define LO(in) (word64)(in)
wolfSSL 4:1b0d80432c79 89 #endif
wolfSSL 4:1b0d80432c79 90
wolfSSL 4:1b0d80432c79 91 static word64 U8TO64(const byte* p) {
wolfSSL 4:1b0d80432c79 92 return
wolfSSL 4:1b0d80432c79 93 (((word64)(p[0] & 0xff) ) |
wolfSSL 4:1b0d80432c79 94 ((word64)(p[1] & 0xff) << 8) |
wolfSSL 4:1b0d80432c79 95 ((word64)(p[2] & 0xff) << 16) |
wolfSSL 4:1b0d80432c79 96 ((word64)(p[3] & 0xff) << 24) |
wolfSSL 4:1b0d80432c79 97 ((word64)(p[4] & 0xff) << 32) |
wolfSSL 4:1b0d80432c79 98 ((word64)(p[5] & 0xff) << 40) |
wolfSSL 4:1b0d80432c79 99 ((word64)(p[6] & 0xff) << 48) |
wolfSSL 4:1b0d80432c79 100 ((word64)(p[7] & 0xff) << 56));
wolfSSL 4:1b0d80432c79 101 }
wolfSSL 4:1b0d80432c79 102
wolfSSL 4:1b0d80432c79 103 static void U64TO8(byte* p, word64 v) {
wolfSSL 4:1b0d80432c79 104 p[0] = (v ) & 0xff;
wolfSSL 4:1b0d80432c79 105 p[1] = (v >> 8) & 0xff;
wolfSSL 4:1b0d80432c79 106 p[2] = (v >> 16) & 0xff;
wolfSSL 4:1b0d80432c79 107 p[3] = (v >> 24) & 0xff;
wolfSSL 4:1b0d80432c79 108 p[4] = (v >> 32) & 0xff;
wolfSSL 4:1b0d80432c79 109 p[5] = (v >> 40) & 0xff;
wolfSSL 4:1b0d80432c79 110 p[6] = (v >> 48) & 0xff;
wolfSSL 4:1b0d80432c79 111 p[7] = (v >> 56) & 0xff;
wolfSSL 4:1b0d80432c79 112 }
wolfSSL 4:1b0d80432c79 113
wolfSSL 4:1b0d80432c79 114 #else /* if not 64 bit then use 32 bit */
wolfSSL 4:1b0d80432c79 115
wolfSSL 4:1b0d80432c79 116 static word32 U8TO32(const byte *p) {
wolfSSL 4:1b0d80432c79 117 return
wolfSSL 4:1b0d80432c79 118 (((word32)(p[0] & 0xff) ) |
wolfSSL 4:1b0d80432c79 119 ((word32)(p[1] & 0xff) << 8) |
wolfSSL 4:1b0d80432c79 120 ((word32)(p[2] & 0xff) << 16) |
wolfSSL 4:1b0d80432c79 121 ((word32)(p[3] & 0xff) << 24));
wolfSSL 4:1b0d80432c79 122 }
wolfSSL 4:1b0d80432c79 123
wolfSSL 4:1b0d80432c79 124 static void U32TO8(byte *p, word32 v) {
wolfSSL 4:1b0d80432c79 125 p[0] = (v ) & 0xff;
wolfSSL 4:1b0d80432c79 126 p[1] = (v >> 8) & 0xff;
wolfSSL 4:1b0d80432c79 127 p[2] = (v >> 16) & 0xff;
wolfSSL 4:1b0d80432c79 128 p[3] = (v >> 24) & 0xff;
wolfSSL 4:1b0d80432c79 129 }
wolfSSL 4:1b0d80432c79 130 #endif
wolfSSL 4:1b0d80432c79 131
wolfSSL 4:1b0d80432c79 132
wolfSSL 4:1b0d80432c79 133 static void U32TO64(word32 v, byte* p) {
wolfSSL 4:1b0d80432c79 134 XMEMSET(p, 0, 8);
wolfSSL 4:1b0d80432c79 135 p[0] = (v & 0xFF);
wolfSSL 4:1b0d80432c79 136 p[1] = (v >> 8) & 0xFF;
wolfSSL 4:1b0d80432c79 137 p[2] = (v >> 16) & 0xFF;
wolfSSL 4:1b0d80432c79 138 p[3] = (v >> 24) & 0xFF;
wolfSSL 4:1b0d80432c79 139 }
wolfSSL 4:1b0d80432c79 140
wolfSSL 4:1b0d80432c79 141
wolfSSL 4:1b0d80432c79 142 static void poly1305_blocks(Poly1305* ctx, const unsigned char *m,
wolfSSL 4:1b0d80432c79 143 size_t bytes) {
wolfSSL 4:1b0d80432c79 144
wolfSSL 4:1b0d80432c79 145 #ifdef POLY130564
wolfSSL 4:1b0d80432c79 146
wolfSSL 4:1b0d80432c79 147 const word64 hibit = (ctx->final) ? 0 : ((word64)1 << 40); /* 1 << 128 */
wolfSSL 4:1b0d80432c79 148 word64 r0,r1,r2;
wolfSSL 4:1b0d80432c79 149 word64 s1,s2;
wolfSSL 4:1b0d80432c79 150 word64 h0,h1,h2;
wolfSSL 4:1b0d80432c79 151 word64 c;
wolfSSL 4:1b0d80432c79 152 word128 d0,d1,d2,d;
wolfSSL 4:1b0d80432c79 153
wolfSSL 4:1b0d80432c79 154 #else
wolfSSL 4:1b0d80432c79 155
wolfSSL 4:1b0d80432c79 156 const word32 hibit = (ctx->final) ? 0 : (1 << 24); /* 1 << 128 */
wolfSSL 4:1b0d80432c79 157 word32 r0,r1,r2,r3,r4;
wolfSSL 4:1b0d80432c79 158 word32 s1,s2,s3,s4;
wolfSSL 4:1b0d80432c79 159 word32 h0,h1,h2,h3,h4;
wolfSSL 4:1b0d80432c79 160 word64 d0,d1,d2,d3,d4;
wolfSSL 4:1b0d80432c79 161 word32 c;
wolfSSL 4:1b0d80432c79 162
wolfSSL 4:1b0d80432c79 163 #endif
wolfSSL 4:1b0d80432c79 164
wolfSSL 4:1b0d80432c79 165 #ifdef POLY130564
wolfSSL 4:1b0d80432c79 166
wolfSSL 4:1b0d80432c79 167 r0 = ctx->r[0];
wolfSSL 4:1b0d80432c79 168 r1 = ctx->r[1];
wolfSSL 4:1b0d80432c79 169 r2 = ctx->r[2];
wolfSSL 4:1b0d80432c79 170
wolfSSL 4:1b0d80432c79 171 h0 = ctx->h[0];
wolfSSL 4:1b0d80432c79 172 h1 = ctx->h[1];
wolfSSL 4:1b0d80432c79 173 h2 = ctx->h[2];
wolfSSL 4:1b0d80432c79 174
wolfSSL 4:1b0d80432c79 175 s1 = r1 * (5 << 2);
wolfSSL 4:1b0d80432c79 176 s2 = r2 * (5 << 2);
wolfSSL 4:1b0d80432c79 177
wolfSSL 4:1b0d80432c79 178 while (bytes >= POLY1305_BLOCK_SIZE) {
wolfSSL 4:1b0d80432c79 179 word64 t0,t1;
wolfSSL 4:1b0d80432c79 180
wolfSSL 4:1b0d80432c79 181 /* h += m[i] */
wolfSSL 4:1b0d80432c79 182 t0 = U8TO64(&m[0]);
wolfSSL 4:1b0d80432c79 183 t1 = U8TO64(&m[8]);
wolfSSL 4:1b0d80432c79 184
wolfSSL 4:1b0d80432c79 185 h0 += (( t0 ) & 0xfffffffffff);
wolfSSL 4:1b0d80432c79 186 h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);
wolfSSL 4:1b0d80432c79 187 h2 += (((t1 >> 24) ) & 0x3ffffffffff) | hibit;
wolfSSL 4:1b0d80432c79 188
wolfSSL 4:1b0d80432c79 189 /* h *= r */
wolfSSL 4:1b0d80432c79 190 MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d);
wolfSSL 4:1b0d80432c79 191 MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d);
wolfSSL 4:1b0d80432c79 192 MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d);
wolfSSL 4:1b0d80432c79 193
wolfSSL 4:1b0d80432c79 194 /* (partial) h %= p */
wolfSSL 4:1b0d80432c79 195 c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff;
wolfSSL 4:1b0d80432c79 196 ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff;
wolfSSL 4:1b0d80432c79 197 ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff;
wolfSSL 4:1b0d80432c79 198 h0 += c * 5; c = (h0 >> 44); h0 = h0 & 0xfffffffffff;
wolfSSL 4:1b0d80432c79 199 h1 += c;
wolfSSL 4:1b0d80432c79 200
wolfSSL 4:1b0d80432c79 201 m += POLY1305_BLOCK_SIZE;
wolfSSL 4:1b0d80432c79 202 bytes -= POLY1305_BLOCK_SIZE;
wolfSSL 4:1b0d80432c79 203 }
wolfSSL 4:1b0d80432c79 204
wolfSSL 4:1b0d80432c79 205 ctx->h[0] = h0;
wolfSSL 4:1b0d80432c79 206 ctx->h[1] = h1;
wolfSSL 4:1b0d80432c79 207 ctx->h[2] = h2;
wolfSSL 4:1b0d80432c79 208
wolfSSL 4:1b0d80432c79 209 #else /* if not 64 bit then use 32 bit */
wolfSSL 4:1b0d80432c79 210
wolfSSL 4:1b0d80432c79 211 r0 = ctx->r[0];
wolfSSL 4:1b0d80432c79 212 r1 = ctx->r[1];
wolfSSL 4:1b0d80432c79 213 r2 = ctx->r[2];
wolfSSL 4:1b0d80432c79 214 r3 = ctx->r[3];
wolfSSL 4:1b0d80432c79 215 r4 = ctx->r[4];
wolfSSL 4:1b0d80432c79 216
wolfSSL 4:1b0d80432c79 217 s1 = r1 * 5;
wolfSSL 4:1b0d80432c79 218 s2 = r2 * 5;
wolfSSL 4:1b0d80432c79 219 s3 = r3 * 5;
wolfSSL 4:1b0d80432c79 220 s4 = r4 * 5;
wolfSSL 4:1b0d80432c79 221
wolfSSL 4:1b0d80432c79 222 h0 = ctx->h[0];
wolfSSL 4:1b0d80432c79 223 h1 = ctx->h[1];
wolfSSL 4:1b0d80432c79 224 h2 = ctx->h[2];
wolfSSL 4:1b0d80432c79 225 h3 = ctx->h[3];
wolfSSL 4:1b0d80432c79 226 h4 = ctx->h[4];
wolfSSL 4:1b0d80432c79 227
wolfSSL 4:1b0d80432c79 228 while (bytes >= POLY1305_BLOCK_SIZE) {
wolfSSL 4:1b0d80432c79 229 /* h += m[i] */
wolfSSL 4:1b0d80432c79 230 h0 += (U8TO32(m+ 0) ) & 0x3ffffff;
wolfSSL 4:1b0d80432c79 231 h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff;
wolfSSL 4:1b0d80432c79 232 h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff;
wolfSSL 4:1b0d80432c79 233 h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff;
wolfSSL 4:1b0d80432c79 234 h4 += (U8TO32(m+12) >> 8) | hibit;
wolfSSL 4:1b0d80432c79 235
wolfSSL 4:1b0d80432c79 236 /* h *= r */
wolfSSL 4:1b0d80432c79 237 d0 = ((word64)h0 * r0) + ((word64)h1 * s4) + ((word64)h2 * s3) +
wolfSSL 4:1b0d80432c79 238 ((word64)h3 * s2) + ((word64)h4 * s1);
wolfSSL 4:1b0d80432c79 239 d1 = ((word64)h0 * r1) + ((word64)h1 * r0) + ((word64)h2 * s4) +
wolfSSL 4:1b0d80432c79 240 ((word64)h3 * s3) + ((word64)h4 * s2);
wolfSSL 4:1b0d80432c79 241 d2 = ((word64)h0 * r2) + ((word64)h1 * r1) + ((word64)h2 * r0) +
wolfSSL 4:1b0d80432c79 242 ((word64)h3 * s4) + ((word64)h4 * s3);
wolfSSL 4:1b0d80432c79 243 d3 = ((word64)h0 * r3) + ((word64)h1 * r2) + ((word64)h2 * r1) +
wolfSSL 4:1b0d80432c79 244 ((word64)h3 * r0) + ((word64)h4 * s4);
wolfSSL 4:1b0d80432c79 245 d4 = ((word64)h0 * r4) + ((word64)h1 * r3) + ((word64)h2 * r2) +
wolfSSL 4:1b0d80432c79 246 ((word64)h3 * r1) + ((word64)h4 * r0);
wolfSSL 4:1b0d80432c79 247
wolfSSL 4:1b0d80432c79 248 /* (partial) h %= p */
wolfSSL 4:1b0d80432c79 249 c = (word32)(d0 >> 26); h0 = (word32)d0 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 250 d1 += c; c = (word32)(d1 >> 26); h1 = (word32)d1 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 251 d2 += c; c = (word32)(d2 >> 26); h2 = (word32)d2 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 252 d3 += c; c = (word32)(d3 >> 26); h3 = (word32)d3 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 253 d4 += c; c = (word32)(d4 >> 26); h4 = (word32)d4 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 254 h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 255 h1 += c;
wolfSSL 4:1b0d80432c79 256
wolfSSL 4:1b0d80432c79 257 m += POLY1305_BLOCK_SIZE;
wolfSSL 4:1b0d80432c79 258 bytes -= POLY1305_BLOCK_SIZE;
wolfSSL 4:1b0d80432c79 259 }
wolfSSL 4:1b0d80432c79 260
wolfSSL 4:1b0d80432c79 261 ctx->h[0] = h0;
wolfSSL 4:1b0d80432c79 262 ctx->h[1] = h1;
wolfSSL 4:1b0d80432c79 263 ctx->h[2] = h2;
wolfSSL 4:1b0d80432c79 264 ctx->h[3] = h3;
wolfSSL 4:1b0d80432c79 265 ctx->h[4] = h4;
wolfSSL 4:1b0d80432c79 266
wolfSSL 4:1b0d80432c79 267 #endif /* end of 64 bit cpu blocks or 32 bit cpu */
wolfSSL 4:1b0d80432c79 268 }
wolfSSL 4:1b0d80432c79 269
wolfSSL 4:1b0d80432c79 270
wolfSSL 4:1b0d80432c79 271 int wc_Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz) {
wolfSSL 4:1b0d80432c79 272
wolfSSL 4:1b0d80432c79 273 #if defined(POLY130564)
wolfSSL 4:1b0d80432c79 274 word64 t0,t1;
wolfSSL 4:1b0d80432c79 275 #endif
wolfSSL 4:1b0d80432c79 276
wolfSSL 4:1b0d80432c79 277 #ifdef CHACHA_AEAD_TEST
wolfSSL 4:1b0d80432c79 278 word32 k;
wolfSSL 4:1b0d80432c79 279 printf("Poly key used:\n");
wolfSSL 4:1b0d80432c79 280 for (k = 0; k < keySz; k++) {
wolfSSL 4:1b0d80432c79 281 printf("%02x", key[k]);
wolfSSL 4:1b0d80432c79 282 if ((k+1) % 8 == 0)
wolfSSL 4:1b0d80432c79 283 printf("\n");
wolfSSL 4:1b0d80432c79 284 }
wolfSSL 4:1b0d80432c79 285 printf("\n");
wolfSSL 4:1b0d80432c79 286 #endif
wolfSSL 4:1b0d80432c79 287
wolfSSL 4:1b0d80432c79 288 if (keySz != 32 || ctx == NULL)
wolfSSL 4:1b0d80432c79 289 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 290
wolfSSL 4:1b0d80432c79 291 #if defined(POLY130564)
wolfSSL 4:1b0d80432c79 292
wolfSSL 4:1b0d80432c79 293 /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
wolfSSL 4:1b0d80432c79 294 t0 = U8TO64(key + 0);
wolfSSL 4:1b0d80432c79 295 t1 = U8TO64(key + 8);
wolfSSL 4:1b0d80432c79 296
wolfSSL 4:1b0d80432c79 297 ctx->r[0] = ( t0 ) & 0xffc0fffffff;
wolfSSL 4:1b0d80432c79 298 ctx->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;
wolfSSL 4:1b0d80432c79 299 ctx->r[2] = ((t1 >> 24) ) & 0x00ffffffc0f;
wolfSSL 4:1b0d80432c79 300
wolfSSL 4:1b0d80432c79 301 /* h (accumulator) = 0 */
wolfSSL 4:1b0d80432c79 302 ctx->h[0] = 0;
wolfSSL 4:1b0d80432c79 303 ctx->h[1] = 0;
wolfSSL 4:1b0d80432c79 304 ctx->h[2] = 0;
wolfSSL 4:1b0d80432c79 305
wolfSSL 4:1b0d80432c79 306 /* save pad for later */
wolfSSL 4:1b0d80432c79 307 ctx->pad[0] = U8TO64(key + 16);
wolfSSL 4:1b0d80432c79 308 ctx->pad[1] = U8TO64(key + 24);
wolfSSL 4:1b0d80432c79 309
wolfSSL 4:1b0d80432c79 310 #else /* if not 64 bit then use 32 bit */
wolfSSL 4:1b0d80432c79 311
wolfSSL 4:1b0d80432c79 312 /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
wolfSSL 4:1b0d80432c79 313 ctx->r[0] = (U8TO32(key + 0) ) & 0x3ffffff;
wolfSSL 4:1b0d80432c79 314 ctx->r[1] = (U8TO32(key + 3) >> 2) & 0x3ffff03;
wolfSSL 4:1b0d80432c79 315 ctx->r[2] = (U8TO32(key + 6) >> 4) & 0x3ffc0ff;
wolfSSL 4:1b0d80432c79 316 ctx->r[3] = (U8TO32(key + 9) >> 6) & 0x3f03fff;
wolfSSL 4:1b0d80432c79 317 ctx->r[4] = (U8TO32(key + 12) >> 8) & 0x00fffff;
wolfSSL 4:1b0d80432c79 318
wolfSSL 4:1b0d80432c79 319 /* h = 0 */
wolfSSL 4:1b0d80432c79 320 ctx->h[0] = 0;
wolfSSL 4:1b0d80432c79 321 ctx->h[1] = 0;
wolfSSL 4:1b0d80432c79 322 ctx->h[2] = 0;
wolfSSL 4:1b0d80432c79 323 ctx->h[3] = 0;
wolfSSL 4:1b0d80432c79 324 ctx->h[4] = 0;
wolfSSL 4:1b0d80432c79 325
wolfSSL 4:1b0d80432c79 326 /* save pad for later */
wolfSSL 4:1b0d80432c79 327 ctx->pad[0] = U8TO32(key + 16);
wolfSSL 4:1b0d80432c79 328 ctx->pad[1] = U8TO32(key + 20);
wolfSSL 4:1b0d80432c79 329 ctx->pad[2] = U8TO32(key + 24);
wolfSSL 4:1b0d80432c79 330 ctx->pad[3] = U8TO32(key + 28);
wolfSSL 4:1b0d80432c79 331
wolfSSL 4:1b0d80432c79 332 #endif
wolfSSL 4:1b0d80432c79 333
wolfSSL 4:1b0d80432c79 334 ctx->leftover = 0;
wolfSSL 4:1b0d80432c79 335 ctx->final = 0;
wolfSSL 4:1b0d80432c79 336
wolfSSL 4:1b0d80432c79 337 return 0;
wolfSSL 4:1b0d80432c79 338 }
wolfSSL 4:1b0d80432c79 339
wolfSSL 4:1b0d80432c79 340
wolfSSL 4:1b0d80432c79 341 int wc_Poly1305Final(Poly1305* ctx, byte* mac) {
wolfSSL 4:1b0d80432c79 342
wolfSSL 4:1b0d80432c79 343 #if defined(POLY130564)
wolfSSL 4:1b0d80432c79 344
wolfSSL 4:1b0d80432c79 345 word64 h0,h1,h2,c;
wolfSSL 4:1b0d80432c79 346 word64 g0,g1,g2;
wolfSSL 4:1b0d80432c79 347 word64 t0,t1;
wolfSSL 4:1b0d80432c79 348
wolfSSL 4:1b0d80432c79 349 #else
wolfSSL 4:1b0d80432c79 350
wolfSSL 4:1b0d80432c79 351 word32 h0,h1,h2,h3,h4,c;
wolfSSL 4:1b0d80432c79 352 word32 g0,g1,g2,g3,g4;
wolfSSL 4:1b0d80432c79 353 word64 f;
wolfSSL 4:1b0d80432c79 354 word32 mask;
wolfSSL 4:1b0d80432c79 355
wolfSSL 4:1b0d80432c79 356 #endif
wolfSSL 4:1b0d80432c79 357
wolfSSL 4:1b0d80432c79 358 if (ctx == NULL)
wolfSSL 4:1b0d80432c79 359 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 360
wolfSSL 4:1b0d80432c79 361 #if defined(POLY130564)
wolfSSL 4:1b0d80432c79 362
wolfSSL 4:1b0d80432c79 363 /* process the remaining block */
wolfSSL 4:1b0d80432c79 364 if (ctx->leftover) {
wolfSSL 4:1b0d80432c79 365 size_t i = ctx->leftover;
wolfSSL 4:1b0d80432c79 366 ctx->buffer[i] = 1;
wolfSSL 4:1b0d80432c79 367 for (i = i + 1; i < POLY1305_BLOCK_SIZE; i++)
wolfSSL 4:1b0d80432c79 368 ctx->buffer[i] = 0;
wolfSSL 4:1b0d80432c79 369 ctx->final = 1;
wolfSSL 4:1b0d80432c79 370 poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
wolfSSL 4:1b0d80432c79 371 }
wolfSSL 4:1b0d80432c79 372
wolfSSL 4:1b0d80432c79 373 /* fully carry h */
wolfSSL 4:1b0d80432c79 374 h0 = ctx->h[0];
wolfSSL 4:1b0d80432c79 375 h1 = ctx->h[1];
wolfSSL 4:1b0d80432c79 376 h2 = ctx->h[2];
wolfSSL 4:1b0d80432c79 377
wolfSSL 4:1b0d80432c79 378 c = (h1 >> 44); h1 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 379 h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
wolfSSL 4:1b0d80432c79 380 h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 381 h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 382 h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
wolfSSL 4:1b0d80432c79 383 h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 384 h1 += c;
wolfSSL 4:1b0d80432c79 385
wolfSSL 4:1b0d80432c79 386 /* compute h + -p */
wolfSSL 4:1b0d80432c79 387 g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 388 g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 389 g2 = h2 + c - ((word64)1 << 42);
wolfSSL 4:1b0d80432c79 390
wolfSSL 4:1b0d80432c79 391 /* select h if h < p, or h + -p if h >= p */
wolfSSL 4:1b0d80432c79 392 c = (g2 >> ((sizeof(word64) * 8) - 1)) - 1;
wolfSSL 4:1b0d80432c79 393 g0 &= c;
wolfSSL 4:1b0d80432c79 394 g1 &= c;
wolfSSL 4:1b0d80432c79 395 g2 &= c;
wolfSSL 4:1b0d80432c79 396 c = ~c;
wolfSSL 4:1b0d80432c79 397 h0 = (h0 & c) | g0;
wolfSSL 4:1b0d80432c79 398 h1 = (h1 & c) | g1;
wolfSSL 4:1b0d80432c79 399 h2 = (h2 & c) | g2;
wolfSSL 4:1b0d80432c79 400
wolfSSL 4:1b0d80432c79 401 /* h = (h + pad) */
wolfSSL 4:1b0d80432c79 402 t0 = ctx->pad[0];
wolfSSL 4:1b0d80432c79 403 t1 = ctx->pad[1];
wolfSSL 4:1b0d80432c79 404
wolfSSL 4:1b0d80432c79 405 h0 += (( t0 ) & 0xfffffffffff) ;
wolfSSL 4:1b0d80432c79 406 c = (h0 >> 44); h0 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 407 h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c;
wolfSSL 4:1b0d80432c79 408 c = (h1 >> 44); h1 &= 0xfffffffffff;
wolfSSL 4:1b0d80432c79 409 h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c;
wolfSSL 4:1b0d80432c79 410 h2 &= 0x3ffffffffff;
wolfSSL 4:1b0d80432c79 411
wolfSSL 4:1b0d80432c79 412 /* mac = h % (2^128) */
wolfSSL 4:1b0d80432c79 413 h0 = ((h0 ) | (h1 << 44));
wolfSSL 4:1b0d80432c79 414 h1 = ((h1 >> 20) | (h2 << 24));
wolfSSL 4:1b0d80432c79 415
wolfSSL 4:1b0d80432c79 416 U64TO8(mac + 0, h0);
wolfSSL 4:1b0d80432c79 417 U64TO8(mac + 8, h1);
wolfSSL 4:1b0d80432c79 418
wolfSSL 4:1b0d80432c79 419 /* zero out the state */
wolfSSL 4:1b0d80432c79 420 ctx->h[0] = 0;
wolfSSL 4:1b0d80432c79 421 ctx->h[1] = 0;
wolfSSL 4:1b0d80432c79 422 ctx->h[2] = 0;
wolfSSL 4:1b0d80432c79 423 ctx->r[0] = 0;
wolfSSL 4:1b0d80432c79 424 ctx->r[1] = 0;
wolfSSL 4:1b0d80432c79 425 ctx->r[2] = 0;
wolfSSL 4:1b0d80432c79 426 ctx->pad[0] = 0;
wolfSSL 4:1b0d80432c79 427 ctx->pad[1] = 0;
wolfSSL 4:1b0d80432c79 428
wolfSSL 4:1b0d80432c79 429 #else /* if not 64 bit then use 32 bit */
wolfSSL 4:1b0d80432c79 430
wolfSSL 4:1b0d80432c79 431 /* process the remaining block */
wolfSSL 4:1b0d80432c79 432 if (ctx->leftover) {
wolfSSL 4:1b0d80432c79 433 size_t i = ctx->leftover;
wolfSSL 4:1b0d80432c79 434 ctx->buffer[i++] = 1;
wolfSSL 4:1b0d80432c79 435 for (; i < POLY1305_BLOCK_SIZE; i++)
wolfSSL 4:1b0d80432c79 436 ctx->buffer[i] = 0;
wolfSSL 4:1b0d80432c79 437 ctx->final = 1;
wolfSSL 4:1b0d80432c79 438 poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
wolfSSL 4:1b0d80432c79 439 }
wolfSSL 4:1b0d80432c79 440
wolfSSL 4:1b0d80432c79 441 /* fully carry h */
wolfSSL 4:1b0d80432c79 442 h0 = ctx->h[0];
wolfSSL 4:1b0d80432c79 443 h1 = ctx->h[1];
wolfSSL 4:1b0d80432c79 444 h2 = ctx->h[2];
wolfSSL 4:1b0d80432c79 445 h3 = ctx->h[3];
wolfSSL 4:1b0d80432c79 446 h4 = ctx->h[4];
wolfSSL 4:1b0d80432c79 447
wolfSSL 4:1b0d80432c79 448 c = h1 >> 26; h1 = h1 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 449 h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 450 h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 451 h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 452 h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
wolfSSL 4:1b0d80432c79 453 h1 += c;
wolfSSL 4:1b0d80432c79 454
wolfSSL 4:1b0d80432c79 455 /* compute h + -p */
wolfSSL 4:1b0d80432c79 456 g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
wolfSSL 4:1b0d80432c79 457 g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
wolfSSL 4:1b0d80432c79 458 g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
wolfSSL 4:1b0d80432c79 459 g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
wolfSSL 4:1b0d80432c79 460 g4 = h4 + c - (1 << 26);
wolfSSL 4:1b0d80432c79 461
wolfSSL 4:1b0d80432c79 462 /* select h if h < p, or h + -p if h >= p */
wolfSSL 4:1b0d80432c79 463 mask = (g4 >> ((sizeof(word32) * 8) - 1)) - 1;
wolfSSL 4:1b0d80432c79 464 g0 &= mask;
wolfSSL 4:1b0d80432c79 465 g1 &= mask;
wolfSSL 4:1b0d80432c79 466 g2 &= mask;
wolfSSL 4:1b0d80432c79 467 g3 &= mask;
wolfSSL 4:1b0d80432c79 468 g4 &= mask;
wolfSSL 4:1b0d80432c79 469 mask = ~mask;
wolfSSL 4:1b0d80432c79 470 h0 = (h0 & mask) | g0;
wolfSSL 4:1b0d80432c79 471 h1 = (h1 & mask) | g1;
wolfSSL 4:1b0d80432c79 472 h2 = (h2 & mask) | g2;
wolfSSL 4:1b0d80432c79 473 h3 = (h3 & mask) | g3;
wolfSSL 4:1b0d80432c79 474 h4 = (h4 & mask) | g4;
wolfSSL 4:1b0d80432c79 475
wolfSSL 4:1b0d80432c79 476 /* h = h % (2^128) */
wolfSSL 4:1b0d80432c79 477 h0 = ((h0 ) | (h1 << 26)) & 0xffffffff;
wolfSSL 4:1b0d80432c79 478 h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
wolfSSL 4:1b0d80432c79 479 h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
wolfSSL 4:1b0d80432c79 480 h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
wolfSSL 4:1b0d80432c79 481
wolfSSL 4:1b0d80432c79 482 /* mac = (h + pad) % (2^128) */
wolfSSL 4:1b0d80432c79 483 f = (word64)h0 + ctx->pad[0] ; h0 = (word32)f;
wolfSSL 4:1b0d80432c79 484 f = (word64)h1 + ctx->pad[1] + (f >> 32); h1 = (word32)f;
wolfSSL 4:1b0d80432c79 485 f = (word64)h2 + ctx->pad[2] + (f >> 32); h2 = (word32)f;
wolfSSL 4:1b0d80432c79 486 f = (word64)h3 + ctx->pad[3] + (f >> 32); h3 = (word32)f;
wolfSSL 4:1b0d80432c79 487
wolfSSL 4:1b0d80432c79 488 U32TO8(mac + 0, h0);
wolfSSL 4:1b0d80432c79 489 U32TO8(mac + 4, h1);
wolfSSL 4:1b0d80432c79 490 U32TO8(mac + 8, h2);
wolfSSL 4:1b0d80432c79 491 U32TO8(mac + 12, h3);
wolfSSL 4:1b0d80432c79 492
wolfSSL 4:1b0d80432c79 493 /* zero out the state */
wolfSSL 4:1b0d80432c79 494 ctx->h[0] = 0;
wolfSSL 4:1b0d80432c79 495 ctx->h[1] = 0;
wolfSSL 4:1b0d80432c79 496 ctx->h[2] = 0;
wolfSSL 4:1b0d80432c79 497 ctx->h[3] = 0;
wolfSSL 4:1b0d80432c79 498 ctx->h[4] = 0;
wolfSSL 4:1b0d80432c79 499 ctx->r[0] = 0;
wolfSSL 4:1b0d80432c79 500 ctx->r[1] = 0;
wolfSSL 4:1b0d80432c79 501 ctx->r[2] = 0;
wolfSSL 4:1b0d80432c79 502 ctx->r[3] = 0;
wolfSSL 4:1b0d80432c79 503 ctx->r[4] = 0;
wolfSSL 4:1b0d80432c79 504 ctx->pad[0] = 0;
wolfSSL 4:1b0d80432c79 505 ctx->pad[1] = 0;
wolfSSL 4:1b0d80432c79 506 ctx->pad[2] = 0;
wolfSSL 4:1b0d80432c79 507 ctx->pad[3] = 0;
wolfSSL 4:1b0d80432c79 508
wolfSSL 4:1b0d80432c79 509 #endif
wolfSSL 4:1b0d80432c79 510
wolfSSL 4:1b0d80432c79 511 return 0;
wolfSSL 4:1b0d80432c79 512 }
wolfSSL 4:1b0d80432c79 513
wolfSSL 4:1b0d80432c79 514
wolfSSL 4:1b0d80432c79 515 int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) {
wolfSSL 4:1b0d80432c79 516
wolfSSL 4:1b0d80432c79 517 size_t i;
wolfSSL 4:1b0d80432c79 518
wolfSSL 4:1b0d80432c79 519 #ifdef CHACHA_AEAD_TEST
wolfSSL 4:1b0d80432c79 520 word32 k;
wolfSSL 4:1b0d80432c79 521 printf("Raw input to poly:\n");
wolfSSL 4:1b0d80432c79 522 for (k = 0; k < bytes; k++) {
wolfSSL 4:1b0d80432c79 523 printf("%02x", m[k]);
wolfSSL 4:1b0d80432c79 524 if ((k+1) % 16 == 0)
wolfSSL 4:1b0d80432c79 525 printf("\n");
wolfSSL 4:1b0d80432c79 526 }
wolfSSL 4:1b0d80432c79 527 printf("\n");
wolfSSL 4:1b0d80432c79 528 #endif
wolfSSL 4:1b0d80432c79 529
wolfSSL 4:1b0d80432c79 530 if (ctx == NULL)
wolfSSL 4:1b0d80432c79 531 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 532
wolfSSL 4:1b0d80432c79 533 /* handle leftover */
wolfSSL 4:1b0d80432c79 534 if (ctx->leftover) {
wolfSSL 4:1b0d80432c79 535 size_t want = (POLY1305_BLOCK_SIZE - ctx->leftover);
wolfSSL 4:1b0d80432c79 536 if (want > bytes)
wolfSSL 4:1b0d80432c79 537 want = bytes;
wolfSSL 4:1b0d80432c79 538 for (i = 0; i < want; i++)
wolfSSL 4:1b0d80432c79 539 ctx->buffer[ctx->leftover + i] = m[i];
wolfSSL 4:1b0d80432c79 540 bytes -= (word32)want;
wolfSSL 4:1b0d80432c79 541 m += want;
wolfSSL 4:1b0d80432c79 542 ctx->leftover += want;
wolfSSL 4:1b0d80432c79 543 if (ctx->leftover < POLY1305_BLOCK_SIZE)
wolfSSL 4:1b0d80432c79 544 return 0;
wolfSSL 4:1b0d80432c79 545 poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
wolfSSL 4:1b0d80432c79 546 ctx->leftover = 0;
wolfSSL 4:1b0d80432c79 547 }
wolfSSL 4:1b0d80432c79 548
wolfSSL 4:1b0d80432c79 549 /* process full blocks */
wolfSSL 4:1b0d80432c79 550 if (bytes >= POLY1305_BLOCK_SIZE) {
wolfSSL 4:1b0d80432c79 551 size_t want = (bytes & ~(POLY1305_BLOCK_SIZE - 1));
wolfSSL 4:1b0d80432c79 552 poly1305_blocks(ctx, m, want);
wolfSSL 4:1b0d80432c79 553 m += want;
wolfSSL 4:1b0d80432c79 554 bytes -= (word32)want;
wolfSSL 4:1b0d80432c79 555 }
wolfSSL 4:1b0d80432c79 556
wolfSSL 4:1b0d80432c79 557 /* store leftover */
wolfSSL 4:1b0d80432c79 558 if (bytes) {
wolfSSL 4:1b0d80432c79 559 for (i = 0; i < bytes; i++)
wolfSSL 4:1b0d80432c79 560 ctx->buffer[ctx->leftover + i] = m[i];
wolfSSL 4:1b0d80432c79 561 ctx->leftover += bytes;
wolfSSL 4:1b0d80432c79 562 }
wolfSSL 4:1b0d80432c79 563 return 0;
wolfSSL 4:1b0d80432c79 564 }
wolfSSL 4:1b0d80432c79 565
wolfSSL 4:1b0d80432c79 566
wolfSSL 4:1b0d80432c79 567 /* Takes in an initialized Poly1305 struct that has a key loaded and creates
wolfSSL 4:1b0d80432c79 568 a MAC (tag) using recent TLS AEAD padding scheme.
wolfSSL 4:1b0d80432c79 569 ctx : Initialized Poly1305 struct to use
wolfSSL 4:1b0d80432c79 570 additional : Additional data to use
wolfSSL 4:1b0d80432c79 571 addSz : Size of additional buffer
wolfSSL 4:1b0d80432c79 572 input : Input buffer to create tag from
wolfSSL 4:1b0d80432c79 573 sz : Size of input buffer
wolfSSL 4:1b0d80432c79 574 tag : Buffer to hold created tag
wolfSSL 4:1b0d80432c79 575 tagSz : Size of input tag buffer (must be at least
wolfSSL 4:1b0d80432c79 576 WC_POLY1305_MAC_SZ(16))
wolfSSL 4:1b0d80432c79 577 */
wolfSSL 4:1b0d80432c79 578 int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz,
wolfSSL 4:1b0d80432c79 579 byte* input, word32 sz, byte* tag, word32 tagSz)
wolfSSL 4:1b0d80432c79 580 {
wolfSSL 4:1b0d80432c79 581 int ret;
wolfSSL 4:1b0d80432c79 582 byte padding[WC_POLY1305_PAD_SZ - 1];
wolfSSL 4:1b0d80432c79 583 word32 paddingLen;
wolfSSL 4:1b0d80432c79 584 byte little64[8];
wolfSSL 4:1b0d80432c79 585
wolfSSL 4:1b0d80432c79 586 XMEMSET(padding, 0, sizeof(padding));
wolfSSL 4:1b0d80432c79 587
wolfSSL 4:1b0d80432c79 588 /* sanity check on arguments */
wolfSSL 4:1b0d80432c79 589 if (ctx == NULL || input == NULL || tag == NULL ||
wolfSSL 4:1b0d80432c79 590 tagSz < WC_POLY1305_MAC_SZ) {
wolfSSL 4:1b0d80432c79 591 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 592 }
wolfSSL 4:1b0d80432c79 593
wolfSSL 4:1b0d80432c79 594 if (additional == NULL && addSz > 0) {
wolfSSL 4:1b0d80432c79 595 return BAD_FUNC_ARG;
wolfSSL 4:1b0d80432c79 596 }
wolfSSL 4:1b0d80432c79 597
wolfSSL 4:1b0d80432c79 598 /* additional data plus padding */
wolfSSL 4:1b0d80432c79 599 if ((ret = wc_Poly1305Update(ctx, additional, addSz)) != 0) {
wolfSSL 4:1b0d80432c79 600 return ret;
wolfSSL 4:1b0d80432c79 601 }
wolfSSL 4:1b0d80432c79 602 paddingLen = -addSz & (WC_POLY1305_PAD_SZ - 1);
wolfSSL 4:1b0d80432c79 603 if (paddingLen) {
wolfSSL 4:1b0d80432c79 604 if ((ret = wc_Poly1305Update(ctx, padding, paddingLen)) != 0) {
wolfSSL 4:1b0d80432c79 605 return ret;
wolfSSL 4:1b0d80432c79 606 }
wolfSSL 4:1b0d80432c79 607 }
wolfSSL 4:1b0d80432c79 608
wolfSSL 4:1b0d80432c79 609 /* input plus padding */
wolfSSL 4:1b0d80432c79 610 if ((ret = wc_Poly1305Update(ctx, input, sz)) != 0) {
wolfSSL 4:1b0d80432c79 611 return ret;
wolfSSL 4:1b0d80432c79 612 }
wolfSSL 4:1b0d80432c79 613 paddingLen = -sz & (WC_POLY1305_PAD_SZ - 1);
wolfSSL 4:1b0d80432c79 614 if (paddingLen) {
wolfSSL 4:1b0d80432c79 615 if ((ret = wc_Poly1305Update(ctx, padding, paddingLen)) != 0) {
wolfSSL 4:1b0d80432c79 616 return ret;
wolfSSL 4:1b0d80432c79 617 }
wolfSSL 4:1b0d80432c79 618 }
wolfSSL 4:1b0d80432c79 619
wolfSSL 4:1b0d80432c79 620 /* size of additional data and input as little endian 64 bit types */
wolfSSL 4:1b0d80432c79 621 U32TO64(addSz, little64);
wolfSSL 4:1b0d80432c79 622 ret = wc_Poly1305Update(ctx, little64, sizeof(little64));
wolfSSL 4:1b0d80432c79 623 if (ret)
wolfSSL 4:1b0d80432c79 624 {
wolfSSL 4:1b0d80432c79 625 return ret;
wolfSSL 4:1b0d80432c79 626 }
wolfSSL 4:1b0d80432c79 627
wolfSSL 4:1b0d80432c79 628 U32TO64(sz, little64);
wolfSSL 4:1b0d80432c79 629 ret = wc_Poly1305Update(ctx, little64, sizeof(little64));
wolfSSL 4:1b0d80432c79 630 if (ret)
wolfSSL 4:1b0d80432c79 631 {
wolfSSL 4:1b0d80432c79 632 return ret;
wolfSSL 4:1b0d80432c79 633 }
wolfSSL 4:1b0d80432c79 634
wolfSSL 4:1b0d80432c79 635 /* Finalize the auth tag */
wolfSSL 4:1b0d80432c79 636 ret = wc_Poly1305Final(ctx, tag);
wolfSSL 4:1b0d80432c79 637
wolfSSL 4:1b0d80432c79 638 return ret;
wolfSSL 4:1b0d80432c79 639
wolfSSL 4:1b0d80432c79 640 }
wolfSSL 4:1b0d80432c79 641 #endif /* HAVE_POLY1305 */
wolfSSL 4:1b0d80432c79 642
wolfSSL 4:1b0d80432c79 643