Coverage Report

Created: 2024-01-20 12:32

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