Coverage Report

Created: 2024-11-21 07:03

/src/mbedtls/library/poly1305.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * \file poly1305.c
3
 *
4
 * \brief Poly1305 authentication algorithm.
5
 *
6
 *  Copyright The Mbed TLS Contributors
7
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
8
 */
9
#include "common.h"
10
11
#if defined(MBEDTLS_POLY1305_C)
12
13
#include "mbedtls/poly1305.h"
14
#include "mbedtls/platform_util.h"
15
#include "mbedtls/error.h"
16
17
#include <string.h>
18
19
#include "mbedtls/platform.h"
20
21
#if !defined(MBEDTLS_POLY1305_ALT)
22
23
554
#define POLY1305_BLOCK_SIZE_BYTES (16U)
24
25
/*
26
 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
27
 * However we provided an alternative for platforms without such a multiplier.
28
 */
29
#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
30
static uint64_t mul64(uint32_t a, uint32_t b)
31
{
32
    /* a = al + 2**16 ah, b = bl + 2**16 bh */
33
    const uint16_t al = (uint16_t) a;
34
    const uint16_t bl = (uint16_t) b;
35
    const uint16_t ah = a >> 16;
36
    const uint16_t bh = b >> 16;
37
38
    /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
39
    const uint32_t lo = (uint32_t) al * bl;
40
    const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh;
41
    const uint32_t hi = (uint32_t) ah * bh;
42
43
    return lo + (me << 16) + ((uint64_t) hi << 32);
44
}
45
#else
46
static inline uint64_t mul64(uint32_t a, uint32_t b)
47
2.71k
{
48
2.71k
    return (uint64_t) a * b;
49
2.71k
}
50
#endif
51
52
53
/**
54
 * \brief                   Process blocks with Poly1305.
55
 *
56
 * \param ctx               The Poly1305 context.
57
 * \param nblocks           Number of blocks to process. Note that this
58
 *                          function only processes full blocks.
59
 * \param input             Buffer containing the input block(s).
60
 * \param needs_padding     Set to 0 if the padding bit has already been
61
 *                          applied to the input data before calling this
62
 *                          function.  Otherwise, set this parameter to 1.
63
 */
64
static void poly1305_process(mbedtls_poly1305_context *ctx,
65
                             size_t nblocks,
66
                             const unsigned char *input,
67
                             uint32_t needs_padding)
68
108
{
69
108
    uint64_t d0, d1, d2, d3;
70
108
    uint32_t acc0, acc1, acc2, acc3, acc4;
71
108
    uint32_t r0, r1, r2, r3;
72
108
    uint32_t rs1, rs2, rs3;
73
108
    size_t offset  = 0U;
74
108
    size_t i;
75
76
108
    r0 = ctx->r[0];
77
108
    r1 = ctx->r[1];
78
108
    r2 = ctx->r[2];
79
108
    r3 = ctx->r[3];
80
81
108
    rs1 = r1 + (r1 >> 2U);
82
108
    rs2 = r2 + (r2 >> 2U);
83
108
    rs3 = r3 + (r3 >> 2U);
84
85
108
    acc0 = ctx->acc[0];
86
108
    acc1 = ctx->acc[1];
87
108
    acc2 = ctx->acc[2];
88
108
    acc3 = ctx->acc[3];
89
108
    acc4 = ctx->acc[4];
90
91
    /* Process full blocks */
92
251
    for (i = 0U; i < nblocks; i++) {
93
        /* The input block is treated as a 128-bit little-endian integer */
94
143
        d0   = MBEDTLS_GET_UINT32_LE(input, offset + 0);
95
143
        d1   = MBEDTLS_GET_UINT32_LE(input, offset + 4);
96
143
        d2   = MBEDTLS_GET_UINT32_LE(input, offset + 8);
97
143
        d3   = MBEDTLS_GET_UINT32_LE(input, offset + 12);
98
99
        /* Compute: acc += (padded) block as a 130-bit integer */
100
143
        d0  += (uint64_t) acc0;
101
143
        d1  += (uint64_t) acc1 + (d0 >> 32U);
102
143
        d2  += (uint64_t) acc2 + (d1 >> 32U);
103
143
        d3  += (uint64_t) acc3 + (d2 >> 32U);
104
143
        acc0 = (uint32_t) d0;
105
143
        acc1 = (uint32_t) d1;
106
143
        acc2 = (uint32_t) d2;
107
143
        acc3 = (uint32_t) d3;
108
143
        acc4 += (uint32_t) (d3 >> 32U) + needs_padding;
109
110
        /* Compute: acc *= r */
111
143
        d0 = mul64(acc0, r0) +
112
143
             mul64(acc1, rs3) +
113
143
             mul64(acc2, rs2) +
114
143
             mul64(acc3, rs1);
115
143
        d1 = mul64(acc0, r1) +
116
143
             mul64(acc1, r0) +
117
143
             mul64(acc2, rs3) +
118
143
             mul64(acc3, rs2) +
119
143
             mul64(acc4, rs1);
120
143
        d2 = mul64(acc0, r2) +
121
143
             mul64(acc1, r1) +
122
143
             mul64(acc2, r0) +
123
143
             mul64(acc3, rs3) +
124
143
             mul64(acc4, rs2);
125
143
        d3 = mul64(acc0, r3) +
126
143
             mul64(acc1, r2) +
127
143
             mul64(acc2, r1) +
128
143
             mul64(acc3, r0) +
129
143
             mul64(acc4, rs3);
130
143
        acc4 *= r0;
131
132
        /* Compute: acc %= (2^130 - 5) (partial remainder) */
133
143
        d1 += (d0 >> 32);
134
143
        d2 += (d1 >> 32);
135
143
        d3 += (d2 >> 32);
136
143
        acc0 = (uint32_t) d0;
137
143
        acc1 = (uint32_t) d1;
138
143
        acc2 = (uint32_t) d2;
139
143
        acc3 = (uint32_t) d3;
140
143
        acc4 = (uint32_t) (d3 >> 32) + acc4;
141
142
143
        d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
143
143
        acc4 &= 3U;
144
143
        acc0 = (uint32_t) d0;
145
143
        d0 = (uint64_t) acc1 + (d0 >> 32U);
146
143
        acc1 = (uint32_t) d0;
147
143
        d0 = (uint64_t) acc2 + (d0 >> 32U);
148
143
        acc2 = (uint32_t) d0;
149
143
        d0 = (uint64_t) acc3 + (d0 >> 32U);
150
143
        acc3 = (uint32_t) d0;
151
143
        d0 = (uint64_t) acc4 + (d0 >> 32U);
152
143
        acc4 = (uint32_t) d0;
153
154
143
        offset    += POLY1305_BLOCK_SIZE_BYTES;
155
143
    }
156
157
108
    ctx->acc[0] = acc0;
158
108
    ctx->acc[1] = acc1;
159
108
    ctx->acc[2] = acc2;
160
108
    ctx->acc[3] = acc3;
161
108
    ctx->acc[4] = acc4;
162
108
}
163
164
/**
165
 * \brief                   Compute the Poly1305 MAC
166
 *
167
 * \param ctx               The Poly1305 context.
168
 * \param mac               The buffer to where the MAC is written. Must be
169
 *                          big enough to contain the 16-byte MAC.
170
 */
171
static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
172
                                 unsigned char mac[16])
173
36
{
174
36
    uint64_t d;
175
36
    uint32_t g0, g1, g2, g3, g4;
176
36
    uint32_t acc0, acc1, acc2, acc3, acc4;
177
36
    uint32_t mask;
178
36
    uint32_t mask_inv;
179
180
36
    acc0 = ctx->acc[0];
181
36
    acc1 = ctx->acc[1];
182
36
    acc2 = ctx->acc[2];
183
36
    acc3 = ctx->acc[3];
184
36
    acc4 = ctx->acc[4];
185
186
    /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
187
     * We do this by calculating acc - (2^130 - 5), then checking if
188
     * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
189
     */
190
191
    /* Calculate acc + -(2^130 - 5) */
192
36
    d  = ((uint64_t) acc0 + 5U);
193
36
    g0 = (uint32_t) d;
194
36
    d  = ((uint64_t) acc1 + (d >> 32));
195
36
    g1 = (uint32_t) d;
196
36
    d  = ((uint64_t) acc2 + (d >> 32));
197
36
    g2 = (uint32_t) d;
198
36
    d  = ((uint64_t) acc3 + (d >> 32));
199
36
    g3 = (uint32_t) d;
200
36
    g4 = acc4 + (uint32_t) (d >> 32U);
201
202
    /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
203
36
    mask = (uint32_t) 0U - (g4 >> 2U);
204
36
    mask_inv = ~mask;
205
206
    /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
207
36
    acc0 = (acc0 & mask_inv) | (g0 & mask);
208
36
    acc1 = (acc1 & mask_inv) | (g1 & mask);
209
36
    acc2 = (acc2 & mask_inv) | (g2 & mask);
210
36
    acc3 = (acc3 & mask_inv) | (g3 & mask);
211
212
    /* Add 's' */
213
36
    d = (uint64_t) acc0 + ctx->s[0];
214
36
    acc0 = (uint32_t) d;
215
36
    d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
216
36
    acc1 = (uint32_t) d;
217
36
    d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
218
36
    acc2 = (uint32_t) d;
219
36
    acc3 += ctx->s[3] + (uint32_t) (d >> 32U);
220
221
    /* Compute MAC (128 least significant bits of the accumulator) */
222
36
    MBEDTLS_PUT_UINT32_LE(acc0, mac,  0);
223
36
    MBEDTLS_PUT_UINT32_LE(acc1, mac,  4);
224
36
    MBEDTLS_PUT_UINT32_LE(acc2, mac,  8);
225
36
    MBEDTLS_PUT_UINT32_LE(acc3, mac, 12);
226
36
}
227
228
void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
229
82
{
230
82
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
231
82
}
232
233
void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
234
82
{
235
82
    if (ctx == NULL) {
236
0
        return;
237
0
    }
238
239
82
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
240
82
}
241
242
int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
243
                            const unsigned char key[32])
244
44
{
245
    /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
246
44
    ctx->r[0] = MBEDTLS_GET_UINT32_LE(key, 0)  & 0x0FFFFFFFU;
247
44
    ctx->r[1] = MBEDTLS_GET_UINT32_LE(key, 4)  & 0x0FFFFFFCU;
248
44
    ctx->r[2] = MBEDTLS_GET_UINT32_LE(key, 8)  & 0x0FFFFFFCU;
249
44
    ctx->r[3] = MBEDTLS_GET_UINT32_LE(key, 12) & 0x0FFFFFFCU;
250
251
44
    ctx->s[0] = MBEDTLS_GET_UINT32_LE(key, 16);
252
44
    ctx->s[1] = MBEDTLS_GET_UINT32_LE(key, 20);
253
44
    ctx->s[2] = MBEDTLS_GET_UINT32_LE(key, 24);
254
44
    ctx->s[3] = MBEDTLS_GET_UINT32_LE(key, 28);
255
256
    /* Initial accumulator state */
257
44
    ctx->acc[0] = 0U;
258
44
    ctx->acc[1] = 0U;
259
44
    ctx->acc[2] = 0U;
260
44
    ctx->acc[3] = 0U;
261
44
    ctx->acc[4] = 0U;
262
263
    /* Queue initially empty */
264
44
    mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
265
44
    ctx->queue_len = 0U;
266
267
44
    return 0;
268
44
}
269
270
int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
271
                            const unsigned char *input,
272
                            size_t ilen)
273
161
{
274
161
    size_t offset    = 0U;
275
161
    size_t remaining = ilen;
276
161
    size_t queue_free_len;
277
161
    size_t nblocks;
278
279
161
    if ((remaining > 0U) && (ctx->queue_len > 0U)) {
280
37
        queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
281
282
37
        if (ilen < queue_free_len) {
283
            /* Not enough data to complete the block.
284
             * Store this data with the other leftovers.
285
             */
286
0
            memcpy(&ctx->queue[ctx->queue_len],
287
0
                   input,
288
0
                   ilen);
289
290
0
            ctx->queue_len += ilen;
291
292
0
            remaining = 0U;
293
37
        } else {
294
            /* Enough data to produce a complete block */
295
37
            memcpy(&ctx->queue[ctx->queue_len],
296
37
                   input,
297
37
                   queue_free_len);
298
299
37
            ctx->queue_len = 0U;
300
301
37
            poly1305_process(ctx, 1U, ctx->queue, 1U);   /* add padding bit */
302
303
37
            offset    += queue_free_len;
304
37
            remaining -= queue_free_len;
305
37
        }
306
37
    }
307
308
161
    if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
309
71
        nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
310
311
71
        poly1305_process(ctx, nblocks, &input[offset], 1U);
312
313
71
        offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
314
71
        remaining %= POLY1305_BLOCK_SIZE_BYTES;
315
71
    }
316
317
161
    if (remaining > 0U) {
318
        /* Store partial block */
319
45
        ctx->queue_len = remaining;
320
45
        memcpy(ctx->queue, &input[offset], remaining);
321
45
    }
322
323
161
    return 0;
324
161
}
325
326
int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
327
                            unsigned char mac[16])
328
36
{
329
    /* Process any leftover data */
330
36
    if (ctx->queue_len > 0U) {
331
        /* Add padding bit */
332
0
        ctx->queue[ctx->queue_len] = 1U;
333
0
        ctx->queue_len++;
334
335
        /* Pad with zeroes */
336
0
        memset(&ctx->queue[ctx->queue_len],
337
0
               0,
338
0
               POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
339
340
0
        poly1305_process(ctx, 1U,           /* Process 1 block */
341
0
                         ctx->queue, 0U);   /* Already padded above */
342
0
    }
343
344
36
    poly1305_compute_mac(ctx, mac);
345
346
36
    return 0;
347
36
}
348
349
int mbedtls_poly1305_mac(const unsigned char key[32],
350
                         const unsigned char *input,
351
                         size_t ilen,
352
                         unsigned char mac[16])
353
0
{
354
0
    mbedtls_poly1305_context ctx;
355
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
356
357
0
    mbedtls_poly1305_init(&ctx);
358
359
0
    ret = mbedtls_poly1305_starts(&ctx, key);
360
0
    if (ret != 0) {
361
0
        goto cleanup;
362
0
    }
363
364
0
    ret = mbedtls_poly1305_update(&ctx, input, ilen);
365
0
    if (ret != 0) {
366
0
        goto cleanup;
367
0
    }
368
369
0
    ret = mbedtls_poly1305_finish(&ctx, mac);
370
371
0
cleanup:
372
0
    mbedtls_poly1305_free(&ctx);
373
0
    return ret;
374
0
}
375
376
#endif /* MBEDTLS_POLY1305_ALT */
377
378
#if defined(MBEDTLS_SELF_TEST)
379
380
static const unsigned char test_keys[2][32] =
381
{
382
    {
383
        0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
384
        0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
385
        0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
386
        0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
387
    },
388
    {
389
        0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
390
        0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
391
        0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
392
        0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
393
    }
394
};
395
396
static const unsigned char test_data[2][127] =
397
{
398
    {
399
        0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
400
        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
401
        0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
402
        0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
403
        0x75, 0x70
404
    },
405
    {
406
        0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
407
        0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
408
        0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
409
        0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
410
        0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
411
        0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
412
        0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
413
        0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
414
        0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
415
        0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
416
        0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
417
        0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
418
        0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
419
        0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
420
        0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
421
        0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
422
    }
423
};
424
425
static const size_t test_data_len[2] =
426
{
427
    34U,
428
    127U
429
};
430
431
static const unsigned char test_mac[2][16] =
432
{
433
    {
434
        0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
435
        0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
436
    },
437
    {
438
        0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
439
        0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
440
    }
441
};
442
443
/* Make sure no other definition is already present. */
444
#undef ASSERT
445
446
#define ASSERT(cond, args)            \
447
0
    do                                  \
448
0
    {                                   \
449
0
        if (!(cond))                \
450
0
        {                               \
451
0
            if (verbose != 0)          \
452
0
            mbedtls_printf args;    \
453
0
                                        \
454
0
            return -1;               \
455
0
        }                               \
456
0
    }                                   \
457
0
    while (0)
458
459
int mbedtls_poly1305_self_test(int verbose)
460
0
{
461
0
    unsigned char mac[16];
462
0
    unsigned i;
463
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
464
465
0
    for (i = 0U; i < 2U; i++) {
466
0
        if (verbose != 0) {
467
0
            mbedtls_printf("  Poly1305 test %u ", i);
468
0
        }
469
470
0
        ret = mbedtls_poly1305_mac(test_keys[i],
471
0
                                   test_data[i],
472
0
                                   test_data_len[i],
473
0
                                   mac);
474
0
        ASSERT(0 == ret, ("error code: %i\n", ret));
475
476
0
        ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
477
478
0
        if (verbose != 0) {
479
0
            mbedtls_printf("passed\n");
480
0
        }
481
0
    }
482
483
0
    if (verbose != 0) {
484
0
        mbedtls_printf("\n");
485
0
    }
486
487
0
    return 0;
488
0
}
489
490
#endif /* MBEDTLS_SELF_TEST */
491
492
#endif /* MBEDTLS_POLY1305_C */