wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
wolfcrypt/src/poly1305.c@17:a5f916481144, 2020-06-05 (annotated)
- Committer:
- wolfSSL
- Date:
- Fri Jun 05 00:11:07 2020 +0000
- Revision:
- 17:a5f916481144
- Parent:
- 16:8e0d178b1d1e
wolfSSL 4.4.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 15:117db924cf7c | 1 | /* poly1305.c |
wolfSSL | 15:117db924cf7c | 2 | * |
wolfSSL | 16:8e0d178b1d1e | 3 | * Copyright (C) 2006-2020 wolfSSL Inc. |
wolfSSL | 15:117db924cf7c | 4 | * |
wolfSSL | 15:117db924cf7c | 5 | * This file is part of wolfSSL. |
wolfSSL | 15:117db924cf7c | 6 | * |
wolfSSL | 15:117db924cf7c | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 15:117db924cf7c | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 15:117db924cf7c | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 15:117db924cf7c | 10 | * (at your option) any later version. |
wolfSSL | 15:117db924cf7c | 11 | * |
wolfSSL | 15:117db924cf7c | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 15:117db924cf7c | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 15:117db924cf7c | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 15:117db924cf7c | 15 | * GNU General Public License for more details. |
wolfSSL | 15:117db924cf7c | 16 | * |
wolfSSL | 15:117db924cf7c | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 15:117db924cf7c | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 15:117db924cf7c | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 15:117db924cf7c | 20 | */ |
wolfSSL | 15:117db924cf7c | 21 | |
wolfSSL | 15:117db924cf7c | 22 | /* |
wolfSSL | 15:117db924cf7c | 23 | * Based off the public domain implementations by Andrew Moon |
wolfSSL | 15:117db924cf7c | 24 | * and Daniel J. Bernstein |
wolfSSL | 15:117db924cf7c | 25 | */ |
wolfSSL | 15:117db924cf7c | 26 | |
wolfSSL | 16:8e0d178b1d1e | 27 | |
wolfSSL | 15:117db924cf7c | 28 | #ifdef HAVE_CONFIG_H |
wolfSSL | 15:117db924cf7c | 29 | #include <config.h> |
wolfSSL | 15:117db924cf7c | 30 | #endif |
wolfSSL | 15:117db924cf7c | 31 | |
wolfSSL | 15:117db924cf7c | 32 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 15:117db924cf7c | 33 | |
wolfSSL | 15:117db924cf7c | 34 | #ifdef HAVE_POLY1305 |
wolfSSL | 15:117db924cf7c | 35 | #include <wolfssl/wolfcrypt/poly1305.h> |
wolfSSL | 15:117db924cf7c | 36 | #include <wolfssl/wolfcrypt/error-crypt.h> |
wolfSSL | 15:117db924cf7c | 37 | #include <wolfssl/wolfcrypt/logging.h> |
wolfSSL | 15:117db924cf7c | 38 | #include <wolfssl/wolfcrypt/cpuid.h> |
wolfSSL | 15:117db924cf7c | 39 | #ifdef NO_INLINE |
wolfSSL | 15:117db924cf7c | 40 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 15:117db924cf7c | 41 | #else |
wolfSSL | 15:117db924cf7c | 42 | #define WOLFSSL_MISC_INCLUDED |
wolfSSL | 15:117db924cf7c | 43 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 15:117db924cf7c | 44 | #endif |
wolfSSL | 15:117db924cf7c | 45 | #ifdef CHACHA_AEAD_TEST |
wolfSSL | 15:117db924cf7c | 46 | #include <stdio.h> |
wolfSSL | 15:117db924cf7c | 47 | #endif |
wolfSSL | 15:117db924cf7c | 48 | |
wolfSSL | 15:117db924cf7c | 49 | #ifdef _MSC_VER |
wolfSSL | 15:117db924cf7c | 50 | /* 4127 warning constant while(1) */ |
wolfSSL | 15:117db924cf7c | 51 | #pragma warning(disable: 4127) |
wolfSSL | 15:117db924cf7c | 52 | #endif |
wolfSSL | 15:117db924cf7c | 53 | |
wolfSSL | 15:117db924cf7c | 54 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 55 | #include <emmintrin.h> |
wolfSSL | 15:117db924cf7c | 56 | #include <immintrin.h> |
wolfSSL | 15:117db924cf7c | 57 | |
wolfSSL | 15:117db924cf7c | 58 | #if defined(__GNUC__) && ((__GNUC__ < 4) || \ |
wolfSSL | 15:117db924cf7c | 59 | (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)) |
wolfSSL | 16:8e0d178b1d1e | 60 | #undef NO_AVX2_SUPPORT |
wolfSSL | 15:117db924cf7c | 61 | #define NO_AVX2_SUPPORT |
wolfSSL | 15:117db924cf7c | 62 | #endif |
wolfSSL | 15:117db924cf7c | 63 | #if defined(__clang__) && ((__clang_major__ < 3) || \ |
wolfSSL | 15:117db924cf7c | 64 | (__clang_major__ == 3 && __clang_minor__ <= 5)) |
wolfSSL | 15:117db924cf7c | 65 | #define NO_AVX2_SUPPORT |
wolfSSL | 15:117db924cf7c | 66 | #elif defined(__clang__) && defined(NO_AVX2_SUPPORT) |
wolfSSL | 15:117db924cf7c | 67 | #undef NO_AVX2_SUPPORT |
wolfSSL | 15:117db924cf7c | 68 | #endif |
wolfSSL | 15:117db924cf7c | 69 | |
wolfSSL | 15:117db924cf7c | 70 | #define HAVE_INTEL_AVX1 |
wolfSSL | 15:117db924cf7c | 71 | #ifndef NO_AVX2_SUPPORT |
wolfSSL | 15:117db924cf7c | 72 | #define HAVE_INTEL_AVX2 |
wolfSSL | 15:117db924cf7c | 73 | #endif |
wolfSSL | 15:117db924cf7c | 74 | #endif |
wolfSSL | 15:117db924cf7c | 75 | |
wolfSSL | 15:117db924cf7c | 76 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 77 | static word32 intel_flags = 0; |
wolfSSL | 15:117db924cf7c | 78 | static word32 cpu_flags_set = 0; |
wolfSSL | 15:117db924cf7c | 79 | #endif |
wolfSSL | 15:117db924cf7c | 80 | |
wolfSSL | 15:117db924cf7c | 81 | #if defined(USE_INTEL_SPEEDUP) || defined(POLY130564) |
wolfSSL | 15:117db924cf7c | 82 | #if defined(_MSC_VER) |
wolfSSL | 15:117db924cf7c | 83 | #define POLY1305_NOINLINE __declspec(noinline) |
wolfSSL | 15:117db924cf7c | 84 | #elif defined(__GNUC__) |
wolfSSL | 15:117db924cf7c | 85 | #define POLY1305_NOINLINE __attribute__((noinline)) |
wolfSSL | 15:117db924cf7c | 86 | #else |
wolfSSL | 15:117db924cf7c | 87 | #define POLY1305_NOINLINE |
wolfSSL | 15:117db924cf7c | 88 | #endif |
wolfSSL | 15:117db924cf7c | 89 | |
wolfSSL | 15:117db924cf7c | 90 | #if defined(_MSC_VER) |
wolfSSL | 15:117db924cf7c | 91 | #include <intrin.h> |
wolfSSL | 15:117db924cf7c | 92 | |
wolfSSL | 15:117db924cf7c | 93 | typedef struct word128 { |
wolfSSL | 15:117db924cf7c | 94 | word64 lo; |
wolfSSL | 15:117db924cf7c | 95 | word64 hi; |
wolfSSL | 15:117db924cf7c | 96 | } word128; |
wolfSSL | 15:117db924cf7c | 97 | |
wolfSSL | 15:117db924cf7c | 98 | #define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi) |
wolfSSL | 15:117db924cf7c | 99 | #define ADD(out, in) { word64 t = out.lo; out.lo += in.lo; \ |
wolfSSL | 15:117db924cf7c | 100 | out.hi += (out.lo < t) + in.hi; } |
wolfSSL | 15:117db924cf7c | 101 | #define ADDLO(out, in) { word64 t = out.lo; out.lo += in; \ |
wolfSSL | 15:117db924cf7c | 102 | out.hi += (out.lo < t); } |
wolfSSL | 15:117db924cf7c | 103 | #define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift))) |
wolfSSL | 15:117db924cf7c | 104 | #define LO(in) (in.lo) |
wolfSSL | 15:117db924cf7c | 105 | |
wolfSSL | 15:117db924cf7c | 106 | #elif defined(__GNUC__) |
wolfSSL | 15:117db924cf7c | 107 | #if defined(__SIZEOF_INT128__) |
wolfSSL | 15:117db924cf7c | 108 | typedef unsigned __int128 word128; |
wolfSSL | 15:117db924cf7c | 109 | #else |
wolfSSL | 15:117db924cf7c | 110 | typedef unsigned word128 __attribute__((mode(TI))); |
wolfSSL | 15:117db924cf7c | 111 | #endif |
wolfSSL | 15:117db924cf7c | 112 | |
wolfSSL | 15:117db924cf7c | 113 | #define MUL(out, x, y) out = ((word128)x * y) |
wolfSSL | 15:117db924cf7c | 114 | #define ADD(out, in) out += in |
wolfSSL | 15:117db924cf7c | 115 | #define ADDLO(out, in) out += in |
wolfSSL | 15:117db924cf7c | 116 | #define SHR(in, shift) (word64)(in >> (shift)) |
wolfSSL | 15:117db924cf7c | 117 | #define LO(in) (word64)(in) |
wolfSSL | 15:117db924cf7c | 118 | #endif |
wolfSSL | 15:117db924cf7c | 119 | #endif |
wolfSSL | 15:117db924cf7c | 120 | |
wolfSSL | 15:117db924cf7c | 121 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 16:8e0d178b1d1e | 122 | #ifdef __cplusplus |
wolfSSL | 16:8e0d178b1d1e | 123 | extern "C" { |
wolfSSL | 16:8e0d178b1d1e | 124 | #endif |
wolfSSL | 16:8e0d178b1d1e | 125 | |
wolfSSL | 15:117db924cf7c | 126 | #ifdef HAVE_INTEL_AVX1 |
wolfSSL | 15:117db924cf7c | 127 | /* Process one block (16 bytes) of data. |
wolfSSL | 15:117db924cf7c | 128 | * |
wolfSSL | 15:117db924cf7c | 129 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 130 | * m One block of message data. |
wolfSSL | 15:117db924cf7c | 131 | */ |
wolfSSL | 16:8e0d178b1d1e | 132 | extern void poly1305_block_avx(Poly1305* ctx, const unsigned char *m); |
wolfSSL | 15:117db924cf7c | 133 | /* Process multiple blocks (n * 16 bytes) of data. |
wolfSSL | 15:117db924cf7c | 134 | * |
wolfSSL | 15:117db924cf7c | 135 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 136 | * m Blocks of message data. |
wolfSSL | 15:117db924cf7c | 137 | * bytes The number of bytes to process. |
wolfSSL | 15:117db924cf7c | 138 | */ |
wolfSSL | 16:8e0d178b1d1e | 139 | extern void poly1305_blocks_avx(Poly1305* ctx, const unsigned char* m, |
wolfSSL | 16:8e0d178b1d1e | 140 | size_t bytes); |
wolfSSL | 15:117db924cf7c | 141 | /* Set the key to use when processing data. |
wolfSSL | 15:117db924cf7c | 142 | * Initialize the context. |
wolfSSL | 15:117db924cf7c | 143 | * |
wolfSSL | 15:117db924cf7c | 144 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 145 | * key The key data (16 bytes). |
wolfSSL | 15:117db924cf7c | 146 | */ |
wolfSSL | 16:8e0d178b1d1e | 147 | extern void poly1305_setkey_avx(Poly1305* ctx, const byte* key); |
wolfSSL | 15:117db924cf7c | 148 | /* Calculate the final result - authentication data. |
wolfSSL | 15:117db924cf7c | 149 | * Zeros out the private data in the context. |
wolfSSL | 15:117db924cf7c | 150 | * |
wolfSSL | 15:117db924cf7c | 151 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 152 | * mac Buffer to hold 16 bytes. |
wolfSSL | 15:117db924cf7c | 153 | */ |
wolfSSL | 16:8e0d178b1d1e | 154 | extern void poly1305_final_avx(Poly1305* ctx, byte* mac); |
wolfSSL | 15:117db924cf7c | 155 | #endif |
wolfSSL | 15:117db924cf7c | 156 | |
wolfSSL | 15:117db924cf7c | 157 | #ifdef HAVE_INTEL_AVX2 |
wolfSSL | 15:117db924cf7c | 158 | /* Process multiple blocks (n * 16 bytes) of data. |
wolfSSL | 15:117db924cf7c | 159 | * |
wolfSSL | 15:117db924cf7c | 160 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 161 | * m Blocks of message data. |
wolfSSL | 15:117db924cf7c | 162 | * bytes The number of bytes to process. |
wolfSSL | 15:117db924cf7c | 163 | */ |
wolfSSL | 16:8e0d178b1d1e | 164 | extern void poly1305_blocks_avx2(Poly1305* ctx, const unsigned char* m, |
wolfSSL | 16:8e0d178b1d1e | 165 | size_t bytes); |
wolfSSL | 15:117db924cf7c | 166 | /* Calculate R^1, R^2, R^3 and R^4 and store them in the context. |
wolfSSL | 15:117db924cf7c | 167 | * |
wolfSSL | 15:117db924cf7c | 168 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 169 | */ |
wolfSSL | 16:8e0d178b1d1e | 170 | extern void poly1305_calc_powers_avx2(Poly1305* ctx); |
wolfSSL | 15:117db924cf7c | 171 | /* Set the key to use when processing data. |
wolfSSL | 15:117db924cf7c | 172 | * Initialize the context. |
wolfSSL | 15:117db924cf7c | 173 | * Calls AVX set key function as final function calls AVX code. |
wolfSSL | 15:117db924cf7c | 174 | * |
wolfSSL | 15:117db924cf7c | 175 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 176 | * key The key data (16 bytes). |
wolfSSL | 15:117db924cf7c | 177 | */ |
wolfSSL | 16:8e0d178b1d1e | 178 | extern void poly1305_setkey_avx2(Poly1305* ctx, const byte* key); |
wolfSSL | 15:117db924cf7c | 179 | /* Calculate the final result - authentication data. |
wolfSSL | 15:117db924cf7c | 180 | * Zeros out the private data in the context. |
wolfSSL | 15:117db924cf7c | 181 | * Calls AVX final function to quickly process last blocks. |
wolfSSL | 15:117db924cf7c | 182 | * |
wolfSSL | 15:117db924cf7c | 183 | * ctx Poly1305 context. |
wolfSSL | 15:117db924cf7c | 184 | * mac Buffer to hold 16 bytes - authentication data. |
wolfSSL | 15:117db924cf7c | 185 | */ |
wolfSSL | 16:8e0d178b1d1e | 186 | extern void poly1305_final_avx2(Poly1305* ctx, byte* mac); |
wolfSSL | 16:8e0d178b1d1e | 187 | #endif |
wolfSSL | 15:117db924cf7c | 188 | |
wolfSSL | 16:8e0d178b1d1e | 189 | #ifdef __cplusplus |
wolfSSL | 16:8e0d178b1d1e | 190 | } /* extern "C" */ |
wolfSSL | 15:117db924cf7c | 191 | #endif |
wolfSSL | 15:117db924cf7c | 192 | |
wolfSSL | 15:117db924cf7c | 193 | #elif defined(POLY130564) |
wolfSSL | 16:8e0d178b1d1e | 194 | #ifndef WOLFSSL_ARMASM |
wolfSSL | 15:117db924cf7c | 195 | static word64 U8TO64(const byte* p) |
wolfSSL | 15:117db924cf7c | 196 | { |
wolfSSL | 15:117db924cf7c | 197 | return |
wolfSSL | 15:117db924cf7c | 198 | (((word64)(p[0] & 0xff) ) | |
wolfSSL | 15:117db924cf7c | 199 | ((word64)(p[1] & 0xff) << 8) | |
wolfSSL | 15:117db924cf7c | 200 | ((word64)(p[2] & 0xff) << 16) | |
wolfSSL | 15:117db924cf7c | 201 | ((word64)(p[3] & 0xff) << 24) | |
wolfSSL | 15:117db924cf7c | 202 | ((word64)(p[4] & 0xff) << 32) | |
wolfSSL | 15:117db924cf7c | 203 | ((word64)(p[5] & 0xff) << 40) | |
wolfSSL | 15:117db924cf7c | 204 | ((word64)(p[6] & 0xff) << 48) | |
wolfSSL | 15:117db924cf7c | 205 | ((word64)(p[7] & 0xff) << 56)); |
wolfSSL | 15:117db924cf7c | 206 | } |
wolfSSL | 15:117db924cf7c | 207 | |
wolfSSL | 15:117db924cf7c | 208 | static void U64TO8(byte* p, word64 v) { |
wolfSSL | 15:117db924cf7c | 209 | p[0] = (v ) & 0xff; |
wolfSSL | 15:117db924cf7c | 210 | p[1] = (v >> 8) & 0xff; |
wolfSSL | 15:117db924cf7c | 211 | p[2] = (v >> 16) & 0xff; |
wolfSSL | 15:117db924cf7c | 212 | p[3] = (v >> 24) & 0xff; |
wolfSSL | 15:117db924cf7c | 213 | p[4] = (v >> 32) & 0xff; |
wolfSSL | 15:117db924cf7c | 214 | p[5] = (v >> 40) & 0xff; |
wolfSSL | 15:117db924cf7c | 215 | p[6] = (v >> 48) & 0xff; |
wolfSSL | 15:117db924cf7c | 216 | p[7] = (v >> 56) & 0xff; |
wolfSSL | 15:117db924cf7c | 217 | } |
wolfSSL | 16:8e0d178b1d1e | 218 | #endif/* WOLFSSL_ARMASM */ |
wolfSSL | 15:117db924cf7c | 219 | #else /* if not 64 bit then use 32 bit */ |
wolfSSL | 15:117db924cf7c | 220 | |
wolfSSL | 15:117db924cf7c | 221 | static word32 U8TO32(const byte *p) |
wolfSSL | 15:117db924cf7c | 222 | { |
wolfSSL | 15:117db924cf7c | 223 | return |
wolfSSL | 15:117db924cf7c | 224 | (((word32)(p[0] & 0xff) ) | |
wolfSSL | 15:117db924cf7c | 225 | ((word32)(p[1] & 0xff) << 8) | |
wolfSSL | 15:117db924cf7c | 226 | ((word32)(p[2] & 0xff) << 16) | |
wolfSSL | 15:117db924cf7c | 227 | ((word32)(p[3] & 0xff) << 24)); |
wolfSSL | 15:117db924cf7c | 228 | } |
wolfSSL | 15:117db924cf7c | 229 | |
wolfSSL | 15:117db924cf7c | 230 | static void U32TO8(byte *p, word32 v) { |
wolfSSL | 15:117db924cf7c | 231 | p[0] = (v ) & 0xff; |
wolfSSL | 15:117db924cf7c | 232 | p[1] = (v >> 8) & 0xff; |
wolfSSL | 15:117db924cf7c | 233 | p[2] = (v >> 16) & 0xff; |
wolfSSL | 15:117db924cf7c | 234 | p[3] = (v >> 24) & 0xff; |
wolfSSL | 15:117db924cf7c | 235 | } |
wolfSSL | 15:117db924cf7c | 236 | #endif |
wolfSSL | 15:117db924cf7c | 237 | |
wolfSSL | 16:8e0d178b1d1e | 238 | /* convert 32-bit unsigned to little endian 64 bit type as byte array */ |
wolfSSL | 16:8e0d178b1d1e | 239 | static WC_INLINE void u32tole64(const word32 inLe32, byte outLe64[8]) |
wolfSSL | 15:117db924cf7c | 240 | { |
wolfSSL | 16:8e0d178b1d1e | 241 | #ifndef WOLFSSL_X86_64_BUILD |
wolfSSL | 16:8e0d178b1d1e | 242 | outLe64[0] = (byte)(inLe32 & 0x000000FF); |
wolfSSL | 16:8e0d178b1d1e | 243 | outLe64[1] = (byte)((inLe32 & 0x0000FF00) >> 8); |
wolfSSL | 16:8e0d178b1d1e | 244 | outLe64[2] = (byte)((inLe32 & 0x00FF0000) >> 16); |
wolfSSL | 16:8e0d178b1d1e | 245 | outLe64[3] = (byte)((inLe32 & 0xFF000000) >> 24); |
wolfSSL | 16:8e0d178b1d1e | 246 | outLe64[4] = 0; |
wolfSSL | 16:8e0d178b1d1e | 247 | outLe64[5] = 0; |
wolfSSL | 16:8e0d178b1d1e | 248 | outLe64[6] = 0; |
wolfSSL | 16:8e0d178b1d1e | 249 | outLe64[7] = 0; |
wolfSSL | 16:8e0d178b1d1e | 250 | #else |
wolfSSL | 16:8e0d178b1d1e | 251 | *(word64*)outLe64 = inLe32; |
wolfSSL | 16:8e0d178b1d1e | 252 | #endif |
wolfSSL | 15:117db924cf7c | 253 | } |
wolfSSL | 15:117db924cf7c | 254 | |
wolfSSL | 16:8e0d178b1d1e | 255 | |
wolfSSL | 16:8e0d178b1d1e | 256 | #if !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) |
wolfSSL | 16:8e0d178b1d1e | 257 | void poly1305_blocks(Poly1305* ctx, const unsigned char *m, |
wolfSSL | 16:8e0d178b1d1e | 258 | size_t bytes) |
wolfSSL | 15:117db924cf7c | 259 | { |
wolfSSL | 15:117db924cf7c | 260 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 261 | /* AVX2 is handled in wc_Poly1305Update. */ |
wolfSSL | 15:117db924cf7c | 262 | poly1305_blocks_avx(ctx, m, bytes); |
wolfSSL | 15:117db924cf7c | 263 | #elif defined(POLY130564) |
wolfSSL | 15:117db924cf7c | 264 | const word64 hibit = (ctx->finished) ? 0 : ((word64)1 << 40); /* 1 << 128 */ |
wolfSSL | 15:117db924cf7c | 265 | word64 r0,r1,r2; |
wolfSSL | 15:117db924cf7c | 266 | word64 s1,s2; |
wolfSSL | 15:117db924cf7c | 267 | word64 h0,h1,h2; |
wolfSSL | 15:117db924cf7c | 268 | word64 c; |
wolfSSL | 15:117db924cf7c | 269 | word128 d0,d1,d2,d; |
wolfSSL | 15:117db924cf7c | 270 | |
wolfSSL | 15:117db924cf7c | 271 | r0 = ctx->r[0]; |
wolfSSL | 15:117db924cf7c | 272 | r1 = ctx->r[1]; |
wolfSSL | 15:117db924cf7c | 273 | r2 = ctx->r[2]; |
wolfSSL | 15:117db924cf7c | 274 | |
wolfSSL | 15:117db924cf7c | 275 | h0 = ctx->h[0]; |
wolfSSL | 15:117db924cf7c | 276 | h1 = ctx->h[1]; |
wolfSSL | 15:117db924cf7c | 277 | h2 = ctx->h[2]; |
wolfSSL | 15:117db924cf7c | 278 | |
wolfSSL | 15:117db924cf7c | 279 | s1 = r1 * (5 << 2); |
wolfSSL | 15:117db924cf7c | 280 | s2 = r2 * (5 << 2); |
wolfSSL | 15:117db924cf7c | 281 | |
wolfSSL | 15:117db924cf7c | 282 | while (bytes >= POLY1305_BLOCK_SIZE) { |
wolfSSL | 15:117db924cf7c | 283 | word64 t0,t1; |
wolfSSL | 15:117db924cf7c | 284 | |
wolfSSL | 15:117db924cf7c | 285 | /* h += m[i] */ |
wolfSSL | 15:117db924cf7c | 286 | t0 = U8TO64(&m[0]); |
wolfSSL | 15:117db924cf7c | 287 | t1 = U8TO64(&m[8]); |
wolfSSL | 15:117db924cf7c | 288 | |
wolfSSL | 15:117db924cf7c | 289 | h0 += (( t0 ) & 0xfffffffffff); |
wolfSSL | 15:117db924cf7c | 290 | h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff); |
wolfSSL | 15:117db924cf7c | 291 | h2 += (((t1 >> 24) ) & 0x3ffffffffff) | hibit; |
wolfSSL | 15:117db924cf7c | 292 | |
wolfSSL | 15:117db924cf7c | 293 | /* h *= r */ |
wolfSSL | 15:117db924cf7c | 294 | MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d); |
wolfSSL | 15:117db924cf7c | 295 | MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d); |
wolfSSL | 15:117db924cf7c | 296 | MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d); |
wolfSSL | 15:117db924cf7c | 297 | |
wolfSSL | 15:117db924cf7c | 298 | /* (partial) h %= p */ |
wolfSSL | 15:117db924cf7c | 299 | c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 300 | ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 301 | ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff; |
wolfSSL | 15:117db924cf7c | 302 | h0 += c * 5; c = (h0 >> 44); h0 = h0 & 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 303 | h1 += c; |
wolfSSL | 15:117db924cf7c | 304 | |
wolfSSL | 15:117db924cf7c | 305 | m += POLY1305_BLOCK_SIZE; |
wolfSSL | 15:117db924cf7c | 306 | bytes -= POLY1305_BLOCK_SIZE; |
wolfSSL | 15:117db924cf7c | 307 | } |
wolfSSL | 15:117db924cf7c | 308 | |
wolfSSL | 15:117db924cf7c | 309 | ctx->h[0] = h0; |
wolfSSL | 15:117db924cf7c | 310 | ctx->h[1] = h1; |
wolfSSL | 15:117db924cf7c | 311 | ctx->h[2] = h2; |
wolfSSL | 15:117db924cf7c | 312 | |
wolfSSL | 15:117db924cf7c | 313 | #else /* if not 64 bit then use 32 bit */ |
wolfSSL | 16:8e0d178b1d1e | 314 | const word32 hibit = (ctx->finished) ? 0 : ((word32)1 << 24); /* 1 << 128 */ |
wolfSSL | 15:117db924cf7c | 315 | word32 r0,r1,r2,r3,r4; |
wolfSSL | 15:117db924cf7c | 316 | word32 s1,s2,s3,s4; |
wolfSSL | 15:117db924cf7c | 317 | word32 h0,h1,h2,h3,h4; |
wolfSSL | 15:117db924cf7c | 318 | word64 d0,d1,d2,d3,d4; |
wolfSSL | 15:117db924cf7c | 319 | word32 c; |
wolfSSL | 15:117db924cf7c | 320 | |
wolfSSL | 15:117db924cf7c | 321 | |
wolfSSL | 15:117db924cf7c | 322 | r0 = ctx->r[0]; |
wolfSSL | 15:117db924cf7c | 323 | r1 = ctx->r[1]; |
wolfSSL | 15:117db924cf7c | 324 | r2 = ctx->r[2]; |
wolfSSL | 15:117db924cf7c | 325 | r3 = ctx->r[3]; |
wolfSSL | 15:117db924cf7c | 326 | r4 = ctx->r[4]; |
wolfSSL | 15:117db924cf7c | 327 | |
wolfSSL | 15:117db924cf7c | 328 | s1 = r1 * 5; |
wolfSSL | 15:117db924cf7c | 329 | s2 = r2 * 5; |
wolfSSL | 15:117db924cf7c | 330 | s3 = r3 * 5; |
wolfSSL | 15:117db924cf7c | 331 | s4 = r4 * 5; |
wolfSSL | 15:117db924cf7c | 332 | |
wolfSSL | 15:117db924cf7c | 333 | h0 = ctx->h[0]; |
wolfSSL | 15:117db924cf7c | 334 | h1 = ctx->h[1]; |
wolfSSL | 15:117db924cf7c | 335 | h2 = ctx->h[2]; |
wolfSSL | 15:117db924cf7c | 336 | h3 = ctx->h[3]; |
wolfSSL | 15:117db924cf7c | 337 | h4 = ctx->h[4]; |
wolfSSL | 15:117db924cf7c | 338 | |
wolfSSL | 15:117db924cf7c | 339 | while (bytes >= POLY1305_BLOCK_SIZE) { |
wolfSSL | 15:117db924cf7c | 340 | /* h += m[i] */ |
wolfSSL | 15:117db924cf7c | 341 | h0 += (U8TO32(m+ 0) ) & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 342 | h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 343 | h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 344 | h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 345 | h4 += (U8TO32(m+12) >> 8) | hibit; |
wolfSSL | 15:117db924cf7c | 346 | |
wolfSSL | 15:117db924cf7c | 347 | /* h *= r */ |
wolfSSL | 15:117db924cf7c | 348 | d0 = ((word64)h0 * r0) + ((word64)h1 * s4) + ((word64)h2 * s3) + |
wolfSSL | 15:117db924cf7c | 349 | ((word64)h3 * s2) + ((word64)h4 * s1); |
wolfSSL | 15:117db924cf7c | 350 | d1 = ((word64)h0 * r1) + ((word64)h1 * r0) + ((word64)h2 * s4) + |
wolfSSL | 15:117db924cf7c | 351 | ((word64)h3 * s3) + ((word64)h4 * s2); |
wolfSSL | 15:117db924cf7c | 352 | d2 = ((word64)h0 * r2) + ((word64)h1 * r1) + ((word64)h2 * r0) + |
wolfSSL | 15:117db924cf7c | 353 | ((word64)h3 * s4) + ((word64)h4 * s3); |
wolfSSL | 15:117db924cf7c | 354 | d3 = ((word64)h0 * r3) + ((word64)h1 * r2) + ((word64)h2 * r1) + |
wolfSSL | 15:117db924cf7c | 355 | ((word64)h3 * r0) + ((word64)h4 * s4); |
wolfSSL | 15:117db924cf7c | 356 | d4 = ((word64)h0 * r4) + ((word64)h1 * r3) + ((word64)h2 * r2) + |
wolfSSL | 15:117db924cf7c | 357 | ((word64)h3 * r1) + ((word64)h4 * r0); |
wolfSSL | 15:117db924cf7c | 358 | |
wolfSSL | 15:117db924cf7c | 359 | /* (partial) h %= p */ |
wolfSSL | 15:117db924cf7c | 360 | c = (word32)(d0 >> 26); h0 = (word32)d0 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 361 | d1 += c; c = (word32)(d1 >> 26); h1 = (word32)d1 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 362 | d2 += c; c = (word32)(d2 >> 26); h2 = (word32)d2 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 363 | d3 += c; c = (word32)(d3 >> 26); h3 = (word32)d3 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 364 | d4 += c; c = (word32)(d4 >> 26); h4 = (word32)d4 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 365 | h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 366 | h1 += c; |
wolfSSL | 15:117db924cf7c | 367 | |
wolfSSL | 15:117db924cf7c | 368 | m += POLY1305_BLOCK_SIZE; |
wolfSSL | 15:117db924cf7c | 369 | bytes -= POLY1305_BLOCK_SIZE; |
wolfSSL | 15:117db924cf7c | 370 | } |
wolfSSL | 15:117db924cf7c | 371 | |
wolfSSL | 15:117db924cf7c | 372 | ctx->h[0] = h0; |
wolfSSL | 15:117db924cf7c | 373 | ctx->h[1] = h1; |
wolfSSL | 15:117db924cf7c | 374 | ctx->h[2] = h2; |
wolfSSL | 15:117db924cf7c | 375 | ctx->h[3] = h3; |
wolfSSL | 15:117db924cf7c | 376 | ctx->h[4] = h4; |
wolfSSL | 15:117db924cf7c | 377 | |
wolfSSL | 15:117db924cf7c | 378 | #endif /* end of 64 bit cpu blocks or 32 bit cpu */ |
wolfSSL | 15:117db924cf7c | 379 | } |
wolfSSL | 15:117db924cf7c | 380 | |
wolfSSL | 16:8e0d178b1d1e | 381 | void poly1305_block(Poly1305* ctx, const unsigned char *m) |
wolfSSL | 15:117db924cf7c | 382 | { |
wolfSSL | 15:117db924cf7c | 383 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 384 | /* No call to poly1305_block when AVX2, AVX2 does 4 blocks at a time. */ |
wolfSSL | 15:117db924cf7c | 385 | poly1305_block_avx(ctx, m); |
wolfSSL | 15:117db924cf7c | 386 | #else |
wolfSSL | 15:117db924cf7c | 387 | poly1305_blocks(ctx, m, POLY1305_BLOCK_SIZE); |
wolfSSL | 15:117db924cf7c | 388 | #endif |
wolfSSL | 15:117db924cf7c | 389 | } |
wolfSSL | 16:8e0d178b1d1e | 390 | #endif /* !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) */ |
wolfSSL | 15:117db924cf7c | 391 | |
wolfSSL | 16:8e0d178b1d1e | 392 | #if !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) |
wolfSSL | 15:117db924cf7c | 393 | int wc_Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz) |
wolfSSL | 15:117db924cf7c | 394 | { |
wolfSSL | 16:8e0d178b1d1e | 395 | #if defined(POLY130564) && !defined(USE_INTEL_SPEEDUP) |
wolfSSL | 15:117db924cf7c | 396 | word64 t0,t1; |
wolfSSL | 15:117db924cf7c | 397 | #endif |
wolfSSL | 15:117db924cf7c | 398 | |
wolfSSL | 15:117db924cf7c | 399 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 400 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 401 | |
wolfSSL | 15:117db924cf7c | 402 | #ifdef CHACHA_AEAD_TEST |
wolfSSL | 15:117db924cf7c | 403 | word32 k; |
wolfSSL | 15:117db924cf7c | 404 | printf("Poly key used:\n"); |
wolfSSL | 15:117db924cf7c | 405 | for (k = 0; k < keySz; k++) { |
wolfSSL | 15:117db924cf7c | 406 | printf("%02x", key[k]); |
wolfSSL | 15:117db924cf7c | 407 | if ((k+1) % 8 == 0) |
wolfSSL | 15:117db924cf7c | 408 | printf("\n"); |
wolfSSL | 15:117db924cf7c | 409 | } |
wolfSSL | 15:117db924cf7c | 410 | printf("\n"); |
wolfSSL | 15:117db924cf7c | 411 | #endif |
wolfSSL | 15:117db924cf7c | 412 | |
wolfSSL | 15:117db924cf7c | 413 | if (keySz != 32 || ctx == NULL) |
wolfSSL | 15:117db924cf7c | 414 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 415 | |
wolfSSL | 15:117db924cf7c | 416 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 417 | if (!cpu_flags_set) { |
wolfSSL | 15:117db924cf7c | 418 | intel_flags = cpuid_get_flags(); |
wolfSSL | 15:117db924cf7c | 419 | cpu_flags_set = 1; |
wolfSSL | 15:117db924cf7c | 420 | } |
wolfSSL | 15:117db924cf7c | 421 | #ifdef HAVE_INTEL_AVX2 |
wolfSSL | 15:117db924cf7c | 422 | if (IS_INTEL_AVX2(intel_flags)) |
wolfSSL | 15:117db924cf7c | 423 | poly1305_setkey_avx2(ctx, key); |
wolfSSL | 15:117db924cf7c | 424 | else |
wolfSSL | 15:117db924cf7c | 425 | #endif |
wolfSSL | 15:117db924cf7c | 426 | poly1305_setkey_avx(ctx, key); |
wolfSSL | 15:117db924cf7c | 427 | #elif defined(POLY130564) |
wolfSSL | 15:117db924cf7c | 428 | |
wolfSSL | 15:117db924cf7c | 429 | /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ |
wolfSSL | 15:117db924cf7c | 430 | t0 = U8TO64(key + 0); |
wolfSSL | 15:117db924cf7c | 431 | t1 = U8TO64(key + 8); |
wolfSSL | 15:117db924cf7c | 432 | |
wolfSSL | 15:117db924cf7c | 433 | ctx->r[0] = ( t0 ) & 0xffc0fffffff; |
wolfSSL | 15:117db924cf7c | 434 | ctx->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff; |
wolfSSL | 15:117db924cf7c | 435 | ctx->r[2] = ((t1 >> 24) ) & 0x00ffffffc0f; |
wolfSSL | 15:117db924cf7c | 436 | |
wolfSSL | 15:117db924cf7c | 437 | /* h (accumulator) = 0 */ |
wolfSSL | 15:117db924cf7c | 438 | ctx->h[0] = 0; |
wolfSSL | 15:117db924cf7c | 439 | ctx->h[1] = 0; |
wolfSSL | 15:117db924cf7c | 440 | ctx->h[2] = 0; |
wolfSSL | 15:117db924cf7c | 441 | |
wolfSSL | 15:117db924cf7c | 442 | /* save pad for later */ |
wolfSSL | 15:117db924cf7c | 443 | ctx->pad[0] = U8TO64(key + 16); |
wolfSSL | 15:117db924cf7c | 444 | ctx->pad[1] = U8TO64(key + 24); |
wolfSSL | 15:117db924cf7c | 445 | |
wolfSSL | 15:117db924cf7c | 446 | ctx->leftover = 0; |
wolfSSL | 15:117db924cf7c | 447 | ctx->finished = 0; |
wolfSSL | 15:117db924cf7c | 448 | |
wolfSSL | 15:117db924cf7c | 449 | #else /* if not 64 bit then use 32 bit */ |
wolfSSL | 15:117db924cf7c | 450 | |
wolfSSL | 15:117db924cf7c | 451 | /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ |
wolfSSL | 15:117db924cf7c | 452 | ctx->r[0] = (U8TO32(key + 0) ) & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 453 | ctx->r[1] = (U8TO32(key + 3) >> 2) & 0x3ffff03; |
wolfSSL | 15:117db924cf7c | 454 | ctx->r[2] = (U8TO32(key + 6) >> 4) & 0x3ffc0ff; |
wolfSSL | 15:117db924cf7c | 455 | ctx->r[3] = (U8TO32(key + 9) >> 6) & 0x3f03fff; |
wolfSSL | 15:117db924cf7c | 456 | ctx->r[4] = (U8TO32(key + 12) >> 8) & 0x00fffff; |
wolfSSL | 15:117db924cf7c | 457 | |
wolfSSL | 15:117db924cf7c | 458 | /* h = 0 */ |
wolfSSL | 15:117db924cf7c | 459 | ctx->h[0] = 0; |
wolfSSL | 15:117db924cf7c | 460 | ctx->h[1] = 0; |
wolfSSL | 15:117db924cf7c | 461 | ctx->h[2] = 0; |
wolfSSL | 15:117db924cf7c | 462 | ctx->h[3] = 0; |
wolfSSL | 15:117db924cf7c | 463 | ctx->h[4] = 0; |
wolfSSL | 15:117db924cf7c | 464 | |
wolfSSL | 15:117db924cf7c | 465 | /* save pad for later */ |
wolfSSL | 15:117db924cf7c | 466 | ctx->pad[0] = U8TO32(key + 16); |
wolfSSL | 15:117db924cf7c | 467 | ctx->pad[1] = U8TO32(key + 20); |
wolfSSL | 15:117db924cf7c | 468 | ctx->pad[2] = U8TO32(key + 24); |
wolfSSL | 15:117db924cf7c | 469 | ctx->pad[3] = U8TO32(key + 28); |
wolfSSL | 15:117db924cf7c | 470 | |
wolfSSL | 15:117db924cf7c | 471 | ctx->leftover = 0; |
wolfSSL | 15:117db924cf7c | 472 | ctx->finished = 0; |
wolfSSL | 15:117db924cf7c | 473 | |
wolfSSL | 15:117db924cf7c | 474 | #endif |
wolfSSL | 15:117db924cf7c | 475 | |
wolfSSL | 15:117db924cf7c | 476 | return 0; |
wolfSSL | 15:117db924cf7c | 477 | } |
wolfSSL | 15:117db924cf7c | 478 | |
wolfSSL | 15:117db924cf7c | 479 | int wc_Poly1305Final(Poly1305* ctx, byte* mac) |
wolfSSL | 15:117db924cf7c | 480 | { |
wolfSSL | 15:117db924cf7c | 481 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 482 | #elif defined(POLY130564) |
wolfSSL | 15:117db924cf7c | 483 | |
wolfSSL | 15:117db924cf7c | 484 | word64 h0,h1,h2,c; |
wolfSSL | 15:117db924cf7c | 485 | word64 g0,g1,g2; |
wolfSSL | 15:117db924cf7c | 486 | word64 t0,t1; |
wolfSSL | 15:117db924cf7c | 487 | |
wolfSSL | 15:117db924cf7c | 488 | #else |
wolfSSL | 15:117db924cf7c | 489 | |
wolfSSL | 15:117db924cf7c | 490 | word32 h0,h1,h2,h3,h4,c; |
wolfSSL | 15:117db924cf7c | 491 | word32 g0,g1,g2,g3,g4; |
wolfSSL | 15:117db924cf7c | 492 | word64 f; |
wolfSSL | 15:117db924cf7c | 493 | word32 mask; |
wolfSSL | 15:117db924cf7c | 494 | |
wolfSSL | 15:117db924cf7c | 495 | #endif |
wolfSSL | 15:117db924cf7c | 496 | |
wolfSSL | 15:117db924cf7c | 497 | if (ctx == NULL) |
wolfSSL | 15:117db924cf7c | 498 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 499 | |
wolfSSL | 15:117db924cf7c | 500 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 501 | #ifdef HAVE_INTEL_AVX2 |
wolfSSL | 15:117db924cf7c | 502 | if (IS_INTEL_AVX2(intel_flags)) |
wolfSSL | 15:117db924cf7c | 503 | poly1305_final_avx2(ctx, mac); |
wolfSSL | 15:117db924cf7c | 504 | else |
wolfSSL | 15:117db924cf7c | 505 | #endif |
wolfSSL | 15:117db924cf7c | 506 | poly1305_final_avx(ctx, mac); |
wolfSSL | 15:117db924cf7c | 507 | #elif defined(POLY130564) |
wolfSSL | 15:117db924cf7c | 508 | |
wolfSSL | 15:117db924cf7c | 509 | /* process the remaining block */ |
wolfSSL | 15:117db924cf7c | 510 | if (ctx->leftover) { |
wolfSSL | 15:117db924cf7c | 511 | size_t i = ctx->leftover; |
wolfSSL | 15:117db924cf7c | 512 | ctx->buffer[i] = 1; |
wolfSSL | 15:117db924cf7c | 513 | for (i = i + 1; i < POLY1305_BLOCK_SIZE; i++) |
wolfSSL | 15:117db924cf7c | 514 | ctx->buffer[i] = 0; |
wolfSSL | 15:117db924cf7c | 515 | ctx->finished = 1; |
wolfSSL | 15:117db924cf7c | 516 | poly1305_block(ctx, ctx->buffer); |
wolfSSL | 15:117db924cf7c | 517 | } |
wolfSSL | 15:117db924cf7c | 518 | |
wolfSSL | 15:117db924cf7c | 519 | /* fully carry h */ |
wolfSSL | 15:117db924cf7c | 520 | h0 = ctx->h[0]; |
wolfSSL | 15:117db924cf7c | 521 | h1 = ctx->h[1]; |
wolfSSL | 15:117db924cf7c | 522 | h2 = ctx->h[2]; |
wolfSSL | 15:117db924cf7c | 523 | |
wolfSSL | 15:117db924cf7c | 524 | c = (h1 >> 44); h1 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 525 | h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff; |
wolfSSL | 15:117db924cf7c | 526 | h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 527 | h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 528 | h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff; |
wolfSSL | 15:117db924cf7c | 529 | h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 530 | h1 += c; |
wolfSSL | 15:117db924cf7c | 531 | |
wolfSSL | 15:117db924cf7c | 532 | /* compute h + -p */ |
wolfSSL | 15:117db924cf7c | 533 | g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 534 | g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 535 | g2 = h2 + c - ((word64)1 << 42); |
wolfSSL | 15:117db924cf7c | 536 | |
wolfSSL | 15:117db924cf7c | 537 | /* select h if h < p, or h + -p if h >= p */ |
wolfSSL | 15:117db924cf7c | 538 | c = (g2 >> ((sizeof(word64) * 8) - 1)) - 1; |
wolfSSL | 15:117db924cf7c | 539 | g0 &= c; |
wolfSSL | 15:117db924cf7c | 540 | g1 &= c; |
wolfSSL | 15:117db924cf7c | 541 | g2 &= c; |
wolfSSL | 15:117db924cf7c | 542 | c = ~c; |
wolfSSL | 15:117db924cf7c | 543 | h0 = (h0 & c) | g0; |
wolfSSL | 15:117db924cf7c | 544 | h1 = (h1 & c) | g1; |
wolfSSL | 15:117db924cf7c | 545 | h2 = (h2 & c) | g2; |
wolfSSL | 15:117db924cf7c | 546 | |
wolfSSL | 15:117db924cf7c | 547 | /* h = (h + pad) */ |
wolfSSL | 15:117db924cf7c | 548 | t0 = ctx->pad[0]; |
wolfSSL | 15:117db924cf7c | 549 | t1 = ctx->pad[1]; |
wolfSSL | 15:117db924cf7c | 550 | |
wolfSSL | 15:117db924cf7c | 551 | h0 += (( t0 ) & 0xfffffffffff) ; |
wolfSSL | 15:117db924cf7c | 552 | c = (h0 >> 44); h0 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 553 | h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; |
wolfSSL | 15:117db924cf7c | 554 | c = (h1 >> 44); h1 &= 0xfffffffffff; |
wolfSSL | 15:117db924cf7c | 555 | h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c; |
wolfSSL | 15:117db924cf7c | 556 | h2 &= 0x3ffffffffff; |
wolfSSL | 15:117db924cf7c | 557 | |
wolfSSL | 15:117db924cf7c | 558 | /* mac = h % (2^128) */ |
wolfSSL | 15:117db924cf7c | 559 | h0 = ((h0 ) | (h1 << 44)); |
wolfSSL | 15:117db924cf7c | 560 | h1 = ((h1 >> 20) | (h2 << 24)); |
wolfSSL | 15:117db924cf7c | 561 | |
wolfSSL | 15:117db924cf7c | 562 | U64TO8(mac + 0, h0); |
wolfSSL | 15:117db924cf7c | 563 | U64TO8(mac + 8, h1); |
wolfSSL | 15:117db924cf7c | 564 | |
wolfSSL | 15:117db924cf7c | 565 | /* zero out the state */ |
wolfSSL | 15:117db924cf7c | 566 | ctx->h[0] = 0; |
wolfSSL | 15:117db924cf7c | 567 | ctx->h[1] = 0; |
wolfSSL | 15:117db924cf7c | 568 | ctx->h[2] = 0; |
wolfSSL | 15:117db924cf7c | 569 | ctx->r[0] = 0; |
wolfSSL | 15:117db924cf7c | 570 | ctx->r[1] = 0; |
wolfSSL | 15:117db924cf7c | 571 | ctx->r[2] = 0; |
wolfSSL | 15:117db924cf7c | 572 | ctx->pad[0] = 0; |
wolfSSL | 15:117db924cf7c | 573 | ctx->pad[1] = 0; |
wolfSSL | 15:117db924cf7c | 574 | |
wolfSSL | 15:117db924cf7c | 575 | #else /* if not 64 bit then use 32 bit */ |
wolfSSL | 15:117db924cf7c | 576 | |
wolfSSL | 15:117db924cf7c | 577 | /* process the remaining block */ |
wolfSSL | 15:117db924cf7c | 578 | if (ctx->leftover) { |
wolfSSL | 15:117db924cf7c | 579 | size_t i = ctx->leftover; |
wolfSSL | 15:117db924cf7c | 580 | ctx->buffer[i++] = 1; |
wolfSSL | 15:117db924cf7c | 581 | for (; i < POLY1305_BLOCK_SIZE; i++) |
wolfSSL | 15:117db924cf7c | 582 | ctx->buffer[i] = 0; |
wolfSSL | 15:117db924cf7c | 583 | ctx->finished = 1; |
wolfSSL | 15:117db924cf7c | 584 | poly1305_block(ctx, ctx->buffer); |
wolfSSL | 15:117db924cf7c | 585 | } |
wolfSSL | 15:117db924cf7c | 586 | |
wolfSSL | 15:117db924cf7c | 587 | /* fully carry h */ |
wolfSSL | 15:117db924cf7c | 588 | h0 = ctx->h[0]; |
wolfSSL | 15:117db924cf7c | 589 | h1 = ctx->h[1]; |
wolfSSL | 15:117db924cf7c | 590 | h2 = ctx->h[2]; |
wolfSSL | 15:117db924cf7c | 591 | h3 = ctx->h[3]; |
wolfSSL | 15:117db924cf7c | 592 | h4 = ctx->h[4]; |
wolfSSL | 15:117db924cf7c | 593 | |
wolfSSL | 15:117db924cf7c | 594 | c = h1 >> 26; h1 = h1 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 595 | h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 596 | h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 597 | h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 598 | h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 599 | h1 += c; |
wolfSSL | 15:117db924cf7c | 600 | |
wolfSSL | 15:117db924cf7c | 601 | /* compute h + -p */ |
wolfSSL | 15:117db924cf7c | 602 | g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 603 | g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 604 | g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; |
wolfSSL | 15:117db924cf7c | 605 | g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; |
wolfSSL | 16:8e0d178b1d1e | 606 | g4 = h4 + c - ((word32)1 << 26); |
wolfSSL | 15:117db924cf7c | 607 | |
wolfSSL | 15:117db924cf7c | 608 | /* select h if h < p, or h + -p if h >= p */ |
wolfSSL | 16:8e0d178b1d1e | 609 | mask = ((word32)g4 >> ((sizeof(word32) * 8) - 1)) - 1; |
wolfSSL | 15:117db924cf7c | 610 | g0 &= mask; |
wolfSSL | 15:117db924cf7c | 611 | g1 &= mask; |
wolfSSL | 15:117db924cf7c | 612 | g2 &= mask; |
wolfSSL | 15:117db924cf7c | 613 | g3 &= mask; |
wolfSSL | 15:117db924cf7c | 614 | g4 &= mask; |
wolfSSL | 15:117db924cf7c | 615 | mask = ~mask; |
wolfSSL | 15:117db924cf7c | 616 | h0 = (h0 & mask) | g0; |
wolfSSL | 15:117db924cf7c | 617 | h1 = (h1 & mask) | g1; |
wolfSSL | 15:117db924cf7c | 618 | h2 = (h2 & mask) | g2; |
wolfSSL | 15:117db924cf7c | 619 | h3 = (h3 & mask) | g3; |
wolfSSL | 15:117db924cf7c | 620 | h4 = (h4 & mask) | g4; |
wolfSSL | 15:117db924cf7c | 621 | |
wolfSSL | 15:117db924cf7c | 622 | /* h = h % (2^128) */ |
wolfSSL | 15:117db924cf7c | 623 | h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; |
wolfSSL | 15:117db924cf7c | 624 | h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; |
wolfSSL | 15:117db924cf7c | 625 | h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; |
wolfSSL | 15:117db924cf7c | 626 | h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; |
wolfSSL | 15:117db924cf7c | 627 | |
wolfSSL | 15:117db924cf7c | 628 | /* mac = (h + pad) % (2^128) */ |
wolfSSL | 15:117db924cf7c | 629 | f = (word64)h0 + ctx->pad[0] ; h0 = (word32)f; |
wolfSSL | 15:117db924cf7c | 630 | f = (word64)h1 + ctx->pad[1] + (f >> 32); h1 = (word32)f; |
wolfSSL | 15:117db924cf7c | 631 | f = (word64)h2 + ctx->pad[2] + (f >> 32); h2 = (word32)f; |
wolfSSL | 15:117db924cf7c | 632 | f = (word64)h3 + ctx->pad[3] + (f >> 32); h3 = (word32)f; |
wolfSSL | 15:117db924cf7c | 633 | |
wolfSSL | 15:117db924cf7c | 634 | U32TO8(mac + 0, h0); |
wolfSSL | 15:117db924cf7c | 635 | U32TO8(mac + 4, h1); |
wolfSSL | 15:117db924cf7c | 636 | U32TO8(mac + 8, h2); |
wolfSSL | 15:117db924cf7c | 637 | U32TO8(mac + 12, h3); |
wolfSSL | 15:117db924cf7c | 638 | |
wolfSSL | 15:117db924cf7c | 639 | /* zero out the state */ |
wolfSSL | 15:117db924cf7c | 640 | ctx->h[0] = 0; |
wolfSSL | 15:117db924cf7c | 641 | ctx->h[1] = 0; |
wolfSSL | 15:117db924cf7c | 642 | ctx->h[2] = 0; |
wolfSSL | 15:117db924cf7c | 643 | ctx->h[3] = 0; |
wolfSSL | 15:117db924cf7c | 644 | ctx->h[4] = 0; |
wolfSSL | 15:117db924cf7c | 645 | ctx->r[0] = 0; |
wolfSSL | 15:117db924cf7c | 646 | ctx->r[1] = 0; |
wolfSSL | 15:117db924cf7c | 647 | ctx->r[2] = 0; |
wolfSSL | 15:117db924cf7c | 648 | ctx->r[3] = 0; |
wolfSSL | 15:117db924cf7c | 649 | ctx->r[4] = 0; |
wolfSSL | 15:117db924cf7c | 650 | ctx->pad[0] = 0; |
wolfSSL | 15:117db924cf7c | 651 | ctx->pad[1] = 0; |
wolfSSL | 15:117db924cf7c | 652 | ctx->pad[2] = 0; |
wolfSSL | 15:117db924cf7c | 653 | ctx->pad[3] = 0; |
wolfSSL | 15:117db924cf7c | 654 | |
wolfSSL | 15:117db924cf7c | 655 | #endif |
wolfSSL | 15:117db924cf7c | 656 | |
wolfSSL | 15:117db924cf7c | 657 | return 0; |
wolfSSL | 15:117db924cf7c | 658 | } |
wolfSSL | 16:8e0d178b1d1e | 659 | #endif /* !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) */ |
wolfSSL | 15:117db924cf7c | 660 | |
wolfSSL | 15:117db924cf7c | 661 | |
wolfSSL | 15:117db924cf7c | 662 | int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) |
wolfSSL | 15:117db924cf7c | 663 | { |
wolfSSL | 15:117db924cf7c | 664 | size_t i; |
wolfSSL | 15:117db924cf7c | 665 | |
wolfSSL | 15:117db924cf7c | 666 | #ifdef CHACHA_AEAD_TEST |
wolfSSL | 15:117db924cf7c | 667 | word32 k; |
wolfSSL | 15:117db924cf7c | 668 | printf("Raw input to poly:\n"); |
wolfSSL | 15:117db924cf7c | 669 | for (k = 0; k < bytes; k++) { |
wolfSSL | 15:117db924cf7c | 670 | printf("%02x", m[k]); |
wolfSSL | 15:117db924cf7c | 671 | if ((k+1) % 16 == 0) |
wolfSSL | 15:117db924cf7c | 672 | printf("\n"); |
wolfSSL | 15:117db924cf7c | 673 | } |
wolfSSL | 15:117db924cf7c | 674 | printf("\n"); |
wolfSSL | 15:117db924cf7c | 675 | #endif |
wolfSSL | 15:117db924cf7c | 676 | |
wolfSSL | 15:117db924cf7c | 677 | if (ctx == NULL) |
wolfSSL | 15:117db924cf7c | 678 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 679 | |
wolfSSL | 15:117db924cf7c | 680 | #ifdef USE_INTEL_SPEEDUP |
wolfSSL | 15:117db924cf7c | 681 | #ifdef HAVE_INTEL_AVX2 |
wolfSSL | 15:117db924cf7c | 682 | if (IS_INTEL_AVX2(intel_flags)) { |
wolfSSL | 15:117db924cf7c | 683 | /* handle leftover */ |
wolfSSL | 15:117db924cf7c | 684 | if (ctx->leftover) { |
wolfSSL | 15:117db924cf7c | 685 | size_t want = sizeof(ctx->buffer) - ctx->leftover; |
wolfSSL | 15:117db924cf7c | 686 | if (want > bytes) |
wolfSSL | 15:117db924cf7c | 687 | want = bytes; |
wolfSSL | 15:117db924cf7c | 688 | |
wolfSSL | 15:117db924cf7c | 689 | for (i = 0; i < want; i++) |
wolfSSL | 15:117db924cf7c | 690 | ctx->buffer[ctx->leftover + i] = m[i]; |
wolfSSL | 15:117db924cf7c | 691 | bytes -= (word32)want; |
wolfSSL | 15:117db924cf7c | 692 | m += want; |
wolfSSL | 15:117db924cf7c | 693 | ctx->leftover += want; |
wolfSSL | 15:117db924cf7c | 694 | if (ctx->leftover < sizeof(ctx->buffer)) |
wolfSSL | 15:117db924cf7c | 695 | return 0; |
wolfSSL | 15:117db924cf7c | 696 | |
wolfSSL | 15:117db924cf7c | 697 | if (!ctx->started) |
wolfSSL | 16:8e0d178b1d1e | 698 | poly1305_calc_powers_avx2(ctx); |
wolfSSL | 15:117db924cf7c | 699 | poly1305_blocks_avx2(ctx, ctx->buffer, sizeof(ctx->buffer)); |
wolfSSL | 15:117db924cf7c | 700 | ctx->leftover = 0; |
wolfSSL | 15:117db924cf7c | 701 | } |
wolfSSL | 15:117db924cf7c | 702 | |
wolfSSL | 15:117db924cf7c | 703 | /* process full blocks */ |
wolfSSL | 15:117db924cf7c | 704 | if (bytes >= sizeof(ctx->buffer)) { |
wolfSSL | 15:117db924cf7c | 705 | size_t want = bytes & ~(sizeof(ctx->buffer) - 1); |
wolfSSL | 15:117db924cf7c | 706 | |
wolfSSL | 15:117db924cf7c | 707 | if (!ctx->started) |
wolfSSL | 16:8e0d178b1d1e | 708 | poly1305_calc_powers_avx2(ctx); |
wolfSSL | 15:117db924cf7c | 709 | poly1305_blocks_avx2(ctx, m, want); |
wolfSSL | 15:117db924cf7c | 710 | m += want; |
wolfSSL | 15:117db924cf7c | 711 | bytes -= (word32)want; |
wolfSSL | 15:117db924cf7c | 712 | } |
wolfSSL | 15:117db924cf7c | 713 | |
wolfSSL | 15:117db924cf7c | 714 | /* store leftover */ |
wolfSSL | 15:117db924cf7c | 715 | if (bytes) { |
wolfSSL | 15:117db924cf7c | 716 | for (i = 0; i < bytes; i++) |
wolfSSL | 15:117db924cf7c | 717 | ctx->buffer[ctx->leftover + i] = m[i]; |
wolfSSL | 15:117db924cf7c | 718 | ctx->leftover += bytes; |
wolfSSL | 15:117db924cf7c | 719 | } |
wolfSSL | 15:117db924cf7c | 720 | } |
wolfSSL | 15:117db924cf7c | 721 | else |
wolfSSL | 15:117db924cf7c | 722 | #endif |
wolfSSL | 15:117db924cf7c | 723 | #endif |
wolfSSL | 15:117db924cf7c | 724 | { |
wolfSSL | 15:117db924cf7c | 725 | /* handle leftover */ |
wolfSSL | 15:117db924cf7c | 726 | if (ctx->leftover) { |
wolfSSL | 15:117db924cf7c | 727 | size_t want = (POLY1305_BLOCK_SIZE - ctx->leftover); |
wolfSSL | 15:117db924cf7c | 728 | if (want > bytes) |
wolfSSL | 15:117db924cf7c | 729 | want = bytes; |
wolfSSL | 15:117db924cf7c | 730 | for (i = 0; i < want; i++) |
wolfSSL | 15:117db924cf7c | 731 | ctx->buffer[ctx->leftover + i] = m[i]; |
wolfSSL | 15:117db924cf7c | 732 | bytes -= (word32)want; |
wolfSSL | 15:117db924cf7c | 733 | m += want; |
wolfSSL | 15:117db924cf7c | 734 | ctx->leftover += want; |
wolfSSL | 15:117db924cf7c | 735 | if (ctx->leftover < POLY1305_BLOCK_SIZE) |
wolfSSL | 15:117db924cf7c | 736 | return 0; |
wolfSSL | 15:117db924cf7c | 737 | poly1305_block(ctx, ctx->buffer); |
wolfSSL | 15:117db924cf7c | 738 | ctx->leftover = 0; |
wolfSSL | 15:117db924cf7c | 739 | } |
wolfSSL | 15:117db924cf7c | 740 | |
wolfSSL | 15:117db924cf7c | 741 | /* process full blocks */ |
wolfSSL | 15:117db924cf7c | 742 | if (bytes >= POLY1305_BLOCK_SIZE) { |
wolfSSL | 15:117db924cf7c | 743 | size_t want = (bytes & ~(POLY1305_BLOCK_SIZE - 1)); |
wolfSSL | 15:117db924cf7c | 744 | poly1305_blocks(ctx, m, want); |
wolfSSL | 15:117db924cf7c | 745 | m += want; |
wolfSSL | 15:117db924cf7c | 746 | bytes -= (word32)want; |
wolfSSL | 15:117db924cf7c | 747 | } |
wolfSSL | 15:117db924cf7c | 748 | |
wolfSSL | 15:117db924cf7c | 749 | /* store leftover */ |
wolfSSL | 15:117db924cf7c | 750 | if (bytes) { |
wolfSSL | 15:117db924cf7c | 751 | for (i = 0; i < bytes; i++) |
wolfSSL | 15:117db924cf7c | 752 | ctx->buffer[ctx->leftover + i] = m[i]; |
wolfSSL | 15:117db924cf7c | 753 | ctx->leftover += bytes; |
wolfSSL | 15:117db924cf7c | 754 | } |
wolfSSL | 15:117db924cf7c | 755 | } |
wolfSSL | 15:117db924cf7c | 756 | |
wolfSSL | 15:117db924cf7c | 757 | return 0; |
wolfSSL | 15:117db924cf7c | 758 | } |
wolfSSL | 15:117db924cf7c | 759 | |
wolfSSL | 16:8e0d178b1d1e | 760 | /* Takes a Poly1305 struct that has a key loaded and pads the provided length |
wolfSSL | 16:8e0d178b1d1e | 761 | ctx : Initialized Poly1305 struct to use |
wolfSSL | 16:8e0d178b1d1e | 762 | lenToPad : Current number of bytes updated that needs padding to 16 |
wolfSSL | 16:8e0d178b1d1e | 763 | */ |
wolfSSL | 16:8e0d178b1d1e | 764 | int wc_Poly1305_Pad(Poly1305* ctx, word32 lenToPad) |
wolfSSL | 16:8e0d178b1d1e | 765 | { |
wolfSSL | 16:8e0d178b1d1e | 766 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 767 | word32 paddingLen; |
wolfSSL | 16:8e0d178b1d1e | 768 | byte padding[WC_POLY1305_PAD_SZ - 1]; |
wolfSSL | 16:8e0d178b1d1e | 769 | |
wolfSSL | 16:8e0d178b1d1e | 770 | if (ctx == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 771 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 772 | } |
wolfSSL | 16:8e0d178b1d1e | 773 | if (lenToPad == 0) { |
wolfSSL | 16:8e0d178b1d1e | 774 | return 0; /* nothing needs to be done */ |
wolfSSL | 16:8e0d178b1d1e | 775 | } |
wolfSSL | 16:8e0d178b1d1e | 776 | |
wolfSSL | 16:8e0d178b1d1e | 777 | XMEMSET(padding, 0, sizeof(padding)); |
wolfSSL | 16:8e0d178b1d1e | 778 | |
wolfSSL | 16:8e0d178b1d1e | 779 | /* Pad length to 16 bytes */ |
wolfSSL | 16:8e0d178b1d1e | 780 | paddingLen = -(int)lenToPad & (WC_POLY1305_PAD_SZ - 1); |
wolfSSL | 16:8e0d178b1d1e | 781 | if (paddingLen > 0) { |
wolfSSL | 16:8e0d178b1d1e | 782 | ret = wc_Poly1305Update(ctx, padding, paddingLen); |
wolfSSL | 16:8e0d178b1d1e | 783 | } |
wolfSSL | 16:8e0d178b1d1e | 784 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 785 | } |
wolfSSL | 16:8e0d178b1d1e | 786 | |
wolfSSL | 16:8e0d178b1d1e | 787 | /* Takes a Poly1305 struct that has a key loaded and adds the AEAD length |
wolfSSL | 16:8e0d178b1d1e | 788 | encoding in 64-bit little endian |
wolfSSL | 16:8e0d178b1d1e | 789 | aadSz : Size of the additional authentication data |
wolfSSL | 16:8e0d178b1d1e | 790 | dataSz : Size of the plaintext or ciphertext |
wolfSSL | 16:8e0d178b1d1e | 791 | */ |
wolfSSL | 16:8e0d178b1d1e | 792 | int wc_Poly1305_EncodeSizes(Poly1305* ctx, word32 aadSz, word32 dataSz) |
wolfSSL | 16:8e0d178b1d1e | 793 | { |
wolfSSL | 16:8e0d178b1d1e | 794 | int ret; |
wolfSSL | 16:8e0d178b1d1e | 795 | byte little64[16]; /* sizeof(word64) * 2 */ |
wolfSSL | 16:8e0d178b1d1e | 796 | |
wolfSSL | 16:8e0d178b1d1e | 797 | if (ctx == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 798 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 799 | } |
wolfSSL | 16:8e0d178b1d1e | 800 | |
wolfSSL | 16:8e0d178b1d1e | 801 | XMEMSET(little64, 0, sizeof(little64)); |
wolfSSL | 16:8e0d178b1d1e | 802 | |
wolfSSL | 16:8e0d178b1d1e | 803 | /* size of additional data and input data as little endian 64 bit types */ |
wolfSSL | 16:8e0d178b1d1e | 804 | u32tole64(aadSz, little64); |
wolfSSL | 16:8e0d178b1d1e | 805 | u32tole64(dataSz, little64 + 8); |
wolfSSL | 16:8e0d178b1d1e | 806 | ret = wc_Poly1305Update(ctx, little64, sizeof(little64)); |
wolfSSL | 16:8e0d178b1d1e | 807 | |
wolfSSL | 16:8e0d178b1d1e | 808 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 809 | } |
wolfSSL | 15:117db924cf7c | 810 | |
wolfSSL | 15:117db924cf7c | 811 | /* Takes in an initialized Poly1305 struct that has a key loaded and creates |
wolfSSL | 15:117db924cf7c | 812 | a MAC (tag) using recent TLS AEAD padding scheme. |
wolfSSL | 15:117db924cf7c | 813 | ctx : Initialized Poly1305 struct to use |
wolfSSL | 15:117db924cf7c | 814 | additional : Additional data to use |
wolfSSL | 15:117db924cf7c | 815 | addSz : Size of additional buffer |
wolfSSL | 15:117db924cf7c | 816 | input : Input buffer to create tag from |
wolfSSL | 15:117db924cf7c | 817 | sz : Size of input buffer |
wolfSSL | 15:117db924cf7c | 818 | tag : Buffer to hold created tag |
wolfSSL | 15:117db924cf7c | 819 | tagSz : Size of input tag buffer (must be at least |
wolfSSL | 15:117db924cf7c | 820 | WC_POLY1305_MAC_SZ(16)) |
wolfSSL | 15:117db924cf7c | 821 | */ |
wolfSSL | 15:117db924cf7c | 822 | int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, |
wolfSSL | 15:117db924cf7c | 823 | byte* input, word32 sz, byte* tag, word32 tagSz) |
wolfSSL | 15:117db924cf7c | 824 | { |
wolfSSL | 15:117db924cf7c | 825 | int ret; |
wolfSSL | 15:117db924cf7c | 826 | |
wolfSSL | 15:117db924cf7c | 827 | /* sanity check on arguments */ |
wolfSSL | 15:117db924cf7c | 828 | if (ctx == NULL || input == NULL || tag == NULL || |
wolfSSL | 15:117db924cf7c | 829 | tagSz < WC_POLY1305_MAC_SZ) { |
wolfSSL | 15:117db924cf7c | 830 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 831 | } |
wolfSSL | 15:117db924cf7c | 832 | |
wolfSSL | 15:117db924cf7c | 833 | /* additional allowed to be 0 */ |
wolfSSL | 15:117db924cf7c | 834 | if (addSz > 0) { |
wolfSSL | 15:117db924cf7c | 835 | if (additional == NULL) |
wolfSSL | 15:117db924cf7c | 836 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 837 | |
wolfSSL | 15:117db924cf7c | 838 | /* additional data plus padding */ |
wolfSSL | 15:117db924cf7c | 839 | if ((ret = wc_Poly1305Update(ctx, additional, addSz)) != 0) { |
wolfSSL | 15:117db924cf7c | 840 | return ret; |
wolfSSL | 15:117db924cf7c | 841 | } |
wolfSSL | 16:8e0d178b1d1e | 842 | /* pad additional data */ |
wolfSSL | 16:8e0d178b1d1e | 843 | if ((ret = wc_Poly1305_Pad(ctx, addSz)) != 0) { |
wolfSSL | 16:8e0d178b1d1e | 844 | return ret; |
wolfSSL | 15:117db924cf7c | 845 | } |
wolfSSL | 15:117db924cf7c | 846 | } |
wolfSSL | 15:117db924cf7c | 847 | |
wolfSSL | 15:117db924cf7c | 848 | /* input plus padding */ |
wolfSSL | 15:117db924cf7c | 849 | if ((ret = wc_Poly1305Update(ctx, input, sz)) != 0) { |
wolfSSL | 15:117db924cf7c | 850 | return ret; |
wolfSSL | 15:117db924cf7c | 851 | } |
wolfSSL | 16:8e0d178b1d1e | 852 | /* pad input data */ |
wolfSSL | 16:8e0d178b1d1e | 853 | if ((ret = wc_Poly1305_Pad(ctx, sz)) != 0) { |
wolfSSL | 16:8e0d178b1d1e | 854 | return ret; |
wolfSSL | 15:117db924cf7c | 855 | } |
wolfSSL | 15:117db924cf7c | 856 | |
wolfSSL | 16:8e0d178b1d1e | 857 | /* encode size of AAD and input data as little endian 64 bit types */ |
wolfSSL | 16:8e0d178b1d1e | 858 | if ((ret = wc_Poly1305_EncodeSizes(ctx, addSz, sz)) != 0) { |
wolfSSL | 15:117db924cf7c | 859 | return ret; |
wolfSSL | 15:117db924cf7c | 860 | } |
wolfSSL | 15:117db924cf7c | 861 | |
wolfSSL | 15:117db924cf7c | 862 | /* Finalize the auth tag */ |
wolfSSL | 15:117db924cf7c | 863 | ret = wc_Poly1305Final(ctx, tag); |
wolfSSL | 15:117db924cf7c | 864 | |
wolfSSL | 15:117db924cf7c | 865 | return ret; |
wolfSSL | 15:117db924cf7c | 866 | |
wolfSSL | 15:117db924cf7c | 867 | } |
wolfSSL | 15:117db924cf7c | 868 | #endif /* HAVE_POLY1305 */ |
wolfSSL | 15:117db924cf7c | 869 |