]> git.ipfire.org Git - thirdparty/nettle.git/blame - gcm.c
Add ChangeLog entry for nettle-3.10 release.
[thirdparty/nettle.git] / gcm.c
CommitLineData
018d8bcd 1/* gcm.c
90112edb
NM
2
3 Galois counter mode, specified by NIST,
4 http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
5
6 See also the gcm paper at
7 http://www.cryptobarn.com/papers/gcm-spec.pdf.
8
90112edb 9 Copyright (C) 2011 Katholieke Universiteit Leuven
4ff20685
NM
10 Copyright (C) 2011, 2013, 2018 Niels Möller
11 Copyright (C) 2018 Red Hat, Inc.
90112edb
NM
12
13 Contributed by Nikos Mavrogiannopoulos
14
15 This file is part of GNU Nettle.
16
17 GNU Nettle is free software: you can redistribute it and/or
18 modify it under the terms of either:
19
20 * the GNU Lesser General Public License as published by the Free
21 Software Foundation; either version 3 of the License, or (at your
22 option) any later version.
23
24 or
25
26 * the GNU General Public License as published by the Free
27 Software Foundation; either version 2 of the License, or (at your
28 option) any later version.
29
30 or both in parallel, as here.
31
32 GNU Nettle is distributed in the hope that it will be useful,
33 but WITHOUT ANY WARRANTY; without even the implied warranty of
34 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35 General Public License for more details.
36
37 You should have received copies of the GNU General Public License and
38 the GNU Lesser General Public License along with this program. If
39 not, see http://www.gnu.org/licenses/.
40*/
342ad32a
NM
41
42#if HAVE_CONFIG_H
43# include "config.h"
44#endif
45
46#include <assert.h>
47#include <stdlib.h>
48#include <string.h>
49
50#include "gcm.h"
51
1d438ad4 52#include "ghash-internal.h"
342ad32a
NM
53#include "memxor.h"
54#include "nettle-internal.h"
55#include "macros.h"
4ff20685 56#include "ctr-internal.h"
508908b1 57#include "block-internal.h"
ff660604 58#include "bswap-internal.h"
23f75f58 59
342ad32a
NM
60/* Initialization of GCM.
61 * @ctx: The context of GCM
62 * @cipher: The context of the underlying block cipher
63 * @f: The underlying cipher encryption function
64 */
65void
5f07c78b 66gcm_set_key(struct gcm_key *key,
a9b47a42 67 const void *cipher, nettle_cipher_func *f)
342ad32a 68{
23f75f58
NM
69 static const union nettle_block16 zero_block;
70 union nettle_block16 key_block;
71 f (cipher, GCM_BLOCK_SIZE, key_block.b, zero_block.b);
56691ae4 72
1d438ad4 73 _ghash_set_key (key, &key_block);
342ad32a
NM
74}
75
1d438ad4
NM
76/* Call _ghash_update, with zero padding of any partial final block. */
77static void
78gcm_hash (const struct gcm_key *key, union nettle_block16 *x,
79 size_t length, const uint8_t *data) {
80 data = _ghash_update (key, x, length / GCM_BLOCK_SIZE, data);
81 length &= (GCM_BLOCK_SIZE - 1);
342ad32a
NM
82 if (length > 0)
83 {
1d438ad4
NM
84 union nettle_block16 block;
85 block16_zero (&block);
86 memcpy (block.b, data, length);
87 _ghash_update (key, x, 1, block.b);
342ad32a
NM
88 }
89}
90
9924966a 91static void
61d9a6a0 92gcm_hash_sizes(const struct gcm_key *key, union nettle_block16 *x,
890b2365 93 uint64_t auth_size, uint64_t data_size)
9924966a 94{
1d438ad4 95 union nettle_block16 buffer;
9924966a
NM
96
97 data_size *= 8;
98 auth_size *= 8;
99
ff660604
NM
100 buffer.u64[0] = bswap64_if_le (auth_size);
101 buffer.u64[1] = bswap64_if_le (data_size);
9924966a 102
1d438ad4 103 _ghash_update (key, x, 1, buffer.b);
9924966a
NM
104}
105
187631fa 106/* NOTE: The key is needed only if length != GCM_IV_SIZE */
9924966a
NM
107void
108gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
3eb603d0 109 size_t length, const uint8_t *iv)
9924966a
NM
110{
111 if (length == GCM_IV_SIZE)
112 {
113 memcpy (ctx->iv.b, iv, GCM_BLOCK_SIZE - 4);
114 ctx->iv.b[GCM_BLOCK_SIZE - 4] = 0;
115 ctx->iv.b[GCM_BLOCK_SIZE - 3] = 0;
116 ctx->iv.b[GCM_BLOCK_SIZE - 2] = 0;
117 ctx->iv.b[GCM_BLOCK_SIZE - 1] = 1;
118 }
119 else
120 {
1d438ad4
NM
121 block16_zero(&ctx->iv);
122 gcm_hash(key, &ctx->iv, length, iv);
9924966a
NM
123 gcm_hash_sizes(key, &ctx->iv, 0, length);
124 }
125
1d438ad4
NM
126 ctx->ctr = ctx->iv;
127 /* Increment the rightmost 32 bits. */
128 INCREMENT (4, ctx->ctr.b + GCM_BLOCK_SIZE - 4);
9924966a
NM
129
130 /* Reset the rest of the message-dependent state. */
1d438ad4 131 block16_zero(&ctx->x);
9924966a
NM
132 ctx->auth_size = ctx->data_size = 0;
133}
134
342ad32a 135void
4961af0a 136gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key,
b8bfc32f 137 size_t length, const uint8_t *data)
342ad32a
NM
138{
139 assert(ctx->auth_size % GCM_BLOCK_SIZE == 0);
4961af0a 140 assert(ctx->data_size == 0);
342ad32a 141
1d438ad4 142 gcm_hash(key, &ctx->x, length, data);
342ad32a
NM
143
144 ctx->auth_size += length;
145}
146
4ff20685 147static nettle_fill16_func gcm_fill;
b62e5f5e
NM
148#if WORDS_BIGENDIAN
149static void
150gcm_fill(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
151{
152 uint64_t hi, mid;
153 uint32_t lo;
154 size_t i;
155 hi = READ_UINT64(ctr);
156 mid = (uint64_t) READ_UINT32(ctr + 8) << 32;
157 lo = READ_UINT32(ctr + 12);
158
159 for (i = 0; i < blocks; i++)
160 {
161 buffer[i].u64[0] = hi;
162 buffer[i].u64[1] = mid + lo++;
163 }
164 WRITE_UINT32(ctr + 12, lo);
165
166}
167#elif HAVE_BUILTIN_BSWAP64
168/* Assume __builtin_bswap32 is also available */
169static void
170gcm_fill(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
171{
172 uint64_t hi, mid;
173 uint32_t lo;
174 size_t i;
175 hi = LE_READ_UINT64(ctr);
176 mid = LE_READ_UINT32(ctr + 8);
177 lo = READ_UINT32(ctr + 12);
178
179 for (i = 0; i < blocks; i++)
180 {
181 buffer[i].u64[0] = hi;
182 buffer[i].u64[1] = mid + ((uint64_t)__builtin_bswap32(lo) << 32);
183 lo++;
184 }
185 WRITE_UINT32(ctr + 12, lo);
186}
187#else
342ad32a 188static void
4ff20685 189gcm_fill(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
342ad32a 190{
4ff20685 191 uint32_t c;
342ad32a 192
4ff20685
NM
193 c = READ_UINT32(ctr + GCM_BLOCK_SIZE - 4);
194
195 for (; blocks-- > 0; buffer++, c++)
342ad32a 196 {
4ff20685
NM
197 memcpy(buffer->b, ctr, GCM_BLOCK_SIZE - 4);
198 WRITE_UINT32(buffer->b + GCM_BLOCK_SIZE - 4, c);
342ad32a 199 }
4ff20685
NM
200
201 WRITE_UINT32(ctr + GCM_BLOCK_SIZE - 4, c);
342ad32a 202}
b62e5f5e 203#endif
342ad32a
NM
204
205void
5f07c78b 206gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key,
a9b47a42 207 const void *cipher, nettle_cipher_func *f,
3eb603d0 208 size_t length, uint8_t *dst, const uint8_t *src)
342ad32a
NM
209{
210 assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
211
5ebf7703 212 _nettle_ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src);
1d438ad4 213 gcm_hash(key, &ctx->x, length, dst);
342ad32a
NM
214
215 ctx->data_size += length;
216}
217
218void
5f07c78b 219gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
a9b47a42 220 const void *cipher, nettle_cipher_func *f,
3eb603d0 221 size_t length, uint8_t *dst, const uint8_t *src)
342ad32a
NM
222{
223 assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
224
1d438ad4 225 gcm_hash(key, &ctx->x, length, src);
5ebf7703 226 _nettle_ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src);
342ad32a
NM
227
228 ctx->data_size += length;
229}
230
231void
5f07c78b 232gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
a9b47a42 233 const void *cipher, nettle_cipher_func *f,
b8bfc32f 234 size_t length, uint8_t *digest)
342ad32a 235{
1d438ad4 236 union nettle_block16 buffer;
342ad32a
NM
237
238 assert (length <= GCM_BLOCK_SIZE);
239
9924966a 240 gcm_hash_sizes(key, &ctx->x, ctx->auth_size, ctx->data_size);
342ad32a 241
1d438ad4 242 f (cipher, GCM_BLOCK_SIZE, buffer.b, ctx->iv.b);
d382fcc0 243 block16_xor (&buffer, &ctx->x);
1d438ad4 244 memcpy (digest, buffer.b, length);
342ad32a
NM
245
246 return;
247}