File Coverage

src/chacha/poly1305.c
Criterion Covered Total %
statement 75 86 87.2
branch 8 10 80.0
condition n/a
subroutine n/a
pod n/a
total 83 96 86.4


line stmt bran cond sub pod time code
1             /*
2             * Public Domain poly1305 from Andrew Moon
3             * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
4             */
5              
6             /* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */
7              
8             #include
9             #include
10             #include "poly1305.h"
11              
12             #define mul32x32_64(a,b) ((uint64_t)(a) * (b))
13              
14             #ifndef U8TO32_LE
15             #define U8TO32_LE(p) \
16             (((uint32_t)((p)[0])) | \
17             ((uint32_t)((p)[1]) << 8) | \
18             ((uint32_t)((p)[2]) << 16) | \
19             ((uint32_t)((p)[3]) << 24))
20             #endif
21              
22             #define U32TO8_LE(p, v) \
23             do { \
24             (p)[0] = (uint8_t)((v)); \
25             (p)[1] = (uint8_t)((v) >> 8); \
26             (p)[2] = (uint8_t)((v) >> 16); \
27             (p)[3] = (uint8_t)((v) >> 24); \
28             } while (0)
29              
30             void
31 6           poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
32             uint32_t t0,t1,t2,t3;
33             uint32_t h0,h1,h2,h3,h4;
34             uint32_t r0,r1,r2,r3,r4;
35             uint32_t s1,s2,s3,s4;
36             uint32_t b, nb;
37             size_t j;
38             uint64_t t[5];
39             uint64_t f0,f1,f2,f3;
40             uint32_t g0,g1,g2,g3,g4;
41             uint64_t c;
42             unsigned char mp[16];
43              
44             /* clamp key */
45 6           t0 = U8TO32_LE(key+0);
46 6           t1 = U8TO32_LE(key+4);
47 6           t2 = U8TO32_LE(key+8);
48 6           t3 = U8TO32_LE(key+12);
49              
50             /* precompute multipliers */
51 6           r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
52 6           r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
53 6           r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
54 6           r3 = t2 & 0x3f03fff; t3 >>= 8;
55 6           r4 = t3 & 0x00fffff;
56              
57 6           s1 = r1 * 5;
58 6           s2 = r2 * 5;
59 6           s3 = r3 * 5;
60 6           s4 = r4 * 5;
61              
62             /* init state */
63 6           h0 = 0;
64 6           h1 = 0;
65 6           h2 = 0;
66 6           h3 = 0;
67 6           h4 = 0;
68              
69             /* full blocks */
70 6 50         if (inlen < 16) goto poly1305_donna_atmost15bytes;
71             poly1305_donna_16bytes:
72 0           m += 16;
73 0           inlen -= 16;
74              
75 0           t0 = U8TO32_LE(m-16);
76 0           t1 = U8TO32_LE(m-12);
77 0           t2 = U8TO32_LE(m-8);
78 0           t3 = U8TO32_LE(m-4);
79              
80 0           h0 += t0 & 0x3ffffff;
81 0           h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
82 0           h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
83 0           h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
84 0           h4 += (t3 >> 8) | (1 << 24);
85              
86              
87             poly1305_donna_mul:
88 6           t[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1);
89 6           t[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2);
90 6           t[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3);
91 6           t[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4);
92 6           t[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0);
93              
94 6           h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26);
95 6           t[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);
96 6           t[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);
97 6           t[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);
98 6           t[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);
99 6           h0 += b * 5;
100              
101 6 50         if (inlen >= 16) goto poly1305_donna_16bytes;
102              
103             /* final bytes */
104             poly1305_donna_atmost15bytes:
105 12 100         if (!inlen) goto poly1305_donna_finish;
106              
107 54 100         for (j = 0; j < inlen; j++) mp[j] = m[j];
108 6           mp[j++] = 1;
109 48 100         for (; j < 16; j++) mp[j] = 0;
110 6           inlen = 0;
111              
112 6           t0 = U8TO32_LE(mp+0);
113 6           t1 = U8TO32_LE(mp+4);
114 6           t2 = U8TO32_LE(mp+8);
115 6           t3 = U8TO32_LE(mp+12);
116              
117 6           h0 += t0 & 0x3ffffff;
118 6           h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
119 6           h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
120 6           h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
121 6           h4 += (t3 >> 8);
122              
123 6           goto poly1305_donna_mul;
124              
125             poly1305_donna_finish:
126 6           b = h0 >> 26; h0 = h0 & 0x3ffffff;
127 6           h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
128 6           h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
129 6           h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
130 6           h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
131 6           h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
132 6           h1 += b;
133              
134 6           g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
135 6           g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
136 6           g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
137 6           g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
138 6           g4 = h4 + b - (1 << 26);
139              
140 6           b = (g4 >> 31) - 1;
141 6           nb = ~b;
142 6           h0 = (h0 & nb) | (g0 & b);
143 6           h1 = (h1 & nb) | (g1 & b);
144 6           h2 = (h2 & nb) | (g2 & b);
145 6           h3 = (h3 & nb) | (g3 & b);
146 6           h4 = (h4 & nb) | (g4 & b);
147              
148 6           f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);
149 6           f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);
150 6           f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);
151 6           f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]);
152              
153 6           U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);
154 6           U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);
155 6           U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);
156 6           U32TO8_LE(&out[12], f3);
157 6           }