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