LCOV - code coverage report
Current view: top level - cipher - poly1305.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 97 273 35.5 %
Date: 2017-03-02 16:44:37 Functions: 7 10 70.0 %

          Line data    Source code
       1             : /* poly1305.c  -  Poly1305 internals and generic implementation
       2             :  * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser general Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /* The code is based on public-domain Poly1305 implementation by
      21             :  * Andrew Moon at
      22             :  *  https://github.com/floodyberry/poly1305-opt
      23             :  */
      24             : 
      25             : #include <config.h>
      26             : #include <stdio.h>
      27             : #include <stdlib.h>
      28             : #include <string.h>
      29             : 
      30             : #include "types.h"
      31             : #include "g10lib.h"
      32             : #include "cipher.h"
      33             : #include "bufhelp.h"
      34             : #include "poly1305-internal.h"
      35             : 
      36             : 
      37             : static const char *selftest (void);
      38             : 
      39             : 
      40             : 
      41             : #ifdef POLY1305_USE_SSE2
      42             : 
      43             : void _gcry_poly1305_amd64_sse2_init_ext(void *state, const poly1305_key_t *key)
      44             :                                        OPS_FUNC_ABI;
      45             : unsigned int _gcry_poly1305_amd64_sse2_finish_ext(void *state, const byte *m,
      46             :                                                   size_t remaining,
      47             :                                                   byte mac[16]) OPS_FUNC_ABI;
      48             : unsigned int _gcry_poly1305_amd64_sse2_blocks(void *ctx, const byte *m,
      49             :                                               size_t bytes) OPS_FUNC_ABI;
      50             : 
      51             : static const poly1305_ops_t poly1305_amd64_sse2_ops = {
      52             :   POLY1305_SSE2_BLOCKSIZE,
      53             :   _gcry_poly1305_amd64_sse2_init_ext,
      54             :   _gcry_poly1305_amd64_sse2_blocks,
      55             :   _gcry_poly1305_amd64_sse2_finish_ext
      56             : };
      57             : 
      58             : #endif
      59             : 
      60             : 
      61             : #ifdef POLY1305_USE_AVX2
      62             : 
      63             : void _gcry_poly1305_amd64_avx2_init_ext(void *state, const poly1305_key_t *key)
      64             :                                        OPS_FUNC_ABI;
      65             : unsigned int _gcry_poly1305_amd64_avx2_finish_ext(void *state, const byte *m,
      66             :                                                   size_t remaining,
      67             :                                                   byte mac[16]) OPS_FUNC_ABI;
      68             : unsigned int _gcry_poly1305_amd64_avx2_blocks(void *ctx, const byte *m,
      69             :                                               size_t bytes) OPS_FUNC_ABI;
      70             : 
      71             : static const poly1305_ops_t poly1305_amd64_avx2_ops = {
      72             :   POLY1305_AVX2_BLOCKSIZE,
      73             :   _gcry_poly1305_amd64_avx2_init_ext,
      74             :   _gcry_poly1305_amd64_avx2_blocks,
      75             :   _gcry_poly1305_amd64_avx2_finish_ext
      76             : };
      77             : 
      78             : #endif
      79             : 
      80             : 
      81             : #ifdef POLY1305_USE_NEON
      82             : 
      83             : void _gcry_poly1305_armv7_neon_init_ext(void *state, const poly1305_key_t *key)
      84             :                                        OPS_FUNC_ABI;
      85             : unsigned int _gcry_poly1305_armv7_neon_finish_ext(void *state, const byte *m,
      86             :                                                   size_t remaining,
      87             :                                                   byte mac[16]) OPS_FUNC_ABI;
      88             : unsigned int _gcry_poly1305_armv7_neon_blocks(void *ctx, const byte *m,
      89             :                                               size_t bytes) OPS_FUNC_ABI;
      90             : 
      91             : static const poly1305_ops_t poly1305_armv7_neon_ops = {
      92             :   POLY1305_NEON_BLOCKSIZE,
      93             :   _gcry_poly1305_armv7_neon_init_ext,
      94             :   _gcry_poly1305_armv7_neon_blocks,
      95             :   _gcry_poly1305_armv7_neon_finish_ext
      96             : };
      97             : 
      98             : #endif
      99             : 
     100             : 
     101             : /* Reference unoptimized poly1305 implementation using 32 bit * 32 bit = 64 bit
     102             :  * multiplication and 64 bit addition.
     103             :  */
     104             : 
     105             : typedef struct poly1305_state_ref32_s
     106             : {
     107             :   u32 r[5];
     108             :   u32 h[5];
     109             :   u32 pad[4];
     110             :   byte final;
     111             : } poly1305_state_ref32_t;
     112             : 
     113             : 
     114             : static OPS_FUNC_ABI void
     115           0 : poly1305_init_ext_ref32 (void *state, const poly1305_key_t * key)
     116             : {
     117           0 :   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
     118             : 
     119             :   gcry_assert (sizeof (*st) + POLY1305_STATE_ALIGNMENT <=
     120             :                sizeof (((poly1305_context_t *) 0)->state));
     121             : 
     122             :   /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
     123           0 :   st->r[0] = (buf_get_le32 (&key->b[0])) & 0x3ffffff;
     124           0 :   st->r[1] = (buf_get_le32 (&key->b[3]) >> 2) & 0x3ffff03;
     125           0 :   st->r[2] = (buf_get_le32 (&key->b[6]) >> 4) & 0x3ffc0ff;
     126           0 :   st->r[3] = (buf_get_le32 (&key->b[9]) >> 6) & 0x3f03fff;
     127           0 :   st->r[4] = (buf_get_le32 (&key->b[12]) >> 8) & 0x00fffff;
     128             : 
     129             :   /* h = 0 */
     130           0 :   st->h[0] = 0;
     131           0 :   st->h[1] = 0;
     132           0 :   st->h[2] = 0;
     133           0 :   st->h[3] = 0;
     134           0 :   st->h[4] = 0;
     135             : 
     136             :   /* save pad for later */
     137           0 :   st->pad[0] = buf_get_le32 (&key->b[16]);
     138           0 :   st->pad[1] = buf_get_le32 (&key->b[20]);
     139           0 :   st->pad[2] = buf_get_le32 (&key->b[24]);
     140           0 :   st->pad[3] = buf_get_le32 (&key->b[28]);
     141             : 
     142           0 :   st->final = 0;
     143           0 : }
     144             : 
     145             : 
     146             : static OPS_FUNC_ABI unsigned int
     147           0 : poly1305_blocks_ref32 (void *state, const byte * m, size_t bytes)
     148             : {
     149           0 :   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
     150           0 :   const u32 hibit = (st->final) ? 0 : (1 << 24);       /* 1 << 128 */
     151             :   u32 r0, r1, r2, r3, r4;
     152             :   u32 s1, s2, s3, s4;
     153             :   u32 h0, h1, h2, h3, h4;
     154             :   u64 d0, d1, d2, d3, d4;
     155             :   u32 c;
     156             : 
     157           0 :   r0 = st->r[0];
     158           0 :   r1 = st->r[1];
     159           0 :   r2 = st->r[2];
     160           0 :   r3 = st->r[3];
     161           0 :   r4 = st->r[4];
     162             : 
     163           0 :   s1 = r1 * 5;
     164           0 :   s2 = r2 * 5;
     165           0 :   s3 = r3 * 5;
     166           0 :   s4 = r4 * 5;
     167             : 
     168           0 :   h0 = st->h[0];
     169           0 :   h1 = st->h[1];
     170           0 :   h2 = st->h[2];
     171           0 :   h3 = st->h[3];
     172           0 :   h4 = st->h[4];
     173             : 
     174           0 :   while (bytes >= POLY1305_REF_BLOCKSIZE)
     175             :     {
     176             :       /* h += m[i] */
     177           0 :       h0 += (buf_get_le32 (m + 0)) & 0x3ffffff;
     178           0 :       h1 += (buf_get_le32 (m + 3) >> 2) & 0x3ffffff;
     179           0 :       h2 += (buf_get_le32 (m + 6) >> 4) & 0x3ffffff;
     180           0 :       h3 += (buf_get_le32 (m + 9) >> 6) & 0x3ffffff;
     181           0 :       h4 += (buf_get_le32 (m + 12) >> 8) | hibit;
     182             : 
     183             :       /* h *= r */
     184           0 :       d0 =
     185           0 :         ((u64) h0 * r0) + ((u64) h1 * s4) +
     186           0 :         ((u64) h2 * s3) + ((u64) h3 * s2) + ((u64) h4 * s1);
     187           0 :       d1 =
     188           0 :         ((u64) h0 * r1) + ((u64) h1 * r0) +
     189           0 :         ((u64) h2 * s4) + ((u64) h3 * s3) + ((u64) h4 * s2);
     190           0 :       d2 =
     191           0 :         ((u64) h0 * r2) + ((u64) h1 * r1) +
     192           0 :         ((u64) h2 * r0) + ((u64) h3 * s4) + ((u64) h4 * s3);
     193           0 :       d3 =
     194           0 :         ((u64) h0 * r3) + ((u64) h1 * r2) +
     195           0 :         ((u64) h2 * r1) + ((u64) h3 * r0) + ((u64) h4 * s4);
     196           0 :       d4 =
     197           0 :         ((u64) h0 * r4) + ((u64) h1 * r3) +
     198           0 :         ((u64) h2 * r2) + ((u64) h3 * r1) + ((u64) h4 * r0);
     199             : 
     200             :       /* (partial) h %= p */
     201           0 :       c = (u32) (d0 >> 26);
     202           0 :       h0 = (u32) d0 & 0x3ffffff;
     203           0 :       d1 += c;
     204           0 :       c = (u32) (d1 >> 26);
     205           0 :       h1 = (u32) d1 & 0x3ffffff;
     206           0 :       d2 += c;
     207           0 :       c = (u32) (d2 >> 26);
     208           0 :       h2 = (u32) d2 & 0x3ffffff;
     209           0 :       d3 += c;
     210           0 :       c = (u32) (d3 >> 26);
     211           0 :       h3 = (u32) d3 & 0x3ffffff;
     212           0 :       d4 += c;
     213           0 :       c = (u32) (d4 >> 26);
     214           0 :       h4 = (u32) d4 & 0x3ffffff;
     215           0 :       h0 += c * 5;
     216           0 :       c = (h0 >> 26);
     217           0 :       h0 = h0 & 0x3ffffff;
     218           0 :       h1 += c;
     219             : 
     220           0 :       m += POLY1305_REF_BLOCKSIZE;
     221           0 :       bytes -= POLY1305_REF_BLOCKSIZE;
     222             :     }
     223             : 
     224           0 :   st->h[0] = h0;
     225           0 :   st->h[1] = h1;
     226           0 :   st->h[2] = h2;
     227           0 :   st->h[3] = h3;
     228           0 :   st->h[4] = h4;
     229             : 
     230           0 :   return (16 * sizeof (u32) + 5 * sizeof (u64) + 5 * sizeof (void *));
     231             : }
     232             : 
     233             : 
     234             : static OPS_FUNC_ABI unsigned int
     235           0 : poly1305_finish_ext_ref32 (void *state, const byte * m,
     236             :                            size_t remaining, byte mac[POLY1305_TAGLEN])
     237             : {
     238           0 :   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
     239             :   u32 h0, h1, h2, h3, h4, c;
     240             :   u32 g0, g1, g2, g3, g4;
     241             :   u64 f;
     242             :   u32 mask;
     243           0 :   unsigned int burn = 0;
     244             : 
     245             :   /* process the remaining block */
     246           0 :   if (remaining)
     247             :     {
     248           0 :       byte final[POLY1305_REF_BLOCKSIZE] = { 0 };
     249             :       size_t i;
     250           0 :       for (i = 0; i < remaining; i++)
     251           0 :         final[i] = m[i];
     252           0 :       final[remaining] = 1;
     253           0 :       st->final = 1;
     254           0 :       burn = poly1305_blocks_ref32 (st, final, POLY1305_REF_BLOCKSIZE);
     255             :     }
     256             : 
     257             :   /* fully carry h */
     258           0 :   h0 = st->h[0];
     259           0 :   h1 = st->h[1];
     260           0 :   h2 = st->h[2];
     261           0 :   h3 = st->h[3];
     262           0 :   h4 = st->h[4];
     263             : 
     264           0 :   c = h1 >> 26;
     265           0 :   h1 = h1 & 0x3ffffff;
     266           0 :   h2 += c;
     267           0 :   c = h2 >> 26;
     268           0 :   h2 = h2 & 0x3ffffff;
     269           0 :   h3 += c;
     270           0 :   c = h3 >> 26;
     271           0 :   h3 = h3 & 0x3ffffff;
     272           0 :   h4 += c;
     273           0 :   c = h4 >> 26;
     274           0 :   h4 = h4 & 0x3ffffff;
     275           0 :   h0 += c * 5;
     276           0 :   c = h0 >> 26;
     277           0 :   h0 = h0 & 0x3ffffff;
     278           0 :   h1 += c;
     279             : 
     280             :   /* compute h + -p */
     281           0 :   g0 = h0 + 5;
     282           0 :   c = g0 >> 26;
     283           0 :   g0 &= 0x3ffffff;
     284           0 :   g1 = h1 + c;
     285           0 :   c = g1 >> 26;
     286           0 :   g1 &= 0x3ffffff;
     287           0 :   g2 = h2 + c;
     288           0 :   c = g2 >> 26;
     289           0 :   g2 &= 0x3ffffff;
     290           0 :   g3 = h3 + c;
     291           0 :   c = g3 >> 26;
     292           0 :   g3 &= 0x3ffffff;
     293           0 :   g4 = h4 + c - (1 << 26);
     294             : 
     295             :   /* select h if h < p, or h + -p if h >= p */
     296           0 :   mask = (g4 >> ((sizeof (u32) * 8) - 1)) - 1;
     297           0 :   g0 &= mask;
     298           0 :   g1 &= mask;
     299           0 :   g2 &= mask;
     300           0 :   g3 &= mask;
     301           0 :   g4 &= mask;
     302           0 :   mask = ~mask;
     303           0 :   h0 = (h0 & mask) | g0;
     304           0 :   h1 = (h1 & mask) | g1;
     305           0 :   h2 = (h2 & mask) | g2;
     306           0 :   h3 = (h3 & mask) | g3;
     307           0 :   h4 = (h4 & mask) | g4;
     308             : 
     309             :   /* h = h % (2^128) */
     310           0 :   h0 = ((h0) | (h1 << 26)) & 0xffffffff;
     311           0 :   h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
     312           0 :   h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
     313           0 :   h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
     314             : 
     315             :   /* mac = (h + pad) % (2^128) */
     316           0 :   f = (u64) h0 + st->pad[0];
     317           0 :   h0 = (u32) f;
     318           0 :   f = (u64) h1 + st->pad[1] + (f >> 32);
     319           0 :   h1 = (u32) f;
     320           0 :   f = (u64) h2 + st->pad[2] + (f >> 32);
     321           0 :   h2 = (u32) f;
     322           0 :   f = (u64) h3 + st->pad[3] + (f >> 32);
     323           0 :   h3 = (u32) f;
     324             : 
     325           0 :   buf_put_le32 (mac + 0, h0);
     326           0 :   buf_put_le32 (mac + 4, h1);
     327           0 :   buf_put_le32 (mac + 8, h2);
     328           0 :   buf_put_le32 (mac + 12, h3);
     329             : 
     330             :   /* zero out the state */
     331           0 :   st->h[0] = 0;
     332           0 :   st->h[1] = 0;
     333           0 :   st->h[2] = 0;
     334           0 :   st->h[3] = 0;
     335           0 :   st->h[4] = 0;
     336           0 :   st->r[0] = 0;
     337           0 :   st->r[1] = 0;
     338           0 :   st->r[2] = 0;
     339           0 :   st->r[3] = 0;
     340           0 :   st->r[4] = 0;
     341           0 :   st->pad[0] = 0;
     342           0 :   st->pad[1] = 0;
     343           0 :   st->pad[2] = 0;
     344           0 :   st->pad[3] = 0;
     345             : 
     346             :   /* burn_stack */
     347             :   return (13 * sizeof (u32) + sizeof (u64) +
     348           0 :           POLY1305_REF_BLOCKSIZE + 6 * sizeof (void *)) + burn;
     349             : }
     350             : 
     351             : 
     352             : static const poly1305_ops_t poly1305_default_ops = {
     353             :   POLY1305_REF_BLOCKSIZE,
     354             :   poly1305_init_ext_ref32,
     355             :   poly1305_blocks_ref32,
     356             :   poly1305_finish_ext_ref32
     357             : };
     358             : 
     359             : 
     360             : 
     361             : 
     362             : static inline void *
     363      720970 : poly1305_get_state (poly1305_context_t * ctx)
     364             : {
     365      720970 :   byte *c = ctx->state;
     366      720970 :   c += POLY1305_STATE_ALIGNMENT - 1;
     367      720970 :   c -= (uintptr_t) c & (POLY1305_STATE_ALIGNMENT - 1);
     368      720970 :   return c;
     369             : }
     370             : 
     371             : 
     372             : static void
     373        9336 : poly1305_init (poly1305_context_t * ctx, const poly1305_key_t * key)
     374             : {
     375        9336 :   void *state = poly1305_get_state (ctx);
     376             : 
     377        9336 :   ctx->leftover = 0;
     378             : 
     379        9336 :   ctx->ops->init_ext (state, key);
     380        9336 : }
     381             : 
     382             : 
     383             : void
     384      702560 : _gcry_poly1305_update (poly1305_context_t * ctx, const byte * m, size_t bytes)
     385             : {
     386      702560 :   void *state = poly1305_get_state (ctx);
     387      702560 :   unsigned int burn = 0;
     388      702560 :   size_t block_size = ctx->ops->block_size;
     389             : 
     390             :   /* handle leftover */
     391      702560 :   if (ctx->leftover)
     392             :     {
     393      644914 :       size_t want = (block_size - ctx->leftover);
     394      644914 :       if (want > bytes)
     395      387478 :         want = bytes;
     396      644914 :       buf_cpy (ctx->buffer + ctx->leftover, m, want);
     397      644914 :       bytes -= want;
     398      644914 :       m += want;
     399      644914 :       ctx->leftover += want;
     400      644914 :       if (ctx->leftover < block_size)
     401      387478 :         return;
     402      257436 :       burn = ctx->ops->blocks (state, ctx->buffer, block_size);
     403      257436 :       ctx->leftover = 0;
     404             :     }
     405             : 
     406             :   /* process full blocks */
     407      315082 :   if (bytes >= block_size)
     408             :     {
     409       82952 :       size_t want = (bytes & ~(block_size - 1));
     410       82952 :       burn = ctx->ops->blocks (state, m, want);
     411       82952 :       m += want;
     412       82952 :       bytes -= want;
     413             :     }
     414             : 
     415             :   /* store leftover */
     416      315082 :   if (bytes)
     417             :     {
     418      264424 :       buf_cpy (ctx->buffer + ctx->leftover, m, bytes);
     419      264424 :       ctx->leftover += bytes;
     420             :     }
     421             : 
     422      315082 :   if (burn)
     423      213634 :     _gcry_burn_stack (burn);
     424             : }
     425             : 
     426             : 
     427             : void
     428        9074 : _gcry_poly1305_finish (poly1305_context_t * ctx, byte mac[POLY1305_TAGLEN])
     429             : {
     430        9074 :   void *state = poly1305_get_state (ctx);
     431             :   unsigned int burn;
     432             : 
     433        9074 :   burn = ctx->ops->finish_ext (state, ctx->buffer, ctx->leftover, mac);
     434             : 
     435        9074 :   _gcry_burn_stack (burn);
     436        9074 : }
     437             : 
     438             : 
     439             : gcry_err_code_t
     440        9336 : _gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
     441             :                      size_t keylen)
     442             : {
     443             :   static int initialized;
     444             :   static const char *selftest_failed;
     445             :   poly1305_key_t keytmp;
     446        9336 :   unsigned int features = _gcry_get_hw_features ();
     447             : 
     448        9336 :   if (!initialized)
     449             :     {
     450           4 :       initialized = 1;
     451           4 :       selftest_failed = selftest ();
     452           4 :       if (selftest_failed)
     453           0 :         log_error ("Poly1305 selftest failed (%s)\n", selftest_failed);
     454             :     }
     455             : 
     456        9336 :   if (keylen != POLY1305_KEYLEN)
     457           0 :     return GPG_ERR_INV_KEYLEN;
     458             : 
     459        9336 :   if (selftest_failed)
     460           0 :     return GPG_ERR_SELFTEST_FAILED;
     461             : 
     462             : #ifdef POLY1305_USE_SSE2
     463        9336 :   ctx->ops = &poly1305_amd64_sse2_ops;
     464             : #else
     465             :   ctx->ops = &poly1305_default_ops;
     466             : #endif
     467             : 
     468             : #ifdef POLY1305_USE_AVX2
     469        9336 :   if (features & HWF_INTEL_AVX2)
     470           0 :     ctx->ops = &poly1305_amd64_avx2_ops;
     471             : #endif
     472             : #ifdef POLY1305_USE_NEON
     473             :   if (features & HWF_ARM_NEON)
     474             :     ctx->ops = &poly1305_armv7_neon_ops;
     475             : #endif
     476             :   (void)features;
     477             : 
     478        9336 :   buf_cpy (keytmp.b, key, POLY1305_KEYLEN);
     479        9336 :   poly1305_init (ctx, &keytmp);
     480             : 
     481        9336 :   wipememory (&keytmp, sizeof (keytmp));
     482             : 
     483        9336 :   return 0;
     484             : }
     485             : 
     486             : 
     487             : static void
     488        1032 : poly1305_auth (byte mac[POLY1305_TAGLEN], const byte * m, size_t bytes,
     489             :                const byte * key)
     490             : {
     491             :   poly1305_context_t ctx;
     492             : 
     493        1032 :   memset (&ctx, 0, sizeof (ctx));
     494             : 
     495        1032 :   _gcry_poly1305_init (&ctx, key, POLY1305_KEYLEN);
     496        1032 :   _gcry_poly1305_update (&ctx, m, bytes);
     497        1032 :   _gcry_poly1305_finish (&ctx, mac);
     498             : 
     499        1032 :   wipememory (&ctx, sizeof (ctx));
     500        1032 : }
     501             : 
     502             : 
     503             : static const char *
     504           4 : selftest (void)
     505             : {
     506             :   /* example from nacl */
     507             :   static const byte nacl_key[POLY1305_KEYLEN] = {
     508             :     0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91,
     509             :     0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25,
     510             :     0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65,
     511             :     0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80,
     512             :   };
     513             : 
     514             :   static const byte nacl_msg[131] = {
     515             :     0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
     516             :     0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
     517             :     0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
     518             :     0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
     519             :     0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
     520             :     0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
     521             :     0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
     522             :     0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
     523             :     0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
     524             :     0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
     525             :     0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
     526             :     0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
     527             :     0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
     528             :     0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
     529             :     0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
     530             :     0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
     531             :     0xe3, 0x55, 0xa5
     532             :   };
     533             : 
     534             :   static const byte nacl_mac[16] = {
     535             :     0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
     536             :     0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9
     537             :   };
     538             : 
     539             :   /* generates a final value of (2^130 - 2) == 3 */
     540             :   static const byte wrap_key[POLY1305_KEYLEN] = {
     541             :     0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     542             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     543             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     544             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     545             :   };
     546             : 
     547             :   static const byte wrap_msg[16] = {
     548             :     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     549             :     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     550             :   };
     551             : 
     552             :   static const byte wrap_mac[16] = {
     553             :     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     554             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     555             :   };
     556             : 
     557             :   /* mac of the macs of messages of length 0 to 256, where the key and messages
     558             :    * have all their values set to the length
     559             :    */
     560             :   static const byte total_key[POLY1305_KEYLEN] = {
     561             :     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     562             :     0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9,
     563             :     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     564             :     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     565             :   };
     566             : 
     567             :   static const byte total_mac[16] = {
     568             :     0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd,
     569             :     0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39
     570             :   };
     571             : 
     572             :   poly1305_context_t ctx;
     573             :   poly1305_context_t total_ctx;
     574             :   byte all_key[POLY1305_KEYLEN];
     575             :   byte all_msg[256];
     576             :   byte mac[16];
     577             :   size_t i, j;
     578             : 
     579           4 :   memset (&ctx, 0, sizeof (ctx));
     580           4 :   memset (&total_ctx, 0, sizeof (total_ctx));
     581             : 
     582           4 :   memset (mac, 0, sizeof (mac));
     583           4 :   poly1305_auth (mac, nacl_msg, sizeof (nacl_msg), nacl_key);
     584           4 :   if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
     585           0 :     return "Poly1305 test 1 failed.";
     586             : 
     587             :   /* SSE2/AVX have a 32 byte block size, but also support 64 byte blocks, so
     588             :    * make sure everything still works varying between them */
     589           4 :   memset (mac, 0, sizeof (mac));
     590           4 :   _gcry_poly1305_init (&ctx, nacl_key, POLY1305_KEYLEN);
     591           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 0, 32);
     592           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 32, 64);
     593           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 96, 16);
     594           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 112, 8);
     595           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 120, 4);
     596           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 124, 2);
     597           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 126, 1);
     598           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 127, 1);
     599           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 128, 1);
     600           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 129, 1);
     601           4 :   _gcry_poly1305_update (&ctx, nacl_msg + 130, 1);
     602           4 :   _gcry_poly1305_finish (&ctx, mac);
     603           4 :   if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
     604           0 :     return "Poly1305 test 2 failed.";
     605             : 
     606           4 :   memset (mac, 0, sizeof (mac));
     607           4 :   poly1305_auth (mac, wrap_msg, sizeof (wrap_msg), wrap_key);
     608           4 :   if (memcmp (wrap_mac, mac, sizeof (nacl_mac)) != 0)
     609           0 :     return "Poly1305 test 3 failed.";
     610             : 
     611           4 :   _gcry_poly1305_init (&total_ctx, total_key, POLY1305_KEYLEN);
     612        1028 :   for (i = 0; i < 256; i++)
     613             :     {
     614             :       /* set key and message to 'i,i,i..' */
     615       33792 :       for (j = 0; j < sizeof (all_key); j++)
     616       32768 :         all_key[j] = i;
     617      131584 :       for (j = 0; j < i; j++)
     618      130560 :         all_msg[j] = i;
     619        1024 :       poly1305_auth (mac, all_msg, i, all_key);
     620        1024 :       _gcry_poly1305_update (&total_ctx, mac, 16);
     621             :     }
     622           4 :   _gcry_poly1305_finish (&total_ctx, mac);
     623           4 :   if (memcmp (total_mac, mac, sizeof (total_mac)) != 0)
     624           0 :     return "Poly1305 test 4 failed.";
     625             : 
     626           4 :   return NULL;
     627             : }

Generated by: LCOV version 1.13