Coverage Report

Created: 2023-09-25 06:33

/src/nettle-with-libgmp/ocb.c
Line
Count
Source (jump to first uncovered line)
1
/* ocb.c
2
3
   OCB AEAD mode, RFC 7253
4
5
   Copyright (C) 2021 Niels Möller
6
7
   This file is part of GNU Nettle.
8
9
   GNU Nettle is free software: you can redistribute it and/or
10
   modify it under the terms of either:
11
12
     * the GNU Lesser General Public License as published by the Free
13
       Software Foundation; either version 3 of the License, or (at your
14
       option) any later version.
15
16
   or
17
18
     * the GNU General Public License as published by the Free
19
       Software Foundation; either version 2 of the License, or (at your
20
       option) any later version.
21
22
   or both in parallel, as here.
23
24
   GNU Nettle is distributed in the hope that it will be useful,
25
   but WITHOUT ANY WARRANTY; without even the implied warranty of
26
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
   General Public License for more details.
28
29
   You should have received copies of the GNU General Public License and
30
   the GNU Lesser General Public License along with this program.  If
31
   not, see http://www.gnu.org/licenses/.
32
*/
33
34
#if HAVE_CONFIG_H
35
# include "config.h"
36
#endif
37
38
#include <string.h>
39
40
#include "ocb.h"
41
#include "block-internal.h"
42
#include "bswap-internal.h"
43
#include "memops.h"
44
45
754
#define OCB_MAX_BLOCKS 16
46
47
/* Returns 64 bits from the concatenation (u0, u1), starting from bit offset. */
48
static inline uint64_t
49
extract(uint64_t u0, uint64_t u1, unsigned offset)
50
144
{
51
144
  if (offset == 0)
52
16
    return u0;
53
128
  u0 = bswap64_if_le(u0);
54
128
  u1 = bswap64_if_le(u1);
55
128
  return bswap64_if_le((u0 << offset) | (u1 >> (64 - offset)));
56
144
}
57
58
void
59
ocb_set_key (struct ocb_key *key, const void *cipher, nettle_cipher_func *f)
60
72
{
61
72
  static const union nettle_block16 zero_block;
62
72
  f (cipher, OCB_BLOCK_SIZE, key->L[0].b, zero_block.b);
63
72
  block16_mulx_be (&key->L[1], &key->L[0]);
64
72
  block16_mulx_be (&key->L[2], &key->L[1]);
65
72
}
66
67
/* Add x^k L[2], where k is the number of trailing zero bits in i. */
68
static void
69
update_offset(const struct ocb_key *key,
70
        union nettle_block16 *offset, size_t i)
71
95
{
72
95
  if (i & 1)
73
0
    block16_xor (offset, &key->L[2]);
74
95
  else
75
95
    {
76
95
      assert (i > 0);
77
95
      union nettle_block16 diff;
78
95
      block16_mulx_be (&diff, &key->L[2]);
79
194
      for (i >>= 1; !(i&1); i >>= 1)
80
99
  block16_mulx_be (&diff, &diff);
81
82
95
      block16_xor (offset, &diff);
83
95
    }
84
95
}
85
86
static void
87
pad_block (union nettle_block16 *block, size_t length, const uint8_t *data)
88
68
{
89
68
  memcpy (block->b, data, length);
90
68
  block->b[length] = 0x80;
91
68
  memset (block->b + length + 1, 0, OCB_BLOCK_SIZE - 1 - length);
92
68
}
93
94
void
95
ocb_set_nonce (struct ocb_ctx *ctx,
96
         const void *cipher, nettle_cipher_func *f,
97
         size_t tag_length,
98
         size_t nonce_length, const uint8_t *nonce)
99
72
{
100
72
  union nettle_block16 top;
101
72
  uint64_t stretch;
102
103
72
  unsigned bottom;
104
72
  assert (nonce_length < 16);
105
72
  assert (tag_length > 0);
106
72
  assert (tag_length <= 16);
107
108
  /* Bit size, or zero for tag_length == 16 */
109
72
  top.b[0] = (tag_length & 15) << 4;
110
72
  memset (top.b + 1, 0, 15 - nonce_length);
111
72
  top.b[15 - nonce_length] |= 1;
112
72
  memcpy (top.b + 16 - nonce_length, nonce, nonce_length);
113
72
  bottom = top.b[15] & 0x3f;
114
72
  top.b[15] &= 0xc0;
115
116
72
  f (cipher, OCB_BLOCK_SIZE, top.b, top.b);
117
118
72
  stretch = top.u64[0];
119
#if WORDS_BIGENDIAN
120
  stretch ^= (top.u64[0] << 8) | (top.u64[1] >> 56);
121
#else
122
72
  stretch ^= (top.u64[0] >> 8) | (top.u64[1] << 56);
123
72
#endif
124
125
72
  ctx->initial.u64[0] = extract(top.u64[0], top.u64[1], bottom);
126
72
  ctx->initial.u64[1] = extract(top.u64[1], stretch, bottom);
127
72
  ctx->sum.u64[0] = ctx->sum.u64[1] = 0;
128
72
  ctx->checksum.u64[0] = ctx->checksum.u64[1] = 0;
129
130
72
  ctx->data_count = ctx->message_count = 0;
131
72
}
132
133
static void
134
ocb_fill_n (const struct ocb_key *key,
135
      union nettle_block16 *offset, size_t count,
136
      size_t n, union nettle_block16 *o)
137
491
{
138
491
  assert (n > 0);
139
491
  union nettle_block16 *prev;
140
491
  if (count & 1)
141
302
    prev = offset;
142
189
  else
143
189
    {
144
      /* Do a single block to align block count. */
145
189
      count++; /* Always odd. */
146
189
      block16_xor (offset, &key->L[2]);
147
189
      block16_set (&o[0], offset);
148
189
      prev = o;
149
189
      n--; o++;
150
189
    }
151
152
2.94k
  for (; n >= 2; n -= 2, o += 2)
153
2.45k
    {
154
2.45k
      size_t i;
155
2.45k
      count += 2; /* Always odd. */
156
157
      /* Based on trailing zeros of ctx->message_count - 1, the
158
         initial shift below discards a one bit. */
159
2.45k
      block16_mulx_be (&o[0], &key->L[2]);
160
4.69k
      for (i = count >> 1; !(i&1); i >>= 1)
161
2.23k
  block16_mulx_be (&o[0], &o[0]);
162
163
2.45k
      block16_xor (&o[0], prev);
164
2.45k
      block16_xor3 (&o[1], &o[0], &key->L[2]);
165
2.45k
      prev = &o[1];
166
2.45k
    }
167
491
  block16_set(offset, prev);
168
169
491
  if (n > 0)
170
95
    {
171
95
      update_offset (key, offset, ++count);
172
95
      block16_set (o, offset);
173
95
    }
174
491
}
175
176
void
177
ocb_update (struct ocb_ctx *ctx, const struct ocb_key *key,
178
      const void *cipher, nettle_cipher_func *f,
179
      size_t length, const uint8_t *data)
180
486
{
181
486
  union nettle_block16 block[OCB_MAX_BLOCKS];
182
486
  size_t n = length / OCB_BLOCK_SIZE;
183
486
  assert (ctx->message_count == 0);
184
185
486
  if (ctx->data_count == 0)
186
32
    ctx->offset.u64[0] = ctx->offset.u64[1] = 0;
187
188
807
  while (n > 0)
189
321
    {
190
321
      size_t size, i;
191
321
      size_t blocks = (n <= OCB_MAX_BLOCKS) ? n
192
321
  : OCB_MAX_BLOCKS - 1 + (ctx->data_count & 1);
193
194
321
      ocb_fill_n (key, &ctx->offset, ctx->data_count, blocks, block);
195
321
      ctx->data_count += blocks;
196
197
321
      size = blocks * OCB_BLOCK_SIZE;
198
321
      memxor (block[0].b, data, size);
199
321
      f (cipher, size, block[0].b, block[0].b);
200
4.66k
      for (i = 0; i < blocks; i++)
201
4.34k
  block16_xor(&ctx->sum, &block[i]);
202
203
321
      n -= blocks; data += size;
204
321
    }
205
206
486
  length &= 15;
207
486
  if (length > 0)
208
26
    {
209
26
      union nettle_block16 block;
210
26
      pad_block (&block, length, data);
211
26
      block16_xor (&ctx->offset, &key->L[0]);
212
26
      block16_xor (&block, &ctx->offset);
213
214
26
      f (cipher, OCB_BLOCK_SIZE, block.b, block.b);
215
26
      block16_xor (&ctx->sum, &block);
216
26
    }
217
486
}
218
219
static void
220
ocb_crypt_n (struct ocb_ctx *ctx, const struct ocb_key *key,
221
       const void *cipher, nettle_cipher_func *f,
222
       size_t n, uint8_t *dst, const uint8_t *src)
223
154
{
224
154
  union nettle_block16 o[OCB_MAX_BLOCKS], block[OCB_MAX_BLOCKS];
225
154
  size_t size;
226
227
324
  while (n > 0)
228
170
    {
229
170
      size_t blocks = (n <= OCB_MAX_BLOCKS) ? n
230
170
  : OCB_MAX_BLOCKS - 1 + (ctx->message_count & 1);
231
232
170
      ocb_fill_n (key, &ctx->offset, ctx->message_count, blocks, o);
233
170
      ctx->message_count += blocks;
234
235
170
      size = blocks * OCB_BLOCK_SIZE;
236
170
      memxor3 (block[0].b, o[0].b, src, size);
237
170
      f (cipher, size, block[0].b, block[0].b);
238
170
      memxor3 (dst, block[0].b, o[0].b, size);
239
240
170
      n -= blocks; src += size; dst += size;
241
170
    }
242
154
}
243
244
/* Rotate bytes c positions to the right, in memory order. */
245
#if WORDS_BIGENDIAN
246
# define MEM_ROTATE_RIGHT(c, s0, s1) do {       \
247
    uint64_t __rotate_t = ((s0) >> (8*(c))) | ((s1) << (64-8*(c))); \
248
    (s1) = ((s1) >> (8*(c))) | ((s0) << (64-8*(c)));      \
249
    (s0) = __rotate_t;              \
250
  } while (0)
251
#else
252
0
# define MEM_ROTATE_RIGHT(c, s0, s1) do {       \
253
0
    uint64_t __rotate_t = ((s0) << (8*(c))) | ((s1) >> (64-8*(c))); \
254
0
    (s1) = ((s1) << (8*(c))) | ((s0) >> (64-8*(c)));      \
255
0
    (s0) = __rotate_t;              \
256
0
  } while (0)
257
#endif
258
259
/* Mask for the first c bytes in memory */
260
#if WORDS_BIGENDIAN
261
# define MEM_MASK(c) (-((uint64_t) 1 << (64 - 8*(c))))
262
#else
263
0
# define MEM_MASK(c) (((uint64_t) 1 << (8*(c))) - 1)
264
#endif
265
266
/* Checksum of n complete blocks. */
267
static void
268
ocb_checksum_n (union nettle_block16 *checksum,
269
    size_t n, const uint8_t *src)
270
154
{
271
154
  unsigned initial;
272
154
  uint64_t edge_word = 0;
273
154
  uint64_t s0, s1;
274
275
154
  if (n == 1)
276
76
    {
277
76
      memxor (checksum->b, src, OCB_BLOCK_SIZE);
278
76
      return;
279
76
    }
280
281
  /* Initial unaligned bytes. */
282
78
  initial = -(uintptr_t) src & 7;
283
284
78
  if (initial > 0)
285
0
    {
286
      /* Input not 64-bit aligned. Read initial bytes. */
287
0
      unsigned i;
288
      /* Edge word is read in big-endian order */
289
0
      for (i = initial; i > 0; i--)
290
0
  edge_word = (edge_word << 8) + *src++;
291
0
      n--;
292
0
    }
293
294
  /* Now src is 64-bit aligned, so do 64-bit reads. */
295
858
  for (s0 = s1 = 0 ; n > 0; n--, src += OCB_BLOCK_SIZE)
296
780
    {
297
780
      s0 ^= ((const uint64_t *) src)[0];
298
780
      s1 ^= ((const uint64_t *) src)[1];
299
780
    }
300
78
  if (initial > 0)
301
0
    {
302
0
      unsigned i;
303
0
      uint64_t mask;
304
0
      s0 ^= ((const uint64_t *) src)[0];
305
0
      for (i = 8 - initial, src += 8; i > 0; i--)
306
0
  edge_word = (edge_word << 8) + *src++;
307
308
      /* Rotate [s0, s1] right initial bytes. */
309
0
      MEM_ROTATE_RIGHT(initial, s0, s1);
310
      /* Add in the edge bytes.  */
311
0
      mask = MEM_MASK(initial);
312
0
      edge_word = bswap64_if_le (edge_word);
313
0
      s0 ^= (edge_word & mask);
314
0
      s1 ^= (edge_word & ~mask);
315
0
    }
316
78
  checksum->u64[0] ^= s0;
317
78
  checksum->u64[1] ^= s1;
318
78
}
319
320
void
321
ocb_encrypt (struct ocb_ctx *ctx, const struct ocb_key *key,
322
       const void *cipher, nettle_cipher_func *f,
323
       size_t length, uint8_t *dst, const uint8_t *src)
324
725
{
325
725
  size_t n = length / OCB_BLOCK_SIZE;
326
327
725
  if (ctx->message_count == 0)
328
73
    ctx->offset = ctx->initial;
329
330
725
  if (n > 0)
331
95
    {
332
95
      ocb_checksum_n (&ctx->checksum, n, src);
333
95
      ocb_crypt_n (ctx, key, cipher, f, n, dst, src);
334
95
      length &= 15;
335
95
    }
336
725
  if (length > 0)
337
18
    {
338
18
      union nettle_block16 block;
339
340
18
      src += n*OCB_BLOCK_SIZE; dst += n*OCB_BLOCK_SIZE;
341
342
18
      pad_block (&block, length, src);
343
18
      block16_xor (&ctx->checksum, &block);
344
345
18
      block16_xor (&ctx->offset, &key->L[0]);
346
18
      f (cipher, OCB_BLOCK_SIZE, block.b, ctx->offset.b);
347
18
      memxor3 (dst, block.b, src, length);
348
18
      ctx->message_count++;
349
18
    }
350
725
}
351
352
void
353
ocb_decrypt (struct ocb_ctx *ctx, const struct ocb_key *key,
354
       const void *encrypt_ctx, nettle_cipher_func *encrypt,
355
       const void *decrypt_ctx, nettle_cipher_func *decrypt,
356
       size_t length, uint8_t *dst, const uint8_t *src)
357
329
{
358
329
  size_t n = length / OCB_BLOCK_SIZE;
359
360
329
  if (ctx->message_count == 0)
361
41
    ctx->offset = ctx->initial;
362
363
329
  if (n > 0)
364
59
    {
365
59
      ocb_crypt_n (ctx, key, decrypt_ctx, decrypt, n, dst, src);
366
59
      ocb_checksum_n (&ctx->checksum, n, dst);
367
59
      length &= 15;
368
59
    }
369
329
  if (length > 0)
370
24
    {
371
24
      union nettle_block16 block;
372
373
24
      src += n*OCB_BLOCK_SIZE; dst += n*OCB_BLOCK_SIZE;
374
375
24
      block16_xor (&ctx->offset, &key->L[0]);
376
24
      encrypt (encrypt_ctx, OCB_BLOCK_SIZE, block.b, ctx->offset.b);
377
24
      memxor3 (dst, block.b, src, length);
378
379
24
      pad_block (&block, length, dst);
380
24
      block16_xor (&ctx->checksum, &block);
381
24
      ctx->message_count++;
382
24
    }
383
329
}
384
385
void
386
ocb_digest (const struct ocb_ctx *ctx, const struct ocb_key *key,
387
      const void *cipher, nettle_cipher_func *f,
388
      size_t length, uint8_t *digest)
389
72
{
390
72
  union nettle_block16 block;
391
72
  assert (length <= OCB_DIGEST_SIZE);
392
72
  block16_xor3 (&block,  &key->L[1],
393
72
    (ctx->message_count > 0) ? &ctx->offset : &ctx->initial);
394
72
  block16_xor (&block, &ctx->checksum);
395
72
  f (cipher, OCB_BLOCK_SIZE, block.b, block.b);
396
72
  memxor3 (digest, block.b, ctx->sum.b, length);
397
72
}
398
399
void
400
ocb_encrypt_message (const struct ocb_key *key,
401
         const void *cipher, nettle_cipher_func *f,
402
         size_t nlength, const uint8_t *nonce,
403
         size_t alength, const uint8_t *adata,
404
         size_t tlength,
405
         size_t clength, uint8_t *dst, const uint8_t *src)
406
0
{
407
0
  struct ocb_ctx ctx;
408
0
  assert (clength >= tlength);
409
0
  ocb_set_nonce (&ctx, cipher, f, tlength, nlength, nonce);
410
0
  ocb_update (&ctx, key, cipher, f, alength, adata);
411
0
  ocb_encrypt (&ctx, key, cipher, f,  clength - tlength, dst, src);
412
0
  ocb_digest (&ctx, key, cipher, f, tlength, dst + clength - tlength);
413
0
}
414
415
int
416
ocb_decrypt_message (const struct ocb_key *key,
417
         const void *encrypt_ctx, nettle_cipher_func *encrypt,
418
         const void *decrypt_ctx, nettle_cipher_func *decrypt,
419
         size_t nlength, const uint8_t *nonce,
420
         size_t alength, const uint8_t *adata,
421
         size_t tlength,
422
         size_t mlength, uint8_t *dst, const uint8_t *src)
423
0
{
424
0
  struct ocb_ctx ctx;
425
0
  union nettle_block16 digest;
426
0
  ocb_set_nonce (&ctx, encrypt_ctx, encrypt, tlength, nlength, nonce);
427
0
  ocb_update (&ctx, key, encrypt_ctx, encrypt, alength, adata);
428
0
  ocb_decrypt (&ctx, key, encrypt_ctx, encrypt, decrypt_ctx, decrypt,
429
0
         mlength, dst, src);
430
0
  ocb_digest (&ctx, key, encrypt_ctx, encrypt, tlength, digest.b);
431
0
  return memeql_sec(digest.b, src + mlength, tlength);
432
0
}