Coverage Report

Created: 2024-07-23 07:36

/src/gnutls/lib/nettle/mac.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2008-2012 Free Software Foundation, Inc.
3
 *
4
 * Author: Nikos Mavrogiannopoulos
5
 *
6
 * This file is part of GNUTLS.
7
 *
8
 * The GNUTLS library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public License
10
 * as published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 *
21
 */
22
23
/* This file provides the backend hash/mac API for nettle.
24
 */
25
26
#include "gnutls_int.h"
27
#include "hash_int.h"
28
#include "errors.h"
29
#include <nettle/md5.h>
30
#include <nettle/md2.h>
31
#include <nettle/ripemd160.h>
32
#include <nettle/sha.h>
33
#include <nettle/sha3.h>
34
#ifndef HAVE_NETTLE_SHA3_128_SHAKE_OUTPUT
35
#include "int/sha3-shake.h"
36
#endif
37
#include <nettle/hmac.h>
38
#include <nettle/umac.h>
39
#include <nettle/hkdf.h>
40
#include <nettle/pbkdf2.h>
41
#include <nettle/cmac.h>
42
#if ENABLE_GOST
43
#include "gost/hmac-gost.h"
44
#ifndef HAVE_NETTLE_GOST28147_SET_KEY
45
#include "gost/gost28147.h"
46
#endif
47
#include "gost/cmac.h"
48
#endif
49
#include <nettle/gcm.h>
50
51
typedef void (*update_func)(void *, size_t, const uint8_t *);
52
typedef void (*digest_func)(void *, size_t, uint8_t *);
53
typedef void (*set_key_func)(void *, size_t, const uint8_t *);
54
typedef void (*set_nonce_func)(void *, size_t, const uint8_t *);
55
typedef void (*init_func)(void *);
56
57
static int wrap_nettle_hash_init(gnutls_digest_algorithm_t algo, void **_ctx);
58
59
struct md5_sha1_ctx {
60
  struct md5_ctx md5;
61
  struct sha1_ctx sha1;
62
};
63
64
struct gmac_ctx {
65
  unsigned int pos;
66
  uint8_t buffer[GCM_BLOCK_SIZE];
67
  struct gcm_key key;
68
  struct gcm_ctx ctx;
69
  nettle_cipher_func *encrypt;
70
  union {
71
    struct aes128_ctx aes128;
72
    struct aes192_ctx aes192;
73
    struct aes256_ctx aes256;
74
  } cipher;
75
};
76
77
struct nettle_hash_ctx {
78
  union {
79
    struct md5_ctx md5;
80
    struct sha224_ctx sha224;
81
    struct sha256_ctx sha256;
82
    struct sha384_ctx sha384;
83
    struct sha512_ctx sha512;
84
    struct sha3_128_ctx sha3_128;
85
    struct sha3_224_ctx sha3_224;
86
    struct sha3_256_ctx sha3_256;
87
    struct sha3_384_ctx sha3_384;
88
    struct sha3_512_ctx sha3_512;
89
    struct sha1_ctx sha1;
90
    struct md2_ctx md2;
91
    struct ripemd160_ctx ripemd160;
92
    struct md5_sha1_ctx md5_sha1;
93
#if ENABLE_GOST
94
    struct gosthash94cp_ctx gosthash94cp;
95
    struct streebog256_ctx streebog256;
96
    struct streebog512_ctx streebog512;
97
#endif
98
  } ctx;
99
  void *ctx_ptr;
100
  gnutls_digest_algorithm_t algo;
101
  size_t length;
102
  update_func update;
103
  digest_func digest;
104
  init_func init;
105
};
106
107
struct nettle_mac_ctx {
108
  union {
109
    struct hmac_md5_ctx md5;
110
    struct hmac_sha224_ctx sha224;
111
    struct hmac_sha256_ctx sha256;
112
    struct hmac_sha384_ctx sha384;
113
    struct hmac_sha512_ctx sha512;
114
    struct hmac_sha1_ctx sha1;
115
#if ENABLE_GOST
116
    struct hmac_gosthash94cp_ctx gosthash94cp;
117
    struct hmac_streebog256_ctx streebog256;
118
    struct hmac_streebog512_ctx streebog512;
119
    struct gost28147_imit_ctx gost28147_imit;
120
    struct cmac_magma_ctx magma;
121
    struct cmac_kuznyechik_ctx kuznyechik;
122
#endif
123
    struct umac96_ctx umac96;
124
    struct umac128_ctx umac128;
125
    struct cmac_aes128_ctx cmac128;
126
    struct cmac_aes256_ctx cmac256;
127
    struct gmac_ctx gmac;
128
  } ctx;
129
130
  void *ctx_ptr;
131
  gnutls_mac_algorithm_t algo;
132
  size_t length;
133
  update_func update;
134
  digest_func digest;
135
  set_key_func set_key;
136
  set_nonce_func set_nonce;
137
};
138
139
#if ENABLE_GOST
140
static void _wrap_gost28147_imit_set_key_tc26z(void *ctx, size_t len,
141
                 const uint8_t *key)
142
0
{
143
0
  gost28147_imit_set_param(ctx, &gost28147_param_TC26_Z);
144
0
  gost28147_imit_set_key(ctx, len, key);
145
0
}
146
147
static void _wrap_cmac_magma_set_key(void *ctx, size_t len, const uint8_t *key)
148
0
{
149
0
  cmac_magma_set_key(ctx, key);
150
0
}
151
152
static void _wrap_cmac_kuznyechik_set_key(void *ctx, size_t len,
153
            const uint8_t *key)
154
0
{
155
0
  cmac_kuznyechik_set_key(ctx, key);
156
0
}
157
#endif
158
159
static void _wrap_umac96_set_key(void *ctx, size_t len, const uint8_t *key)
160
0
{
161
0
  if (unlikely(len != 16))
162
0
    abort();
163
0
  umac96_set_key(ctx, key);
164
0
}
165
166
static void _wrap_umac128_set_key(void *ctx, size_t len, const uint8_t *key)
167
0
{
168
0
  if (unlikely(len != 16))
169
0
    abort();
170
0
  umac128_set_key(ctx, key);
171
0
}
172
173
static void _wrap_cmac128_set_key(void *ctx, size_t len, const uint8_t *key)
174
0
{
175
0
  if (unlikely(len != 16))
176
0
    abort();
177
0
  cmac_aes128_set_key(ctx, key);
178
0
}
179
180
static void _wrap_cmac256_set_key(void *ctx, size_t len, const uint8_t *key)
181
0
{
182
0
  if (unlikely(len != 32))
183
0
    abort();
184
0
  cmac_aes256_set_key(ctx, key);
185
0
}
186
187
static void _wrap_gmac_aes128_set_key(void *_ctx, size_t len,
188
              const uint8_t *key)
189
0
{
190
0
  struct gmac_ctx *ctx = _ctx;
191
192
0
  if (unlikely(len != 16))
193
0
    abort();
194
0
  aes128_set_encrypt_key(&ctx->cipher.aes128, key);
195
0
  gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt);
196
0
  ctx->pos = 0;
197
0
}
198
199
static void _wrap_gmac_aes192_set_key(void *_ctx, size_t len,
200
              const uint8_t *key)
201
0
{
202
0
  struct gmac_ctx *ctx = _ctx;
203
204
0
  if (unlikely(len != 24))
205
0
    abort();
206
0
  aes192_set_encrypt_key(&ctx->cipher.aes192, key);
207
0
  gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt);
208
0
  ctx->pos = 0;
209
0
}
210
211
static void _wrap_gmac_aes256_set_key(void *_ctx, size_t len,
212
              const uint8_t *key)
213
0
{
214
0
  struct gmac_ctx *ctx = _ctx;
215
216
0
  if (unlikely(len != 32))
217
0
    abort();
218
0
  aes256_set_encrypt_key(&ctx->cipher.aes256, key);
219
0
  gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt);
220
0
  ctx->pos = 0;
221
0
}
222
223
static void _wrap_gmac_set_nonce(void *_ctx, size_t nonce_length,
224
         const uint8_t *nonce)
225
0
{
226
0
  struct gmac_ctx *ctx = _ctx;
227
228
0
  gcm_set_iv(&ctx->ctx, &ctx->key, nonce_length, nonce);
229
0
}
230
231
static void _wrap_gmac_update(void *_ctx, size_t length, const uint8_t *data)
232
0
{
233
0
  struct gmac_ctx *ctx = _ctx;
234
235
0
  if (ctx->pos + length < GCM_BLOCK_SIZE) {
236
0
    memcpy(&ctx->buffer[ctx->pos], data, length);
237
0
    ctx->pos += length;
238
0
    return;
239
0
  }
240
241
0
  if (ctx->pos) {
242
0
    memcpy(&ctx->buffer[ctx->pos], data, GCM_BLOCK_SIZE - ctx->pos);
243
0
    gcm_update(&ctx->ctx, &ctx->key, GCM_BLOCK_SIZE, ctx->buffer);
244
0
    data += GCM_BLOCK_SIZE - ctx->pos;
245
0
    length -= GCM_BLOCK_SIZE - ctx->pos;
246
0
  }
247
248
0
  if (length >= GCM_BLOCK_SIZE) {
249
0
    gcm_update(&ctx->ctx, &ctx->key,
250
0
         length / GCM_BLOCK_SIZE * GCM_BLOCK_SIZE, data);
251
0
    data += length / GCM_BLOCK_SIZE * GCM_BLOCK_SIZE;
252
0
    length %= GCM_BLOCK_SIZE;
253
0
  }
254
255
0
  memcpy(ctx->buffer, data, length);
256
0
  ctx->pos = length;
257
0
}
258
259
static void _wrap_gmac_digest(void *_ctx, size_t length, uint8_t *digest)
260
0
{
261
0
  struct gmac_ctx *ctx = _ctx;
262
263
0
  if (ctx->pos)
264
0
    gcm_update(&ctx->ctx, &ctx->key, ctx->pos, ctx->buffer);
265
0
  gcm_digest(&ctx->ctx, &ctx->key, &ctx->cipher, ctx->encrypt, length,
266
0
       digest);
267
0
  ctx->pos = 0;
268
0
}
269
270
static int _mac_ctx_init(gnutls_mac_algorithm_t algo,
271
       struct nettle_mac_ctx *ctx)
272
0
{
273
  /* Any FIPS140-2 related enforcement is performed on
274
   * gnutls_hash_init() and gnutls_hmac_init() */
275
276
0
  ctx->set_nonce = NULL;
277
0
  switch (algo) {
278
0
  case GNUTLS_MAC_MD5:
279
0
    ctx->update = (update_func)hmac_md5_update;
280
0
    ctx->digest = (digest_func)hmac_md5_digest;
281
0
    ctx->set_key = (set_key_func)hmac_md5_set_key;
282
0
    ctx->ctx_ptr = &ctx->ctx.md5;
283
0
    ctx->length = MD5_DIGEST_SIZE;
284
0
    break;
285
0
  case GNUTLS_MAC_SHA1:
286
0
    ctx->update = (update_func)hmac_sha1_update;
287
0
    ctx->digest = (digest_func)hmac_sha1_digest;
288
0
    ctx->set_key = (set_key_func)hmac_sha1_set_key;
289
0
    ctx->ctx_ptr = &ctx->ctx.sha1;
290
0
    ctx->length = SHA1_DIGEST_SIZE;
291
0
    break;
292
0
  case GNUTLS_MAC_SHA224:
293
0
    ctx->update = (update_func)hmac_sha224_update;
294
0
    ctx->digest = (digest_func)hmac_sha224_digest;
295
0
    ctx->set_key = (set_key_func)hmac_sha224_set_key;
296
0
    ctx->ctx_ptr = &ctx->ctx.sha224;
297
0
    ctx->length = SHA224_DIGEST_SIZE;
298
0
    break;
299
0
  case GNUTLS_MAC_SHA256:
300
0
    ctx->update = (update_func)hmac_sha256_update;
301
0
    ctx->digest = (digest_func)hmac_sha256_digest;
302
0
    ctx->set_key = (set_key_func)hmac_sha256_set_key;
303
0
    ctx->ctx_ptr = &ctx->ctx.sha256;
304
0
    ctx->length = SHA256_DIGEST_SIZE;
305
0
    break;
306
0
  case GNUTLS_MAC_SHA384:
307
0
    ctx->update = (update_func)hmac_sha384_update;
308
0
    ctx->digest = (digest_func)hmac_sha384_digest;
309
0
    ctx->set_key = (set_key_func)hmac_sha384_set_key;
310
0
    ctx->ctx_ptr = &ctx->ctx.sha384;
311
0
    ctx->length = SHA384_DIGEST_SIZE;
312
0
    break;
313
0
  case GNUTLS_MAC_SHA512:
314
0
    ctx->update = (update_func)hmac_sha512_update;
315
0
    ctx->digest = (digest_func)hmac_sha512_digest;
316
0
    ctx->set_key = (set_key_func)hmac_sha512_set_key;
317
0
    ctx->ctx_ptr = &ctx->ctx.sha512;
318
0
    ctx->length = SHA512_DIGEST_SIZE;
319
0
    break;
320
0
#if ENABLE_GOST
321
0
  case GNUTLS_MAC_GOSTR_94:
322
0
    ctx->update = (update_func)hmac_gosthash94cp_update;
323
0
    ctx->digest = (digest_func)hmac_gosthash94cp_digest;
324
0
    ctx->set_key = (set_key_func)hmac_gosthash94cp_set_key;
325
0
    ctx->ctx_ptr = &ctx->ctx.gosthash94cp;
326
0
    ctx->length = GOSTHASH94CP_DIGEST_SIZE;
327
0
    break;
328
0
  case GNUTLS_MAC_STREEBOG_256:
329
0
    ctx->update = (update_func)hmac_streebog256_update;
330
0
    ctx->digest = (digest_func)hmac_streebog256_digest;
331
0
    ctx->set_key = (set_key_func)hmac_streebog256_set_key;
332
0
    ctx->ctx_ptr = &ctx->ctx.streebog256;
333
0
    ctx->length = STREEBOG256_DIGEST_SIZE;
334
0
    break;
335
0
  case GNUTLS_MAC_STREEBOG_512:
336
0
    ctx->update = (update_func)hmac_streebog512_update;
337
0
    ctx->digest = (digest_func)hmac_streebog512_digest;
338
0
    ctx->set_key = (set_key_func)hmac_streebog512_set_key;
339
0
    ctx->ctx_ptr = &ctx->ctx.streebog512;
340
0
    ctx->length = STREEBOG512_DIGEST_SIZE;
341
0
    break;
342
0
  case GNUTLS_MAC_GOST28147_TC26Z_IMIT:
343
0
    ctx->update = (update_func)gost28147_imit_update;
344
0
    ctx->digest = (digest_func)gost28147_imit_digest;
345
0
    ctx->set_key = _wrap_gost28147_imit_set_key_tc26z;
346
0
    ctx->ctx_ptr = &ctx->ctx.gost28147_imit;
347
0
    ctx->length = GOST28147_IMIT_DIGEST_SIZE;
348
0
    break;
349
0
  case GNUTLS_MAC_MAGMA_OMAC:
350
0
    ctx->update = (update_func)cmac_magma_update;
351
0
    ctx->digest = (digest_func)cmac_magma_digest;
352
0
    ctx->set_key = _wrap_cmac_magma_set_key;
353
0
    ctx->ctx_ptr = &ctx->ctx.magma;
354
0
    ctx->length = CMAC64_DIGEST_SIZE;
355
0
    break;
356
0
  case GNUTLS_MAC_KUZNYECHIK_OMAC:
357
0
    ctx->update = (update_func)cmac_kuznyechik_update;
358
0
    ctx->digest = (digest_func)cmac_kuznyechik_digest;
359
0
    ctx->set_key = _wrap_cmac_kuznyechik_set_key;
360
0
    ctx->ctx_ptr = &ctx->ctx.kuznyechik;
361
0
    ctx->length = CMAC128_DIGEST_SIZE;
362
0
    break;
363
0
#endif
364
0
  case GNUTLS_MAC_UMAC_96:
365
0
    ctx->update = (update_func)umac96_update;
366
0
    ctx->digest = (digest_func)umac96_digest;
367
0
    ctx->set_key = _wrap_umac96_set_key;
368
0
    ctx->set_nonce = (set_nonce_func)umac96_set_nonce;
369
0
    ctx->ctx_ptr = &ctx->ctx.umac96;
370
0
    ctx->length = 12;
371
0
    break;
372
0
  case GNUTLS_MAC_UMAC_128:
373
0
    ctx->update = (update_func)umac128_update;
374
0
    ctx->digest = (digest_func)umac128_digest;
375
0
    ctx->set_key = _wrap_umac128_set_key;
376
0
    ctx->set_nonce = (set_nonce_func)umac128_set_nonce;
377
0
    ctx->ctx_ptr = &ctx->ctx.umac128;
378
0
    ctx->length = 16;
379
0
    break;
380
0
  case GNUTLS_MAC_AES_CMAC_128:
381
0
    ctx->update = (update_func)cmac_aes128_update;
382
0
    ctx->digest = (digest_func)cmac_aes128_digest;
383
0
    ctx->set_key = _wrap_cmac128_set_key;
384
0
    ctx->ctx_ptr = &ctx->ctx.cmac128;
385
0
    ctx->length = CMAC128_DIGEST_SIZE;
386
0
    break;
387
0
  case GNUTLS_MAC_AES_CMAC_256:
388
0
    ctx->update = (update_func)cmac_aes256_update;
389
0
    ctx->digest = (digest_func)cmac_aes256_digest;
390
0
    ctx->set_key = _wrap_cmac256_set_key;
391
0
    ctx->ctx_ptr = &ctx->ctx.cmac256;
392
0
    ctx->length = CMAC128_DIGEST_SIZE;
393
0
    break;
394
0
  case GNUTLS_MAC_AES_GMAC_128:
395
0
    ctx->set_key = _wrap_gmac_aes128_set_key;
396
0
    ctx->set_nonce = _wrap_gmac_set_nonce;
397
0
    ctx->update = _wrap_gmac_update;
398
0
    ctx->digest = _wrap_gmac_digest;
399
0
    ctx->ctx_ptr = &ctx->ctx.gmac;
400
0
    ctx->length = GCM_DIGEST_SIZE;
401
0
    ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes128_encrypt;
402
0
    break;
403
0
  case GNUTLS_MAC_AES_GMAC_192:
404
0
    ctx->set_key = _wrap_gmac_aes192_set_key;
405
0
    ctx->set_nonce = _wrap_gmac_set_nonce;
406
0
    ctx->update = _wrap_gmac_update;
407
0
    ctx->digest = _wrap_gmac_digest;
408
0
    ctx->ctx_ptr = &ctx->ctx.gmac;
409
0
    ctx->length = GCM_DIGEST_SIZE;
410
0
    ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes192_encrypt;
411
0
    break;
412
0
  case GNUTLS_MAC_AES_GMAC_256:
413
0
    ctx->set_key = _wrap_gmac_aes256_set_key;
414
0
    ctx->set_nonce = _wrap_gmac_set_nonce;
415
0
    ctx->update = _wrap_gmac_update;
416
0
    ctx->digest = _wrap_gmac_digest;
417
0
    ctx->ctx_ptr = &ctx->ctx.gmac;
418
0
    ctx->length = GCM_DIGEST_SIZE;
419
0
    ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes256_encrypt;
420
0
    break;
421
0
  default:
422
0
    gnutls_assert();
423
0
    return GNUTLS_E_INVALID_REQUEST;
424
0
  }
425
426
0
  return 0;
427
0
}
428
429
static int wrap_nettle_mac_fast(gnutls_mac_algorithm_t algo, const void *nonce,
430
        size_t nonce_size, const void *key,
431
        size_t key_size, const void *text,
432
        size_t text_size, void *digest)
433
0
{
434
0
  struct nettle_mac_ctx ctx;
435
0
  int ret;
436
437
0
  ret = _mac_ctx_init(algo, &ctx);
438
0
  if (ret < 0)
439
0
    return gnutls_assert_val(ret);
440
441
0
  ctx.set_key(&ctx, key_size, key);
442
0
  if (ctx.set_nonce) {
443
0
    if (nonce == NULL || nonce_size == 0)
444
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
445
446
0
    ctx.set_nonce(&ctx, nonce_size, nonce);
447
0
  }
448
0
  ctx.update(&ctx, text_size, text);
449
0
  ctx.digest(&ctx, ctx.length, digest);
450
451
0
  zeroize_temp_key(&ctx, sizeof(ctx));
452
453
0
  return 0;
454
0
}
455
456
static int wrap_nettle_mac_exists(gnutls_mac_algorithm_t algo)
457
0
{
458
0
  switch (algo) {
459
0
  case GNUTLS_MAC_MD5:
460
0
  case GNUTLS_MAC_SHA1:
461
0
  case GNUTLS_MAC_SHA224:
462
0
  case GNUTLS_MAC_SHA256:
463
0
  case GNUTLS_MAC_SHA384:
464
0
  case GNUTLS_MAC_SHA512:
465
0
  case GNUTLS_MAC_UMAC_96:
466
0
  case GNUTLS_MAC_UMAC_128:
467
0
  case GNUTLS_MAC_AES_CMAC_128:
468
0
  case GNUTLS_MAC_AES_CMAC_256:
469
0
  case GNUTLS_MAC_AES_GMAC_128:
470
0
  case GNUTLS_MAC_AES_GMAC_192:
471
0
  case GNUTLS_MAC_AES_GMAC_256:
472
0
#if ENABLE_GOST
473
0
  case GNUTLS_MAC_GOSTR_94:
474
0
  case GNUTLS_MAC_STREEBOG_256:
475
0
  case GNUTLS_MAC_STREEBOG_512:
476
0
  case GNUTLS_MAC_GOST28147_TC26Z_IMIT:
477
0
  case GNUTLS_MAC_MAGMA_OMAC:
478
0
  case GNUTLS_MAC_KUZNYECHIK_OMAC:
479
0
#endif
480
0
    return 1;
481
0
  default:
482
0
    return 0;
483
0
  }
484
0
}
485
486
static int wrap_nettle_mac_init(gnutls_mac_algorithm_t algo, void **_ctx)
487
0
{
488
0
  struct nettle_mac_ctx *ctx;
489
0
  int ret;
490
491
0
  ctx = gnutls_calloc(1, sizeof(struct nettle_mac_ctx));
492
0
  if (ctx == NULL) {
493
0
    gnutls_assert();
494
0
    return GNUTLS_E_MEMORY_ERROR;
495
0
  }
496
497
0
  ctx->algo = algo;
498
499
0
  ret = _mac_ctx_init(algo, ctx);
500
0
  if (ret < 0) {
501
0
    gnutls_free(ctx);
502
0
    return gnutls_assert_val(ret);
503
0
  }
504
505
0
  *_ctx = ctx;
506
507
0
  return 0;
508
0
}
509
510
static void *wrap_nettle_mac_copy(const void *_ctx)
511
0
{
512
0
  const struct nettle_mac_ctx *ctx = _ctx;
513
0
  struct nettle_mac_ctx *new_ctx;
514
0
  ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx);
515
516
0
  new_ctx = gnutls_calloc(1, sizeof(struct nettle_mac_ctx));
517
0
  if (new_ctx == NULL)
518
0
    return NULL;
519
520
0
  memcpy(new_ctx, ctx, sizeof(*ctx));
521
0
  new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off;
522
523
0
  return new_ctx;
524
0
}
525
526
static int wrap_nettle_mac_set_key(void *_ctx, const void *key, size_t keylen)
527
0
{
528
0
  struct nettle_mac_ctx *ctx = _ctx;
529
530
0
  ctx->set_key(ctx->ctx_ptr, keylen, key);
531
0
  return 0;
532
0
}
533
534
static int wrap_nettle_mac_set_nonce(void *_ctx, const void *nonce,
535
             size_t noncelen)
536
0
{
537
0
  struct nettle_mac_ctx *ctx = _ctx;
538
539
0
  if (ctx->set_nonce == NULL)
540
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
541
542
0
  if (nonce == NULL || noncelen == 0)
543
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
544
545
0
  ctx->set_nonce(ctx->ctx_ptr, noncelen, nonce);
546
547
0
  return GNUTLS_E_SUCCESS;
548
0
}
549
550
static int wrap_nettle_mac_update(void *_ctx, const void *text, size_t textsize)
551
0
{
552
0
  struct nettle_mac_ctx *ctx = _ctx;
553
554
0
  ctx->update(ctx->ctx_ptr, textsize, text);
555
556
0
  return GNUTLS_E_SUCCESS;
557
0
}
558
559
static int wrap_nettle_mac_output(void *src_ctx, void *digest,
560
          size_t digestsize)
561
0
{
562
0
  struct nettle_mac_ctx *ctx;
563
0
  ctx = src_ctx;
564
565
0
  if (digestsize < ctx->length) {
566
0
    gnutls_assert();
567
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
568
0
  }
569
570
0
  ctx->digest(ctx->ctx_ptr, digestsize, digest);
571
572
0
  return 0;
573
0
}
574
575
static void wrap_nettle_mac_deinit(void *hd)
576
0
{
577
0
  struct nettle_mac_ctx *ctx = hd;
578
579
0
  zeroize_temp_key(ctx, sizeof(*ctx));
580
0
  gnutls_free(ctx);
581
0
}
582
583
/* Hash functions 
584
 */
585
static int wrap_nettle_hash_update(void *_ctx, const void *text,
586
           size_t textsize)
587
0
{
588
0
  struct nettle_hash_ctx *ctx = _ctx;
589
590
0
  ctx->update(ctx->ctx_ptr, textsize, text);
591
592
0
  return GNUTLS_E_SUCCESS;
593
0
}
594
595
static void wrap_nettle_hash_deinit(void *hd)
596
0
{
597
0
  gnutls_free(hd);
598
0
}
599
600
static int wrap_nettle_hash_exists(gnutls_digest_algorithm_t algo)
601
0
{
602
0
  switch (algo) {
603
0
  case GNUTLS_DIG_MD5:
604
0
  case GNUTLS_DIG_SHA1:
605
0
  case GNUTLS_DIG_MD5_SHA1:
606
607
0
  case GNUTLS_DIG_SHA224:
608
0
  case GNUTLS_DIG_SHA256:
609
0
  case GNUTLS_DIG_SHA384:
610
0
  case GNUTLS_DIG_SHA512:
611
612
0
#ifdef NETTLE_SHA3_FIPS202
613
0
  case GNUTLS_DIG_SHA3_224:
614
0
  case GNUTLS_DIG_SHA3_256:
615
0
  case GNUTLS_DIG_SHA3_384:
616
0
  case GNUTLS_DIG_SHA3_512:
617
0
  case GNUTLS_DIG_SHAKE_128:
618
0
  case GNUTLS_DIG_SHAKE_256:
619
0
#endif
620
621
0
  case GNUTLS_DIG_MD2:
622
0
  case GNUTLS_DIG_RMD160:
623
624
0
#if ENABLE_GOST
625
0
  case GNUTLS_DIG_GOSTR_94:
626
0
  case GNUTLS_DIG_STREEBOG_256:
627
0
  case GNUTLS_DIG_STREEBOG_512:
628
0
#endif
629
0
    return 1;
630
0
  default:
631
0
    return 0;
632
0
  }
633
0
}
634
635
static void _md5_sha1_update(void *_ctx, size_t len, const uint8_t *data)
636
0
{
637
0
  struct md5_sha1_ctx *ctx = _ctx;
638
639
0
  md5_update(&ctx->md5, len, data);
640
0
  sha1_update(&ctx->sha1, len, data);
641
0
}
642
643
static void _md5_sha1_digest(void *_ctx, size_t len, uint8_t *digest)
644
0
{
645
0
  struct md5_sha1_ctx *ctx = _ctx;
646
647
0
  md5_digest(&ctx->md5, len <= MD5_DIGEST_SIZE ? len : MD5_DIGEST_SIZE,
648
0
       digest);
649
650
0
  if (len > MD5_DIGEST_SIZE)
651
0
    sha1_digest(&ctx->sha1, len - MD5_DIGEST_SIZE,
652
0
          digest + MD5_DIGEST_SIZE);
653
0
}
654
655
static void _md5_sha1_init(void *_ctx)
656
0
{
657
0
  struct md5_sha1_ctx *ctx = _ctx;
658
659
0
  md5_init(&ctx->md5);
660
0
  sha1_init(&ctx->sha1);
661
0
}
662
663
static int _ctx_init(gnutls_digest_algorithm_t algo,
664
         struct nettle_hash_ctx *ctx)
665
0
{
666
  /* Any FIPS140-2 related enforcement is performed on
667
   * gnutls_hash_init() and gnutls_hmac_init() */
668
0
  switch (algo) {
669
0
  case GNUTLS_DIG_MD5:
670
0
    ctx->init = (init_func)md5_init;
671
0
    ctx->update = (update_func)md5_update;
672
0
    ctx->digest = (digest_func)md5_digest;
673
0
    ctx->ctx_ptr = &ctx->ctx.md5;
674
0
    ctx->length = MD5_DIGEST_SIZE;
675
0
    break;
676
0
  case GNUTLS_DIG_SHA1:
677
0
    ctx->init = (init_func)sha1_init;
678
0
    ctx->update = (update_func)sha1_update;
679
0
    ctx->digest = (digest_func)sha1_digest;
680
0
    ctx->ctx_ptr = &ctx->ctx.sha1;
681
0
    ctx->length = SHA1_DIGEST_SIZE;
682
0
    break;
683
0
  case GNUTLS_DIG_MD5_SHA1:
684
0
    ctx->init = (init_func)_md5_sha1_init;
685
0
    ctx->update = (update_func)_md5_sha1_update;
686
0
    ctx->digest = (digest_func)_md5_sha1_digest;
687
0
    ctx->ctx_ptr = &ctx->ctx.md5_sha1;
688
0
    ctx->length = MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE;
689
0
    break;
690
0
  case GNUTLS_DIG_SHA224:
691
0
    ctx->init = (init_func)sha224_init;
692
0
    ctx->update = (update_func)sha224_update;
693
0
    ctx->digest = (digest_func)sha224_digest;
694
0
    ctx->ctx_ptr = &ctx->ctx.sha224;
695
0
    ctx->length = SHA224_DIGEST_SIZE;
696
0
    break;
697
0
  case GNUTLS_DIG_SHA256:
698
0
    ctx->init = (init_func)sha256_init;
699
0
    ctx->update = (update_func)sha256_update;
700
0
    ctx->digest = (digest_func)sha256_digest;
701
0
    ctx->ctx_ptr = &ctx->ctx.sha256;
702
0
    ctx->length = SHA256_DIGEST_SIZE;
703
0
    break;
704
0
  case GNUTLS_DIG_SHA384:
705
0
    ctx->init = (init_func)sha384_init;
706
0
    ctx->update = (update_func)sha384_update;
707
0
    ctx->digest = (digest_func)sha384_digest;
708
0
    ctx->ctx_ptr = &ctx->ctx.sha384;
709
0
    ctx->length = SHA384_DIGEST_SIZE;
710
0
    break;
711
0
  case GNUTLS_DIG_SHA512:
712
0
    ctx->init = (init_func)sha512_init;
713
0
    ctx->update = (update_func)sha512_update;
714
0
    ctx->digest = (digest_func)sha512_digest;
715
0
    ctx->ctx_ptr = &ctx->ctx.sha512;
716
0
    ctx->length = SHA512_DIGEST_SIZE;
717
0
    break;
718
0
#ifdef NETTLE_SHA3_FIPS202
719
0
  case GNUTLS_DIG_SHA3_224:
720
0
    ctx->init = (init_func)sha3_224_init;
721
0
    ctx->update = (update_func)sha3_224_update;
722
0
    ctx->digest = (digest_func)sha3_224_digest;
723
0
    ctx->ctx_ptr = &ctx->ctx.sha3_224;
724
0
    ctx->length = SHA3_224_DIGEST_SIZE;
725
0
    break;
726
0
  case GNUTLS_DIG_SHA3_256:
727
0
    ctx->init = (init_func)sha3_256_init;
728
0
    ctx->update = (update_func)sha3_256_update;
729
0
    ctx->digest = (digest_func)sha3_256_digest;
730
0
    ctx->ctx_ptr = &ctx->ctx.sha3_256;
731
0
    ctx->length = SHA3_256_DIGEST_SIZE;
732
0
    break;
733
0
  case GNUTLS_DIG_SHA3_384:
734
0
    ctx->init = (init_func)sha3_384_init;
735
0
    ctx->update = (update_func)sha3_384_update;
736
0
    ctx->digest = (digest_func)sha3_384_digest;
737
0
    ctx->ctx_ptr = &ctx->ctx.sha3_384;
738
0
    ctx->length = SHA3_384_DIGEST_SIZE;
739
0
    break;
740
0
  case GNUTLS_DIG_SHA3_512:
741
0
    ctx->init = (init_func)sha3_512_init;
742
0
    ctx->update = (update_func)sha3_512_update;
743
0
    ctx->digest = (digest_func)sha3_512_digest;
744
0
    ctx->ctx_ptr = &ctx->ctx.sha3_512;
745
0
    ctx->length = SHA3_512_DIGEST_SIZE;
746
0
    break;
747
0
  case GNUTLS_DIG_SHAKE_128:
748
0
    ctx->init = (init_func)sha3_128_init;
749
0
    ctx->update = (update_func)sha3_128_update;
750
0
    ctx->digest = (digest_func)sha3_128_shake_output;
751
0
    ctx->ctx_ptr = &ctx->ctx.sha3_128;
752
0
    ctx->length = 0; /* unused */
753
0
    break;
754
0
  case GNUTLS_DIG_SHAKE_256:
755
0
    ctx->init = (init_func)sha3_256_init;
756
0
    ctx->update = (update_func)sha3_256_update;
757
0
    ctx->digest = (digest_func)sha3_256_shake_output;
758
0
    ctx->ctx_ptr = &ctx->ctx.sha3_256;
759
0
    ctx->length = 0; /* unused */
760
0
    break;
761
0
#endif
762
0
  case GNUTLS_DIG_MD2:
763
0
    ctx->init = (init_func)md2_init;
764
0
    ctx->update = (update_func)md2_update;
765
0
    ctx->digest = (digest_func)md2_digest;
766
0
    ctx->ctx_ptr = &ctx->ctx.md2;
767
0
    ctx->length = MD2_DIGEST_SIZE;
768
0
    break;
769
770
0
  case GNUTLS_DIG_RMD160:
771
0
    ctx->init = (init_func)ripemd160_init;
772
0
    ctx->update = (update_func)ripemd160_update;
773
0
    ctx->digest = (digest_func)ripemd160_digest;
774
0
    ctx->ctx_ptr = &ctx->ctx.ripemd160;
775
0
    ctx->length = RIPEMD160_DIGEST_SIZE;
776
0
    break;
777
0
#if ENABLE_GOST
778
0
  case GNUTLS_DIG_GOSTR_94:
779
0
    ctx->init = (init_func)gosthash94cp_init;
780
0
    ctx->update = (update_func)gosthash94cp_update;
781
0
    ctx->digest = (digest_func)gosthash94cp_digest;
782
0
    ctx->ctx_ptr = &ctx->ctx.gosthash94cp;
783
0
    ctx->length = GOSTHASH94_DIGEST_SIZE;
784
0
    break;
785
0
  case GNUTLS_DIG_STREEBOG_256:
786
0
    ctx->init = (init_func)streebog256_init;
787
0
    ctx->update = (update_func)streebog256_update;
788
0
    ctx->digest = (digest_func)streebog256_digest;
789
0
    ctx->ctx_ptr = &ctx->ctx.streebog256;
790
0
    ctx->length = STREEBOG256_DIGEST_SIZE;
791
0
    break;
792
0
  case GNUTLS_DIG_STREEBOG_512:
793
0
    ctx->init = (init_func)streebog512_init;
794
0
    ctx->update = (update_func)streebog512_update;
795
0
    ctx->digest = (digest_func)streebog512_digest;
796
0
    ctx->ctx_ptr = &ctx->ctx.streebog512;
797
0
    ctx->length = STREEBOG512_DIGEST_SIZE;
798
0
    break;
799
0
#endif
800
0
  default:
801
0
    gnutls_assert();
802
0
    return GNUTLS_E_INVALID_REQUEST;
803
0
  }
804
0
  ctx->init(ctx->ctx_ptr);
805
0
  return 0;
806
0
}
807
808
static int wrap_nettle_hash_fast(gnutls_digest_algorithm_t algo,
809
         const void *text, size_t text_size,
810
         void *digest)
811
0
{
812
0
  struct nettle_hash_ctx ctx;
813
0
  int ret;
814
815
0
  ret = _ctx_init(algo, &ctx);
816
0
  if (ret < 0)
817
0
    return gnutls_assert_val(ret);
818
819
0
  if (text_size > 0) {
820
0
    ctx.update(&ctx, text_size, text);
821
0
  }
822
0
  ctx.digest(&ctx, ctx.length, digest);
823
0
  zeroize_temp_key(&ctx, sizeof(ctx));
824
825
0
  return 0;
826
0
}
827
828
static int wrap_nettle_hash_init(gnutls_digest_algorithm_t algo, void **_ctx)
829
0
{
830
0
  struct nettle_hash_ctx *ctx;
831
0
  int ret;
832
833
0
  ctx = gnutls_malloc(sizeof(struct nettle_hash_ctx));
834
0
  if (ctx == NULL) {
835
0
    gnutls_assert();
836
0
    return GNUTLS_E_MEMORY_ERROR;
837
0
  }
838
839
0
  ctx->algo = algo;
840
841
0
  if ((ret = _ctx_init(algo, ctx)) < 0) {
842
0
    gnutls_assert();
843
0
    gnutls_free(ctx);
844
0
    return ret;
845
0
  }
846
847
0
  *_ctx = ctx;
848
849
0
  return 0;
850
0
}
851
852
static void *wrap_nettle_hash_copy(const void *_ctx)
853
0
{
854
0
  const struct nettle_hash_ctx *ctx = _ctx;
855
0
  struct nettle_hash_ctx *new_ctx;
856
0
  ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx);
857
858
0
  new_ctx = gnutls_calloc(1, sizeof(struct nettle_hash_ctx));
859
0
  if (new_ctx == NULL)
860
0
    return NULL;
861
862
0
  memcpy(new_ctx, ctx, sizeof(*ctx));
863
0
  new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off;
864
865
0
  return new_ctx;
866
0
}
867
868
static int wrap_nettle_hash_output(void *src_ctx, void *digest,
869
           size_t digestsize)
870
0
{
871
0
  struct nettle_hash_ctx *ctx;
872
0
  ctx = src_ctx;
873
874
0
  if (digest == NULL) {
875
0
    ctx->init(ctx->ctx_ptr);
876
0
    return 0;
877
0
  }
878
879
0
  if (ctx->length > 0 && digestsize < ctx->length) {
880
0
    gnutls_assert();
881
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
882
0
  }
883
884
0
  ctx->digest(ctx->ctx_ptr, digestsize, digest);
885
886
0
  return 0;
887
0
}
888
889
/* KDF functions based on MAC
890
 */
891
static int wrap_nettle_hkdf_extract(gnutls_mac_algorithm_t mac, const void *key,
892
            size_t keysize, const void *salt,
893
            size_t saltsize, void *output)
894
0
{
895
0
  struct nettle_mac_ctx ctx;
896
0
  int ret;
897
898
0
  ret = _mac_ctx_init(mac, &ctx);
899
0
  if (ret < 0)
900
0
    return gnutls_assert_val(ret);
901
902
0
  ctx.set_key(&ctx, saltsize, salt);
903
0
  hkdf_extract(&ctx.ctx, ctx.update, ctx.digest, ctx.length, keysize, key,
904
0
         output);
905
906
0
  zeroize_temp_key(&ctx, sizeof(ctx));
907
0
  return 0;
908
0
}
909
910
static int wrap_nettle_hkdf_expand(gnutls_mac_algorithm_t mac, const void *key,
911
           size_t keysize, const void *info,
912
           size_t infosize, void *output, size_t length)
913
0
{
914
0
  struct nettle_mac_ctx ctx;
915
0
  int ret;
916
917
0
  ret = _mac_ctx_init(mac, &ctx);
918
0
  if (ret < 0)
919
0
    return gnutls_assert_val(ret);
920
921
  /* RFC 5869 2.3: L must be <= 255 * HashLen */
922
0
  if (length > ctx.length * 255) {
923
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
924
0
  }
925
926
0
  ctx.set_key(&ctx, keysize, key);
927
0
  hkdf_expand(&ctx.ctx, ctx.update, ctx.digest, ctx.length, infosize,
928
0
        info, length, output);
929
0
  zeroize_temp_key(&ctx, sizeof(ctx));
930
931
0
  return 0;
932
0
}
933
934
static int wrap_nettle_pbkdf2(gnutls_mac_algorithm_t mac, const void *key,
935
            size_t keysize, const void *salt, size_t saltsize,
936
            unsigned iter_count, void *output, size_t length)
937
0
{
938
0
  struct nettle_mac_ctx ctx;
939
0
  int ret;
940
941
0
  ret = _mac_ctx_init(mac, &ctx);
942
0
  if (ret < 0)
943
0
    return gnutls_assert_val(ret);
944
945
0
  ctx.set_key(&ctx, keysize, key);
946
0
  pbkdf2(&ctx.ctx, ctx.update, ctx.digest, ctx.length, iter_count,
947
0
         saltsize, salt, length, output);
948
0
  zeroize_temp_key(&ctx, sizeof(ctx));
949
950
0
  return 0;
951
0
}
952
953
gnutls_crypto_mac_st _gnutls_mac_ops = {
954
  .init = wrap_nettle_mac_init,
955
  .setkey = wrap_nettle_mac_set_key,
956
  .setnonce = wrap_nettle_mac_set_nonce,
957
  .hash = wrap_nettle_mac_update,
958
  .output = wrap_nettle_mac_output,
959
  .deinit = wrap_nettle_mac_deinit,
960
  .fast = wrap_nettle_mac_fast,
961
  .exists = wrap_nettle_mac_exists,
962
  .copy = wrap_nettle_mac_copy,
963
};
964
965
gnutls_crypto_digest_st _gnutls_digest_ops = {
966
  .init = wrap_nettle_hash_init,
967
  .hash = wrap_nettle_hash_update,
968
  .output = wrap_nettle_hash_output,
969
  .deinit = wrap_nettle_hash_deinit,
970
  .fast = wrap_nettle_hash_fast,
971
  .exists = wrap_nettle_hash_exists,
972
  .copy = wrap_nettle_hash_copy,
973
};
974
975
/* These names are clashing with nettle's name mangling. */
976
#undef hkdf_extract
977
#undef hkdf_expand
978
#undef pbkdf2
979
gnutls_crypto_kdf_st _gnutls_kdf_ops = {
980
  .hkdf_extract = wrap_nettle_hkdf_extract,
981
  .hkdf_expand = wrap_nettle_hkdf_expand,
982
  .pbkdf2 = wrap_nettle_pbkdf2,
983
};