]> git.ipfire.org Git - thirdparty/nettle.git/blame - umac128.c
Add ChangeLog entry for nettle-3.10 release.
[thirdparty/nettle.git] / umac128.c
CommitLineData
34aef19b 1/* umac128.c
90112edb
NM
2
3 Copyright (C) 2013 Niels Möller
4
5 This file is part of GNU Nettle.
6
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
9
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 or
15
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
19
20 or both in parallel, as here.
21
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
26
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
30*/
34aef19b
NM
31
32#if HAVE_CONFIG_H
33# include "config.h"
34#endif
35
36#include <assert.h>
37#include <string.h>
38
39#include "umac.h"
da81c86a 40#include "umac-internal.h"
34aef19b
NM
41
42#include "macros.h"
43
44void
45umac128_set_key (struct umac128_ctx *ctx, const uint8_t *key)
46{
54a9be1e
NM
47 _nettle_umac_set_key (ctx->l1_key, ctx->l2_key, ctx->l3_key1, ctx->l3_key2,
48 &ctx->pdf_key, key, 4);
34aef19b
NM
49
50 /* Clear nonce */
51 memset (ctx->nonce, 0, sizeof(ctx->nonce));
52 ctx->nonce_length = sizeof(ctx->nonce);
53
54 /* Initialize buffer */
55 ctx->count = ctx->index = 0;
56}
57
58void
59umac128_set_nonce (struct umac128_ctx *ctx,
b8bfc32f 60 size_t nonce_length, const uint8_t *nonce)
34aef19b
NM
61{
62 assert (nonce_length > 0);
63 assert (nonce_length <= AES_BLOCK_SIZE);
64
65 memcpy (ctx->nonce, nonce, nonce_length);
66 memset (ctx->nonce + nonce_length, 0, AES_BLOCK_SIZE - nonce_length);
67
68 ctx->nonce_length = nonce_length;
69}
70
71#define UMAC128_BLOCK(ctx, block) do { \
72 uint64_t __umac128_y[4]; \
54a9be1e 73 _nettle_umac_nh_n (__umac128_y, 4, ctx->l1_key, UMAC_BLOCK_SIZE, block); \
d22bac82
NM
74 __umac128_y[0] += 8*UMAC_BLOCK_SIZE; \
75 __umac128_y[1] += 8*UMAC_BLOCK_SIZE; \
76 __umac128_y[2] += 8*UMAC_BLOCK_SIZE; \
77 __umac128_y[3] += 8*UMAC_BLOCK_SIZE; \
54a9be1e 78 _nettle_umac_l2 (ctx->l2_key, ctx->l2_state, 4, ctx->count++, __umac128_y); \
34aef19b
NM
79 } while (0)
80
81void
82umac128_update (struct umac128_ctx *ctx,
b8bfc32f 83 size_t length, const uint8_t *data)
34aef19b
NM
84{
85 MD_UPDATE (ctx, length, data, UMAC128_BLOCK, (void)0);
86}
87
88
89void
90umac128_digest (struct umac128_ctx *ctx,
b8bfc32f 91 size_t length, uint8_t *digest)
34aef19b
NM
92{
93 uint32_t tag[4];
94 unsigned i;
95
96 assert (length > 0);
97 assert (length <= 16);
98
99 if (ctx->index > 0 || ctx->count == 0)
100 {
101 /* Zero pad to multiple of 32 */
102 uint64_t y[4];
103 unsigned pad = (ctx->index > 0) ? 31 & - ctx->index : 32;
104 memset (ctx->block + ctx->index, 0, pad);
105
54a9be1e 106 _nettle_umac_nh_n (y, 4, ctx->l1_key, ctx->index + pad, ctx->block);
34aef19b
NM
107 y[0] += 8 * ctx->index;
108 y[1] += 8 * ctx->index;
109 y[2] += 8 * ctx->index;
110 y[3] += 8 * ctx->index;
54a9be1e 111 _nettle_umac_l2 (ctx->l2_key, ctx->l2_state, 4, ctx->count++, y);
34aef19b
NM
112 }
113 assert (ctx->count > 0);
114
31a51477
NM
115 aes128_encrypt (&ctx->pdf_key, AES_BLOCK_SIZE,
116 (uint8_t *) tag, ctx->nonce);
34aef19b 117
1d4c756c 118 INCREMENT (ctx->nonce_length, ctx->nonce);
34aef19b 119
54a9be1e 120 _nettle_umac_l2_final (ctx->l2_key, ctx->l2_state, 4, ctx->count);
34aef19b 121 for (i = 0; i < 4; i++)
54a9be1e
NM
122 tag[i] ^= ctx->l3_key2[i] ^ _nettle_umac_l3 (ctx->l3_key1 + 8*i,
123 ctx->l2_state + 2*i);
34aef19b
NM
124
125 memcpy (digest, tag, length);
126
127 /* Reinitialize */
128 ctx->count = ctx->index = 0;
129}