Enable AMD64 SHA512 implementations for WIN64
[libgcrypt.git] / cipher / poly1305.c
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 \f
39
40
41 #ifdef POLY1305_USE_SSE2
42
43 void _gcry_poly1305_amd64_sse2_init_ext(void *state, const poly1305_key_t *key);
44 unsigned int _gcry_poly1305_amd64_sse2_finish_ext(void *state, const byte *m,
45                                                   size_t remaining,
46                                                   byte mac[16]);
47 unsigned int _gcry_poly1305_amd64_sse2_blocks(void *ctx, const byte *m,
48                                               size_t bytes);
49
50 static const poly1305_ops_t poly1305_amd64_sse2_ops = {
51   POLY1305_SSE2_BLOCKSIZE,
52   _gcry_poly1305_amd64_sse2_init_ext,
53   _gcry_poly1305_amd64_sse2_blocks,
54   _gcry_poly1305_amd64_sse2_finish_ext
55 };
56
57 #endif
58
59
60 #ifdef POLY1305_USE_AVX2
61
62 void _gcry_poly1305_amd64_avx2_init_ext(void *state, const poly1305_key_t *key);
63 unsigned int _gcry_poly1305_amd64_avx2_finish_ext(void *state, const byte *m,
64                                                   size_t remaining,
65                                                   byte mac[16]);
66 unsigned int _gcry_poly1305_amd64_avx2_blocks(void *ctx, const byte *m,
67                                               size_t bytes);
68
69 static const poly1305_ops_t poly1305_amd64_avx2_ops = {
70   POLY1305_AVX2_BLOCKSIZE,
71   _gcry_poly1305_amd64_avx2_init_ext,
72   _gcry_poly1305_amd64_avx2_blocks,
73   _gcry_poly1305_amd64_avx2_finish_ext
74 };
75
76 #endif
77
78
79 #ifdef POLY1305_USE_NEON
80
81 void _gcry_poly1305_armv7_neon_init_ext(void *state, const poly1305_key_t *key);
82 unsigned int _gcry_poly1305_armv7_neon_finish_ext(void *state, const byte *m,
83                                                   size_t remaining,
84                                                   byte mac[16]);
85 unsigned int _gcry_poly1305_armv7_neon_blocks(void *ctx, const byte *m,
86                                               size_t bytes);
87
88 static const poly1305_ops_t poly1305_armv7_neon_ops = {
89   POLY1305_NEON_BLOCKSIZE,
90   _gcry_poly1305_armv7_neon_init_ext,
91   _gcry_poly1305_armv7_neon_blocks,
92   _gcry_poly1305_armv7_neon_finish_ext
93 };
94
95 #endif
96
97
98 #ifdef HAVE_U64_TYPEDEF
99
100 /* Reference unoptimized poly1305 implementation using 32 bit * 32 bit = 64 bit
101  * multiplication and 64 bit addition.
102  */
103
104 typedef struct poly1305_state_ref32_s
105 {
106   u32 r[5];
107   u32 h[5];
108   u32 pad[4];
109   byte final;
110 } poly1305_state_ref32_t;
111
112
113 static void
114 poly1305_init_ext_ref32 (void *state, const poly1305_key_t * key)
115 {
116   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
117
118   gcry_assert (sizeof (*st) + POLY1305_STATE_ALIGNMENT <=
119                sizeof (((poly1305_context_t *) 0)->state));
120
121   /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
122   st->r[0] = (buf_get_le32 (&key->b[0])) & 0x3ffffff;
123   st->r[1] = (buf_get_le32 (&key->b[3]) >> 2) & 0x3ffff03;
124   st->r[2] = (buf_get_le32 (&key->b[6]) >> 4) & 0x3ffc0ff;
125   st->r[3] = (buf_get_le32 (&key->b[9]) >> 6) & 0x3f03fff;
126   st->r[4] = (buf_get_le32 (&key->b[12]) >> 8) & 0x00fffff;
127
128   /* h = 0 */
129   st->h[0] = 0;
130   st->h[1] = 0;
131   st->h[2] = 0;
132   st->h[3] = 0;
133   st->h[4] = 0;
134
135   /* save pad for later */
136   st->pad[0] = buf_get_le32 (&key->b[16]);
137   st->pad[1] = buf_get_le32 (&key->b[20]);
138   st->pad[2] = buf_get_le32 (&key->b[24]);
139   st->pad[3] = buf_get_le32 (&key->b[28]);
140
141   st->final = 0;
142 }
143
144
145 static unsigned int
146 poly1305_blocks_ref32 (void *state, const byte * m, size_t bytes)
147 {
148   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
149   const u32 hibit = (st->final) ? 0 : (1 << 24);        /* 1 << 128 */
150   u32 r0, r1, r2, r3, r4;
151   u32 s1, s2, s3, s4;
152   u32 h0, h1, h2, h3, h4;
153   u64 d0, d1, d2, d3, d4;
154   u32 c;
155
156   r0 = st->r[0];
157   r1 = st->r[1];
158   r2 = st->r[2];
159   r3 = st->r[3];
160   r4 = st->r[4];
161
162   s1 = r1 * 5;
163   s2 = r2 * 5;
164   s3 = r3 * 5;
165   s4 = r4 * 5;
166
167   h0 = st->h[0];
168   h1 = st->h[1];
169   h2 = st->h[2];
170   h3 = st->h[3];
171   h4 = st->h[4];
172
173   while (bytes >= POLY1305_REF_BLOCKSIZE)
174     {
175       /* h += m[i] */
176       h0 += (buf_get_le32 (m + 0)) & 0x3ffffff;
177       h1 += (buf_get_le32 (m + 3) >> 2) & 0x3ffffff;
178       h2 += (buf_get_le32 (m + 6) >> 4) & 0x3ffffff;
179       h3 += (buf_get_le32 (m + 9) >> 6) & 0x3ffffff;
180       h4 += (buf_get_le32 (m + 12) >> 8) | hibit;
181
182       /* h *= r */
183       d0 =
184         ((u64) h0 * r0) + ((u64) h1 * s4) +
185         ((u64) h2 * s3) + ((u64) h3 * s2) + ((u64) h4 * s1);
186       d1 =
187         ((u64) h0 * r1) + ((u64) h1 * r0) +
188         ((u64) h2 * s4) + ((u64) h3 * s3) + ((u64) h4 * s2);
189       d2 =
190         ((u64) h0 * r2) + ((u64) h1 * r1) +
191         ((u64) h2 * r0) + ((u64) h3 * s4) + ((u64) h4 * s3);
192       d3 =
193         ((u64) h0 * r3) + ((u64) h1 * r2) +
194         ((u64) h2 * r1) + ((u64) h3 * r0) + ((u64) h4 * s4);
195       d4 =
196         ((u64) h0 * r4) + ((u64) h1 * r3) +
197         ((u64) h2 * r2) + ((u64) h3 * r1) + ((u64) h4 * r0);
198
199       /* (partial) h %= p */
200       c = (u32) (d0 >> 26);
201       h0 = (u32) d0 & 0x3ffffff;
202       d1 += c;
203       c = (u32) (d1 >> 26);
204       h1 = (u32) d1 & 0x3ffffff;
205       d2 += c;
206       c = (u32) (d2 >> 26);
207       h2 = (u32) d2 & 0x3ffffff;
208       d3 += c;
209       c = (u32) (d3 >> 26);
210       h3 = (u32) d3 & 0x3ffffff;
211       d4 += c;
212       c = (u32) (d4 >> 26);
213       h4 = (u32) d4 & 0x3ffffff;
214       h0 += c * 5;
215       c = (h0 >> 26);
216       h0 = h0 & 0x3ffffff;
217       h1 += c;
218
219       m += POLY1305_REF_BLOCKSIZE;
220       bytes -= POLY1305_REF_BLOCKSIZE;
221     }
222
223   st->h[0] = h0;
224   st->h[1] = h1;
225   st->h[2] = h2;
226   st->h[3] = h3;
227   st->h[4] = h4;
228
229   return (16 * sizeof (u32) + 5 * sizeof (u64) + 5 * sizeof (void *));
230 }
231
232
233 static unsigned int
234 poly1305_finish_ext_ref32 (void *state, const byte * m,
235                            size_t remaining, byte mac[POLY1305_TAGLEN])
236 {
237   poly1305_state_ref32_t *st = (poly1305_state_ref32_t *) state;
238   u32 h0, h1, h2, h3, h4, c;
239   u32 g0, g1, g2, g3, g4;
240   u64 f;
241   u32 mask;
242   unsigned int burn = 0;
243
244   /* process the remaining block */
245   if (remaining)
246     {
247       byte final[POLY1305_REF_BLOCKSIZE] = { 0 };
248       size_t i;
249       for (i = 0; i < remaining; i++)
250         final[i] = m[i];
251       final[remaining] = 1;
252       st->final = 1;
253       burn = poly1305_blocks_ref32 (st, final, POLY1305_REF_BLOCKSIZE);
254     }
255
256   /* fully carry h */
257   h0 = st->h[0];
258   h1 = st->h[1];
259   h2 = st->h[2];
260   h3 = st->h[3];
261   h4 = st->h[4];
262
263   c = h1 >> 26;
264   h1 = h1 & 0x3ffffff;
265   h2 += c;
266   c = h2 >> 26;
267   h2 = h2 & 0x3ffffff;
268   h3 += c;
269   c = h3 >> 26;
270   h3 = h3 & 0x3ffffff;
271   h4 += c;
272   c = h4 >> 26;
273   h4 = h4 & 0x3ffffff;
274   h0 += c * 5;
275   c = h0 >> 26;
276   h0 = h0 & 0x3ffffff;
277   h1 += c;
278
279   /* compute h + -p */
280   g0 = h0 + 5;
281   c = g0 >> 26;
282   g0 &= 0x3ffffff;
283   g1 = h1 + c;
284   c = g1 >> 26;
285   g1 &= 0x3ffffff;
286   g2 = h2 + c;
287   c = g2 >> 26;
288   g2 &= 0x3ffffff;
289   g3 = h3 + c;
290   c = g3 >> 26;
291   g3 &= 0x3ffffff;
292   g4 = h4 + c - (1 << 26);
293
294   /* select h if h < p, or h + -p if h >= p */
295   mask = (g4 >> ((sizeof (u32) * 8) - 1)) - 1;
296   g0 &= mask;
297   g1 &= mask;
298   g2 &= mask;
299   g3 &= mask;
300   g4 &= mask;
301   mask = ~mask;
302   h0 = (h0 & mask) | g0;
303   h1 = (h1 & mask) | g1;
304   h2 = (h2 & mask) | g2;
305   h3 = (h3 & mask) | g3;
306   h4 = (h4 & mask) | g4;
307
308   /* h = h % (2^128) */
309   h0 = ((h0) | (h1 << 26)) & 0xffffffff;
310   h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
311   h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
312   h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
313
314   /* mac = (h + pad) % (2^128) */
315   f = (u64) h0 + st->pad[0];
316   h0 = (u32) f;
317   f = (u64) h1 + st->pad[1] + (f >> 32);
318   h1 = (u32) f;
319   f = (u64) h2 + st->pad[2] + (f >> 32);
320   h2 = (u32) f;
321   f = (u64) h3 + st->pad[3] + (f >> 32);
322   h3 = (u32) f;
323
324   buf_put_le32 (mac + 0, h0);
325   buf_put_le32 (mac + 4, h1);
326   buf_put_le32 (mac + 8, h2);
327   buf_put_le32 (mac + 12, h3);
328
329   /* zero out the state */
330   st->h[0] = 0;
331   st->h[1] = 0;
332   st->h[2] = 0;
333   st->h[3] = 0;
334   st->h[4] = 0;
335   st->r[0] = 0;
336   st->r[1] = 0;
337   st->r[2] = 0;
338   st->r[3] = 0;
339   st->r[4] = 0;
340   st->pad[0] = 0;
341   st->pad[1] = 0;
342   st->pad[2] = 0;
343   st->pad[3] = 0;
344
345   /* burn_stack */
346   return (13 * sizeof (u32) + sizeof (u64) +
347           POLY1305_REF_BLOCKSIZE + 6 * sizeof (void *)) + burn;
348 }
349
350
351 static const poly1305_ops_t poly1305_default_ops = {
352   POLY1305_REF_BLOCKSIZE,
353   poly1305_init_ext_ref32,
354   poly1305_blocks_ref32,
355   poly1305_finish_ext_ref32
356 };
357
358 #else /* !HAVE_U64_TYPEDEF */
359
360 /* Reference unoptimized poly1305 implementation using 8 bit * 8 bit = 16 bit
361  * multiplication and 16 bit addition, used when we don't have 'u64'.
362  */
363
364 typedef struct poly1305_state_ref8_t
365 {
366   byte h[17];
367   byte r[17];
368   byte pad[17];
369   byte final;
370 } poly1305_state_ref8_t;
371
372
373 static void
374 poly1305_init_ext_ref8 (void *state, const poly1305_key_t * key)
375 {
376   poly1305_state_ref8_t *st = (poly1305_state_ref8_t *) state;
377   size_t i;
378
379   /* h = 0 */
380   for (i = 0; i < 17; i++)
381     st->h[i] = 0;
382
383   /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
384   st->r[0] = key->b[0];
385   st->r[1] = key->b[1];
386   st->r[2] = key->b[2];
387   st->r[3] = key->b[3] & 0x0f;
388   st->r[4] = key->b[4] & 0xfc;
389   st->r[5] = key->b[5];
390   st->r[6] = key->b[6];
391   st->r[7] = key->b[7] & 0x0f;
392   st->r[8] = key->b[8] & 0xfc;
393   st->r[9] = key->b[9];
394   st->r[10] = key->b[10];
395   st->r[11] = key->b[11] & 0x0f;
396   st->r[12] = key->b[12] & 0xfc;
397   st->r[13] = key->b[13];
398   st->r[14] = key->b[14];
399   st->r[15] = key->b[15] & 0x0f;
400   st->r[16] = 0;
401
402   /* save pad for later */
403   for (i = 0; i < 16; i++)
404     st->pad[i] = key->b[i + 16];
405   st->pad[16] = 0;
406
407   st->final = 0;
408 }
409
410
411 static void
412 poly1305_add_ref8 (byte h[17], const byte c[17])
413 {
414   u16 u;
415   unsigned int i;
416   for (u = 0, i = 0; i < 17; i++)
417     {
418       u += (u16) h[i] + (u16) c[i];
419       h[i] = (byte) u & 0xff;
420       u >>= 8;
421     }
422 }
423
424
425 static void
426 poly1305_squeeze_ref8 (byte h[17], u32 hr[17])
427 {
428   u32 u;
429   unsigned int i;
430   u = 0;
431   for (i = 0; i < 16; i++)
432     {
433       u += hr[i];
434       h[i] = (byte) u & 0xff;
435       u >>= 8;
436     }
437   u += hr[16];
438   h[16] = (byte) u & 0x03;
439   u >>= 2;
440   u += (u << 2);                /* u *= 5; */
441   for (i = 0; i < 16; i++)
442     {
443       u += h[i];
444       h[i] = (byte) u & 0xff;
445       u >>= 8;
446     }
447   h[16] += (byte) u;
448 }
449
450
451 static void
452 poly1305_freeze_ref8 (byte h[17])
453 {
454   static const byte minusp[17] = {
455     0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457     0xfc
458   };
459   byte horig[17], negative;
460   unsigned int i;
461
462   /* compute h + -p */
463   for (i = 0; i < 17; i++)
464     horig[i] = h[i];
465   poly1305_add_ref8 (h, minusp);
466
467   /* select h if h < p, or h + -p if h >= p */
468   negative = -(h[16] >> 7);
469   for (i = 0; i < 17; i++)
470     h[i] ^= negative & (horig[i] ^ h[i]);
471 }
472
473
474 static unsigned int
475 poly1305_blocks_ref8 (void *state, const byte * m, size_t bytes)
476 {
477   poly1305_state_ref8_t *st = (poly1305_state_ref8_t *) state;
478   const byte hibit = st->final ^ 1;     /* 1 << 128 */
479
480   while (bytes >= POLY1305_REF_BLOCKSIZE)
481     {
482       u32 hr[17], u;
483       byte c[17];
484       unsigned int i, j;
485
486       /* h += m */
487       for (i = 0; i < 16; i++)
488         c[i] = m[i];
489       c[16] = hibit;
490       poly1305_add_ref8 (st->h, c);
491
492       /* h *= r */
493       for (i = 0; i < 17; i++)
494         {
495           u = 0;
496           for (j = 0; j <= i; j++)
497             {
498               u += (u16) st->h[j] * st->r[i - j];
499             }
500           for (j = i + 1; j < 17; j++)
501             {
502               u32 v = (u16) st->h[j] * st->r[i + 17 - j];
503               v = ((v << 8) + (v << 6));        /* v *= (5 << 6); */
504               u += v;
505             }
506           hr[i] = u;
507         }
508
509       /* (partial) h %= p */
510       poly1305_squeeze_ref8 (st->h, hr);
511
512       m += POLY1305_REF_BLOCKSIZE;
513       bytes -= POLY1305_REF_BLOCKSIZE;
514     }
515
516   /* burn_stack */
517   return (18 + 2) * sizeof (u32) + 18 + 6 * sizeof (void *) +
518     6 * sizeof (void *);
519 }
520
521
522 static unsigned int
523 poly1305_finish_ext_ref8 (void *state, const byte * m, size_t remaining,
524                           byte mac[POLY1305_TAGLEN])
525 {
526   poly1305_state_ref8_t *st = (poly1305_state_ref8_t *) state;
527   size_t i;
528   unsigned int burn = 0;
529
530   /* process the remaining block */
531   if (remaining)
532     {
533       byte final[POLY1305_REF_BLOCKSIZE] = { 0 };
534       for (i = 0; i < remaining; i++)
535         final[i] = m[i];
536       final[remaining] = 1;
537       st->final = 1;
538       burn = poly1305_blocks_ref8 (st, final, POLY1305_REF_BLOCKSIZE);
539     }
540
541   /* fully reduce h */
542   poly1305_freeze_ref8 (st->h);
543
544   /* h = (h + pad) % (1 << 128) */
545   poly1305_add_ref8 (st->h, st->pad);
546   for (i = 0; i < 16; i++)
547     mac[i] = st->h[i];
548
549   /* zero out the state */
550   for (i = 0; i < 17; i++)
551     st->h[i] = 0;
552   for (i = 0; i < 17; i++)
553     st->r[i] = 0;
554   for (i = 0; i < 17; i++)
555     st->pad[i] = 0;
556
557   /* burn_stack */
558   return POLY1305_REF_BLOCKSIZE + 18 + 16 * sizeof (void *) + burn;
559 }
560
561
562 static const poly1305_ops_t poly1305_default_ops = {
563   POLY1305_REF_BLOCKSIZE,
564   poly1305_init_ext_ref8,
565   poly1305_blocks_ref8,
566   poly1305_finish_ext_ref8
567 };
568
569 #endif /* HAVE_U64_TYPEDEF */
570 \f
571
572
573 static inline void *
574 poly1305_get_state (poly1305_context_t * ctx)
575 {
576   byte *c = ctx->state;
577   c += POLY1305_STATE_ALIGNMENT - 1;
578   c -= (uintptr_t) c & (POLY1305_STATE_ALIGNMENT - 1);
579   return c;
580 }
581
582
583 static void
584 poly1305_init (poly1305_context_t * ctx, const poly1305_key_t * key)
585 {
586   void *state = poly1305_get_state (ctx);
587
588   ctx->leftover = 0;
589
590   ctx->ops->init_ext (state, key);
591 }
592
593
594 void
595 _gcry_poly1305_update (poly1305_context_t * ctx, const byte * m, size_t bytes)
596 {
597   void *state = poly1305_get_state (ctx);
598   unsigned int burn = 0;
599   size_t block_size = ctx->ops->block_size;
600
601   /* handle leftover */
602   if (ctx->leftover)
603     {
604       size_t want = (block_size - ctx->leftover);
605       if (want > bytes)
606         want = bytes;
607       buf_cpy (ctx->buffer + ctx->leftover, m, want);
608       bytes -= want;
609       m += want;
610       ctx->leftover += want;
611       if (ctx->leftover < block_size)
612         return;
613       burn = ctx->ops->blocks (state, ctx->buffer, block_size);
614       ctx->leftover = 0;
615     }
616
617   /* process full blocks */
618   if (bytes >= block_size)
619     {
620       size_t want = (bytes & ~(block_size - 1));
621       burn = ctx->ops->blocks (state, m, want);
622       m += want;
623       bytes -= want;
624     }
625
626   /* store leftover */
627   if (bytes)
628     {
629       buf_cpy (ctx->buffer + ctx->leftover, m, bytes);
630       ctx->leftover += bytes;
631     }
632
633   if (burn)
634     _gcry_burn_stack (burn);
635 }
636
637
638 void
639 _gcry_poly1305_finish (poly1305_context_t * ctx, byte mac[POLY1305_TAGLEN])
640 {
641   void *state = poly1305_get_state (ctx);
642   unsigned int burn;
643
644   burn = ctx->ops->finish_ext (state, ctx->buffer, ctx->leftover, mac);
645
646   _gcry_burn_stack (burn);
647 }
648
649
650 gcry_err_code_t
651 _gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
652                      size_t keylen)
653 {
654   static int initialized;
655   static const char *selftest_failed;
656   poly1305_key_t keytmp;
657   unsigned int features = _gcry_get_hw_features ();
658
659   if (!initialized)
660     {
661       initialized = 1;
662       selftest_failed = selftest ();
663       if (selftest_failed)
664         log_error ("Poly1305 selftest failed (%s)\n", selftest_failed);
665     }
666
667   if (keylen != POLY1305_KEYLEN)
668     return GPG_ERR_INV_KEYLEN;
669
670   if (selftest_failed)
671     return GPG_ERR_SELFTEST_FAILED;
672
673 #ifdef POLY1305_USE_SSE2
674   ctx->ops = &poly1305_amd64_sse2_ops;
675 #else
676   ctx->ops = &poly1305_default_ops;
677 #endif
678
679 #ifdef POLY1305_USE_AVX2
680   if (features & HWF_INTEL_AVX2)
681     ctx->ops = &poly1305_amd64_avx2_ops;
682 #endif
683 #ifdef POLY1305_USE_NEON
684   if (features & HWF_ARM_NEON)
685     ctx->ops = &poly1305_armv7_neon_ops;
686 #endif
687   (void)features;
688
689   buf_cpy (keytmp.b, key, POLY1305_KEYLEN);
690   poly1305_init (ctx, &keytmp);
691
692   wipememory (&keytmp, sizeof (keytmp));
693
694   return 0;
695 }
696
697
698 static void
699 poly1305_auth (byte mac[POLY1305_TAGLEN], const byte * m, size_t bytes,
700                const byte * key)
701 {
702   poly1305_context_t ctx;
703
704   memset (&ctx, 0, sizeof (ctx));
705
706   _gcry_poly1305_init (&ctx, key, POLY1305_KEYLEN);
707   _gcry_poly1305_update (&ctx, m, bytes);
708   _gcry_poly1305_finish (&ctx, mac);
709
710   wipememory (&ctx, sizeof (ctx));
711 }
712
713
714 static const char *
715 selftest (void)
716 {
717   /* example from nacl */
718   static const byte nacl_key[POLY1305_KEYLEN] = {
719     0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91,
720     0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25,
721     0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65,
722     0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80,
723   };
724
725   static const byte nacl_msg[131] = {
726     0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
727     0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
728     0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
729     0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
730     0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
731     0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
732     0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
733     0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
734     0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
735     0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
736     0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
737     0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
738     0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
739     0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
740     0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
741     0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
742     0xe3, 0x55, 0xa5
743   };
744
745   static const byte nacl_mac[16] = {
746     0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
747     0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9
748   };
749
750   /* generates a final value of (2^130 - 2) == 3 */
751   static const byte wrap_key[POLY1305_KEYLEN] = {
752     0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
753     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756   };
757
758   static const byte wrap_msg[16] = {
759     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
760     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
761   };
762
763   static const byte wrap_mac[16] = {
764     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
765     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
766   };
767
768   /* mac of the macs of messages of length 0 to 256, where the key and messages
769    * have all their values set to the length
770    */
771   static const byte total_key[POLY1305_KEYLEN] = {
772     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
773     0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9,
774     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
775     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
776   };
777
778   static const byte total_mac[16] = {
779     0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd,
780     0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39
781   };
782
783   poly1305_context_t ctx;
784   poly1305_context_t total_ctx;
785   byte all_key[POLY1305_KEYLEN];
786   byte all_msg[256];
787   byte mac[16];
788   size_t i, j;
789
790   memset (&ctx, 0, sizeof (ctx));
791   memset (&total_ctx, 0, sizeof (total_ctx));
792
793   memset (mac, 0, sizeof (mac));
794   poly1305_auth (mac, nacl_msg, sizeof (nacl_msg), nacl_key);
795   if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
796     return "Poly1305 test 1 failed.";
797
798   /* SSE2/AVX have a 32 byte block size, but also support 64 byte blocks, so
799    * make sure everything still works varying between them */
800   memset (mac, 0, sizeof (mac));
801   _gcry_poly1305_init (&ctx, nacl_key, POLY1305_KEYLEN);
802   _gcry_poly1305_update (&ctx, nacl_msg + 0, 32);
803   _gcry_poly1305_update (&ctx, nacl_msg + 32, 64);
804   _gcry_poly1305_update (&ctx, nacl_msg + 96, 16);
805   _gcry_poly1305_update (&ctx, nacl_msg + 112, 8);
806   _gcry_poly1305_update (&ctx, nacl_msg + 120, 4);
807   _gcry_poly1305_update (&ctx, nacl_msg + 124, 2);
808   _gcry_poly1305_update (&ctx, nacl_msg + 126, 1);
809   _gcry_poly1305_update (&ctx, nacl_msg + 127, 1);
810   _gcry_poly1305_update (&ctx, nacl_msg + 128, 1);
811   _gcry_poly1305_update (&ctx, nacl_msg + 129, 1);
812   _gcry_poly1305_update (&ctx, nacl_msg + 130, 1);
813   _gcry_poly1305_finish (&ctx, mac);
814   if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
815     return "Poly1305 test 2 failed.";
816
817   memset (mac, 0, sizeof (mac));
818   poly1305_auth (mac, wrap_msg, sizeof (wrap_msg), wrap_key);
819   if (memcmp (wrap_mac, mac, sizeof (nacl_mac)) != 0)
820     return "Poly1305 test 3 failed.";
821
822   _gcry_poly1305_init (&total_ctx, total_key, POLY1305_KEYLEN);
823   for (i = 0; i < 256; i++)
824     {
825       /* set key and message to 'i,i,i..' */
826       for (j = 0; j < sizeof (all_key); j++)
827         all_key[j] = i;
828       for (j = 0; j < i; j++)
829         all_msg[j] = i;
830       poly1305_auth (mac, all_msg, i, all_key);
831       _gcry_poly1305_update (&total_ctx, mac, 16);
832     }
833   _gcry_poly1305_finish (&total_ctx, mac);
834   if (memcmp (total_mac, mac, sizeof (total_mac)) != 0)
835     return "Poly1305 test 4 failed.";
836
837   return NULL;
838 }