Coverage Report

Created: 2026-09-06 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/isc/crypto/ossl3.c
Line
Count
Source
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
#include <stdbool.h>
15
#include <stdint.h>
16
17
#include <openssl/core_names.h>
18
#include <openssl/crypto.h>
19
#include <openssl/err.h>
20
#include <openssl/evp.h>
21
#include <openssl/kdf.h>
22
#include <openssl/provider.h>
23
#include <openssl/rand.h>
24
#include <openssl/ssl.h>
25
26
#include <isc/buffer.h>
27
#include <isc/crypto.h>
28
#include <isc/hmac.h>
29
#include <isc/log.h>
30
#include <isc/magic.h>
31
#include <isc/md.h>
32
#include <isc/mem.h>
33
#include <isc/ossl_wrap.h>
34
#include <isc/overflow.h>
35
#include <isc/region.h>
36
#include <isc/safe.h>
37
#include <isc/util.h>
38
39
#define CRYPTO_ERROR(fn)                                           \
40
0
  isc__ossl_wrap_logged_toresult(                            \
41
0
    ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO, fn, \
42
0
    ISC_R_CRYPTOFAILURE, __FILE__, __LINE__)
43
44
struct isc_hmac_key {
45
  uint32_t magic;
46
  uint32_t len;
47
  isc_mem_t *mctx;
48
  const OSSL_PARAM *params;
49
  uint8_t secret[];
50
};
51
52
struct isc_crypto_quic_hp_protect {
53
  uint32_t magic;
54
  isc_mem_t *mctx;
55
  EVP_CIPHER_CTX *ctx;
56
};
57
58
STATIC_ASSERT(ISC_TYPES_COMPATIBLE(isc_crypto_aead_t, EVP_CIPHER_CTX),
59
        "isc_crypto_aead_t is not compatible with EVP_CIPHER_CTX");
60
61
constexpr uint32_t quic_hp_protect_magic = ISC_MAGIC('C', 'Q', 'h', 'p');
62
constexpr uint32_t hmac_key_magic = ISC_MAGIC('H', 'M', 'A', 'C');
63
64
static OSSL_PROVIDER *base = NULL, *fips = NULL;
65
66
/*
67
 * Because HKDF-Expand-Label is defined in the RFC of TLS 1.3, OpenSSL
68
 * has named the algorithm as TLS1.3 KDF internally.
69
 */
70
static EVP_KDF *evp_tls_1_3_kdf = NULL;
71
static EVP_KDF *evp_hkdf = NULL;
72
73
static EVP_MAC *evp_hmac = NULL;
74
75
/* AEAD */
76
static EVP_CIPHER *evp_aes_128_gcm = NULL;
77
static EVP_CIPHER *evp_aes_256_gcm = NULL;
78
static EVP_CIPHER *evp_chacha20poly1305 = NULL;
79
80
/* QUIC Header Protection */
81
static EVP_CIPHER *evp_aes_128_ctr = NULL;
82
static EVP_CIPHER *evp_aes_256_ctr = NULL;
83
static EVP_CIPHER *evp_chacha20 = NULL;
84
85
static isc_constregion_t md_to_name[ISC_MD_MAX] = {
86
  [ISC_MD_UNKNOWN] = { NULL, 0 },
87
  [ISC_MD_MD5] = { "MD5", sizeof("MD5") - 1 },
88
  [ISC_MD_SHA1] = { "SHA1", sizeof("SHA1") - 1 },
89
  [ISC_MD_SHA224] = { "SHA2-224", sizeof("SHA2-224") - 1 },
90
  [ISC_MD_SHA256] = { "SHA2-256", sizeof("SHA2-256") - 1 },
91
  [ISC_MD_SHA384] = { "SHA2-384", sizeof("SHA2-384") - 1 },
92
  [ISC_MD_SHA512] = { "SHA2-512", sizeof("SHA2-512") - 1 },
93
};
94
95
static OSSL_PARAM md_to_hmac_params[ISC_MD_MAX][2] = {
96
  [ISC_MD_UNKNOWN] = { OSSL_PARAM_END },
97
  [ISC_MD_MD5] = {
98
    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, UNCONST("MD5"), sizeof("MD5") - 1),
99
    OSSL_PARAM_END,
100
  },
101
  [ISC_MD_SHA1] = {
102
    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, UNCONST("SHA1"), sizeof("SHA1") - 1),
103
    OSSL_PARAM_END,
104
  },
105
  [ISC_MD_SHA224] = {
106
    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, UNCONST("SHA2-224"), sizeof("SHA2-224") - 1),
107
    OSSL_PARAM_END,
108
  },
109
  [ISC_MD_SHA256] = {
110
    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, UNCONST("SHA2-256"), sizeof("SHA2-256") - 1),
111
    OSSL_PARAM_END,
112
  },
113
  [ISC_MD_SHA384] = {
114
    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, UNCONST("SHA2-384"), sizeof("SHA2-384") - 1),
115
    OSSL_PARAM_END,
116
  },
117
  [ISC_MD_SHA512] = {
118
    OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, UNCONST("SHA2-512"), sizeof("SHA2-512") - 1),
119
    OSSL_PARAM_END,
120
  },
121
};
122
123
#define md_register_algorithm(alg)                                             \
124
132
  {                                                                      \
125
132
    REQUIRE(isc__crypto_md[ISC_MD_##alg] == NULL);                 \
126
132
    isc__crypto_md[ISC_MD_##alg] = EVP_MD_fetch(NULL, #alg, NULL); \
127
132
    if (isc__crypto_md[ISC_MD_##alg] == NULL) {                    \
128
0
      ERR_clear_error();                                     \
129
0
    }                                                              \
130
132
  }
131
132
static isc_result_t
133
22
register_algorithms(void) {
134
22
  if (!isc_crypto_fips_mode()) {
135
22
    md_register_algorithm(MD5);
136
137
22
    INSIST(evp_chacha20poly1305 == NULL);
138
22
    evp_chacha20poly1305 =
139
22
      EVP_CIPHER_fetch(NULL, "ChaCha20-Poly1305", NULL);
140
141
22
    INSIST(evp_chacha20 == NULL);
142
22
    evp_chacha20 = EVP_CIPHER_fetch(NULL, "ChaCha20", NULL);
143
22
  }
144
145
22
  md_register_algorithm(SHA1);
146
22
  md_register_algorithm(SHA224);
147
22
  md_register_algorithm(SHA256);
148
22
  md_register_algorithm(SHA384);
149
22
  md_register_algorithm(SHA512);
150
151
22
  INSIST(evp_aes_128_gcm == NULL);
152
22
  evp_aes_128_gcm = EVP_CIPHER_fetch(NULL, "AES-128-GCM", NULL);
153
154
22
  INSIST(evp_aes_256_gcm == NULL);
155
22
  evp_aes_256_gcm = EVP_CIPHER_fetch(NULL, "AES-256-GCM", NULL);
156
157
22
  INSIST(evp_aes_128_ctr == NULL);
158
22
  evp_aes_128_ctr = EVP_CIPHER_fetch(NULL, "AES-128-CTR", NULL);
159
160
22
  INSIST(evp_aes_256_ctr == NULL);
161
22
  evp_aes_256_ctr = EVP_CIPHER_fetch(NULL, "AES-256-CTR", NULL);
162
163
  /* We _must_ have HMAC */
164
22
  evp_hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
165
22
  if (evp_hmac == NULL) {
166
0
    FATAL_ERROR("OpenSSL failed to find an HMAC implementation. "
167
0
          "Please make sure the default provider has an "
168
0
          "EVP_MAC-HMAC implementation");
169
0
  }
170
171
22
  evp_tls_1_3_kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_TLS1_3_KDF, NULL);
172
22
  if (evp_tls_1_3_kdf == NULL) {
173
0
    FATAL_ERROR(
174
0
      "OpenSSL failed to find an TLS 1.3 KDF implementation."
175
0
      "Please make sure the default provider has an "
176
0
      "EVP_KDF-TLS13_KDF implementation");
177
0
  }
178
179
22
  evp_hkdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_HKDF, NULL);
180
22
  if (evp_hkdf == NULL) {
181
0
    FATAL_ERROR("OpenSSL failed to find an HKDF implementation. "
182
0
          "Please make sure the default provider has an "
183
0
          "EVP_KDF-HKDF implementation");
184
0
  }
185
186
22
  ERR_clear_error();
187
188
22
  return ISC_R_SUCCESS;
189
22
}
190
191
static void
192
0
unregister_algorithms(void) {
193
0
  size_t i;
194
195
0
  INSIST(evp_hkdf != NULL);
196
0
  EVP_KDF_free(evp_hkdf);
197
0
  evp_hkdf = NULL;
198
199
0
  INSIST(evp_tls_1_3_kdf != NULL);
200
0
  EVP_KDF_free(evp_tls_1_3_kdf);
201
0
  evp_tls_1_3_kdf = NULL;
202
203
0
  INSIST(evp_hmac != NULL);
204
0
  EVP_MAC_free(evp_hmac);
205
0
  evp_hmac = NULL;
206
207
0
  EVP_CIPHER_free(evp_chacha20);
208
0
  evp_chacha20 = NULL;
209
210
0
  EVP_CIPHER_free(evp_aes_256_ctr);
211
0
  evp_aes_256_ctr = NULL;
212
213
0
  EVP_CIPHER_free(evp_aes_128_ctr);
214
0
  evp_aes_128_ctr = NULL;
215
216
0
  EVP_CIPHER_free(evp_chacha20poly1305);
217
0
  evp_chacha20poly1305 = NULL;
218
219
0
  EVP_CIPHER_free(evp_aes_256_gcm);
220
0
  evp_aes_256_gcm = NULL;
221
222
0
  EVP_CIPHER_free(evp_aes_128_gcm);
223
0
  evp_aes_128_gcm = NULL;
224
225
0
  for (i = 0; i < ISC_MD_MAX; i++) {
226
0
    if (isc__crypto_md[i] != NULL) {
227
0
      EVP_MD_free(isc__crypto_md[i]);
228
0
      isc__crypto_md[i] = NULL;
229
0
    }
230
0
  }
231
0
}
232
233
#undef md_register_algorithm
234
235
/*
236
 * HMAC
237
 */
238
239
/*
240
 * Do not call EVP_Q_mac or HMAC (since it calls EVP_Q_mac internally)
241
 *
242
 * Each invocation of the EVP_Q_mac function causes an explicit fetch.
243
 */
244
isc_result_t
245
isc_hmac(isc_md_type_t type, const void *key, const size_t keylen,
246
   const unsigned char *buf, const size_t len, unsigned char *digest,
247
132
   unsigned int *digestlen) {
248
132
  EVP_MAC_CTX *ctx;
249
132
  size_t maclen;
250
251
132
  REQUIRE(type < ISC_MD_MAX);
252
253
132
  if (isc__crypto_md[type] == NULL) {
254
0
    return ISC_R_NOTIMPLEMENTED;
255
0
  }
256
257
132
  ctx = EVP_MAC_CTX_new(evp_hmac);
258
132
  RUNTIME_CHECK(ctx != NULL);
259
260
132
  if (EVP_MAC_init(ctx, key, keylen, md_to_hmac_params[type]) != 1) {
261
0
    goto fail;
262
0
  }
263
264
132
  if (EVP_MAC_update(ctx, buf, len) != 1) {
265
0
    goto fail;
266
0
  }
267
268
132
  maclen = *digestlen;
269
132
  if (EVP_MAC_final(ctx, digest, &maclen, maclen) != 1) {
270
0
    goto fail;
271
0
  }
272
273
132
  *digestlen = maclen;
274
275
132
  EVP_MAC_CTX_free(ctx);
276
132
  return ISC_R_SUCCESS;
277
278
0
fail:
279
0
  ERR_clear_error();
280
0
  EVP_MAC_CTX_free(ctx);
281
0
  return ISC_R_CRYPTOFAILURE;
282
132
}
283
284
/*
285
 * You do not need to process the key to fit the block size.
286
 *
287
 * https://github.com/openssl/openssl/blob/925e4fba1098036e8f8d22652cff6f64c5c7d571/crypto/hmac/hmac.c#L61-L80
288
 */
289
isc_result_t
290
isc_hmac_key_create(isc_md_type_t type, const void *secret, const size_t len,
291
2
        isc_mem_t *mctx, isc_hmac_key_t **keyp) {
292
2
  isc_hmac_key_t *key;
293
2
  uint8_t digest[ISC_MAX_MD_SIZE];
294
2
  unsigned int digest_len = sizeof(digest);
295
2
  size_t key_len;
296
297
2
  REQUIRE(keyp != NULL && *keyp == NULL);
298
2
  REQUIRE(type < ISC_MD_MAX);
299
300
2
  if (isc__crypto_md[type] == NULL) {
301
0
    return ISC_R_NOTIMPLEMENTED;
302
0
  }
303
304
2
  if (len > (size_t)EVP_MD_block_size(isc__crypto_md[type])) {
305
0
    RETERR(isc_md(type, secret, len, digest, &digest_len));
306
0
    secret = digest;
307
0
    key_len = digest_len;
308
2
  } else {
309
2
    key_len = len;
310
2
  }
311
312
2
  key = isc_mem_get(mctx, STRUCT_FLEX_SIZE(key, secret, key_len));
313
2
  *key = (isc_hmac_key_t){
314
2
    .magic = hmac_key_magic,
315
2
    .len = key_len,
316
2
    .params = md_to_hmac_params[type],
317
2
  };
318
2
  memmove(key->secret, secret, key_len);
319
2
  isc_mem_attach(mctx, &key->mctx);
320
321
2
  *keyp = key;
322
323
2
  return ISC_R_SUCCESS;
324
2
}
325
326
void
327
0
isc_hmac_key_destroy(isc_hmac_key_t **keyp) {
328
0
  isc_hmac_key_t *key;
329
330
0
  REQUIRE(keyp != NULL && *keyp != NULL);
331
0
  REQUIRE((*keyp)->magic == hmac_key_magic);
332
333
0
  key = *keyp;
334
0
  *keyp = NULL;
335
336
0
  key->magic = 0x00;
337
338
0
  isc_safe_memwipe(key->secret, key->len);
339
0
  isc_mem_putanddetach(&key->mctx, key,
340
0
           STRUCT_FLEX_SIZE(key, secret, key->len));
341
0
}
342
343
isc_region_t
344
4
isc_hmac_key_expose(isc_hmac_key_t *key) {
345
4
  REQUIRE(key != NULL && key->magic == hmac_key_magic);
346
347
4
  return (isc_region_t){ .base = key->secret, .length = key->len };
348
4
}
349
350
bool
351
0
isc_hmac_key_equal(isc_hmac_key_t *a, isc_hmac_key_t *b) {
352
0
  REQUIRE(a != NULL && a->magic == hmac_key_magic);
353
0
  REQUIRE(b != NULL && b->magic == hmac_key_magic);
354
355
0
  if (a->params != b->params) {
356
0
    return false;
357
0
  }
358
359
0
  if (a->len != b->len) {
360
0
    return false;
361
0
  }
362
363
0
  return isc_safe_memequal(a->secret, b->secret, a->len);
364
0
}
365
366
isc_hmac_t *
367
27
isc_hmac_new(void) {
368
27
  EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(evp_hmac);
369
27
  RUNTIME_CHECK(ctx != NULL);
370
27
  return ctx;
371
27
}
372
373
void
374
27
isc_hmac_free(isc_hmac_t *hmac) {
375
27
  EVP_MAC_CTX_free(hmac);
376
27
}
377
378
isc_result_t
379
27
isc_hmac_init(isc_hmac_t *hmac, isc_hmac_key_t *key) {
380
27
  REQUIRE(key != NULL && key->magic == hmac_key_magic);
381
27
  REQUIRE(hmac != NULL);
382
383
27
  if (EVP_MAC_init(hmac, key->secret, key->len, key->params) != 1) {
384
0
    ERR_clear_error();
385
0
    return ISC_R_CRYPTOFAILURE;
386
0
  }
387
388
27
  return ISC_R_SUCCESS;
389
27
}
390
391
isc_result_t
392
191
isc_hmac_update(isc_hmac_t *hmac, const unsigned char *buf, const size_t len) {
393
191
  REQUIRE(hmac != NULL);
394
395
191
  if (buf == NULL || len == 0) {
396
0
    return ISC_R_SUCCESS;
397
0
  }
398
399
191
  if (EVP_MAC_update(hmac, buf, len) != 1) {
400
0
    ERR_clear_error();
401
0
    return ISC_R_CRYPTOFAILURE;
402
0
  }
403
404
191
  return ISC_R_SUCCESS;
405
191
}
406
407
isc_result_t
408
27
isc_hmac_final(isc_hmac_t *hmac, isc_buffer_t *out) {
409
27
  size_t len;
410
411
27
  REQUIRE(hmac != NULL);
412
413
27
  len = isc_buffer_availablelength(out);
414
27
  if (len < EVP_MAC_CTX_get_mac_size(hmac)) {
415
0
    return ISC_R_NOSPACE;
416
0
  }
417
418
27
  if (EVP_MAC_final(hmac, isc_buffer_used(out), &len, len) != 1) {
419
0
    ERR_clear_error();
420
0
    return ISC_R_CRYPTOFAILURE;
421
0
  }
422
423
27
  isc_buffer_add(out, len);
424
425
27
  return ISC_R_SUCCESS;
426
27
}
427
428
void
429
0
isc_crypto_aead_destroy(isc_crypto_aead_t **aeadp) {
430
0
  EVP_CIPHER_CTX *ctx;
431
432
0
  REQUIRE(aeadp != NULL && *aeadp != NULL);
433
434
0
  ctx = MOVE_OWNERSHIP(*aeadp);
435
436
0
  EVP_CIPHER_CTX_free(ctx);
437
0
}
438
439
isc_result_t
440
isc_crypto_aead_create(isc_crypto_aead_algorithm_t algorithm,
441
           isc_constregion_t key,
442
           isc_crypto_aead_direction_t direction,
443
0
           isc_crypto_aead_t **aeadp) {
444
0
  EVP_CIPHER_CTX *ctx;
445
0
  isc_result_t result;
446
0
  EVP_CIPHER *evp;
447
0
  size_t nonce;
448
0
  int dir;
449
450
0
  const OSSL_PARAM params[] = {
451
0
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, &nonce),
452
0
    OSSL_PARAM_END,
453
0
  };
454
455
0
  REQUIRE(key.base != NULL);
456
0
  REQUIRE(aeadp != NULL && *aeadp == NULL);
457
458
0
  switch (direction) {
459
0
  case ISC_CRYPTO_AEAD_DIRECTION_SEAL:
460
0
    dir = 1;
461
0
    break;
462
0
  case ISC_CRYPTO_AEAD_DIRECTION_OPEN:
463
0
    dir = 0;
464
0
    break;
465
0
  default:
466
0
    UNREACHABLE();
467
0
  }
468
469
0
  switch (algorithm) {
470
0
  case ISC_CRYPTO_AEAD_ALGORITHM_AES128GCM:
471
0
    nonce = isc_crypto_aes128gcm_nonce_length;
472
0
    evp = evp_aes_128_gcm;
473
0
    break;
474
0
  case ISC_CRYPTO_AEAD_ALGORITHM_AES256GCM:
475
0
    nonce = isc_crypto_aes256gcm_nonce_length;
476
0
    evp = evp_aes_256_gcm;
477
0
    break;
478
0
  case ISC_CRYPTO_AEAD_ALGORITHM_CHACHA20POLY1305:
479
0
    nonce = isc_crypto_chacha20poly1305_nonce_length;
480
0
    evp = evp_chacha20poly1305;
481
0
    break;
482
0
  default:
483
0
    UNREACHABLE();
484
0
  };
485
486
0
  if (evp == NULL) {
487
0
    return ISC_R_NOTIMPLEMENTED;
488
0
  }
489
490
0
  ctx = EVP_CIPHER_CTX_new();
491
0
  if (ctx == NULL) {
492
0
    CLEANUP(CRYPTO_ERROR("EVP_CIPHER_CTX_new"));
493
0
  }
494
495
0
  if (EVP_CipherInit_ex2(ctx, evp, key.base, NULL, dir, params) != 1) {
496
0
    CLEANUP(CRYPTO_ERROR("EVP_CipherInit_ex2"));
497
0
  }
498
499
0
  *aeadp = MOVE_OWNERSHIP(ctx);
500
501
0
  result = ISC_R_SUCCESS;
502
0
cleanup:
503
0
  EVP_CIPHER_CTX_free(ctx);
504
0
  return result;
505
0
}
506
507
isc_result_t
508
isc_crypto_aead_seal(isc_crypto_aead_t *aead, isc_constregion_t nonce,
509
         isc_constregion_t plaintext, isc_region_t out,
510
         size_t *out_sealed_len,
511
0
         isc_constregion_t additional_data) {
512
0
  isc_result_t result;
513
0
  size_t sealed;
514
0
  int len;
515
516
0
  REQUIRE(aead != NULL);
517
0
  REQUIRE(nonce.base != NULL);
518
0
  REQUIRE(out.base != NULL && plaintext.base != NULL);
519
0
  REQUIRE(out.length ==
520
0
    ISC_CHECKED_ADD(plaintext.length, isc_crypto_aead_tag_length));
521
0
  REQUIRE(out_sealed_len != NULL);
522
523
0
  OSSL_PARAM params[] = {
524
0
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
525
0
          out.base + plaintext.length,
526
0
          isc_crypto_aead_tag_length),
527
0
    OSSL_PARAM_END,
528
0
  };
529
530
0
  ERR_set_mark();
531
532
0
  if (EVP_EncryptInit_ex(aead, NULL, NULL, NULL, nonce.base) != 1) {
533
0
    CLEANUP(ISC_R_CRYPTOFAILURE);
534
0
  }
535
536
0
  if (additional_data.base != NULL) {
537
0
    INSIST(additional_data.length != 0);
538
0
    if (EVP_EncryptUpdate(aead, NULL, &len, additional_data.base,
539
0
              additional_data.length) != 1)
540
0
    {
541
0
      CLEANUP(ISC_R_CRYPTOFAILURE);
542
0
    }
543
0
  }
544
545
0
  len = out.length;
546
0
  if (EVP_EncryptUpdate(aead, out.base, &len, plaintext.base,
547
0
            plaintext.length) != 1)
548
0
  {
549
0
    CLEANUP(ISC_R_CRYPTOFAILURE);
550
0
  }
551
552
0
  sealed = len + isc_crypto_aead_tag_length;
553
554
0
  out.base += len;
555
0
  len = out.length - len;
556
0
  if (EVP_EncryptFinal_ex(aead, out.base, &len) != 1) {
557
0
    CLEANUP(ISC_R_CRYPTOFAILURE);
558
0
  }
559
560
0
  if (EVP_CIPHER_CTX_get_params(aead, params) != 1) {
561
0
    CLEANUP(ISC_R_CRYPTOFAILURE);
562
0
  }
563
564
0
  *out_sealed_len = sealed + len;
565
566
0
  result = ISC_R_SUCCESS;
567
0
cleanup:
568
0
  ERR_pop_to_mark();
569
0
  return result;
570
0
}
571
572
isc_result_t
573
isc_crypto_aead_open(isc_crypto_aead_t *aead, isc_constregion_t nonce,
574
         isc_constregion_t ciphertext, isc_region_t out,
575
         size_t *out_opened_len,
576
0
         isc_constregion_t additional_data) {
577
0
  isc_result_t result;
578
0
  const uint8_t *ct;
579
0
  size_t opened;
580
0
  int len = 0;
581
582
0
  uint8_t *k = NULL;
583
584
0
  REQUIRE(aead != NULL);
585
0
  REQUIRE(nonce.base != NULL);
586
0
  REQUIRE(out.base != NULL && ciphertext.base != NULL);
587
0
  REQUIRE(out.length ==
588
0
    ISC_CHECKED_SUB(ciphertext.length, isc_crypto_aead_tag_length));
589
0
  REQUIRE(out_opened_len != NULL);
590
591
0
  ct = ciphertext.base;
592
0
  const OSSL_PARAM params[] = {
593
0
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
594
0
          UNCONST(ct + out.length),
595
0
          isc_crypto_aead_tag_length),
596
0
    OSSL_PARAM_END,
597
0
  };
598
599
0
  ERR_set_mark();
600
601
0
  if (EVP_DecryptInit_ex2(aead, NULL, k, nonce.base, params) != 1) {
602
0
    CLEANUP(ISC_R_CRYPTOFAILURE);
603
0
  }
604
605
0
  if (additional_data.base != NULL) {
606
0
    INSIST(additional_data.length != 0);
607
0
    if (EVP_DecryptUpdate(aead, NULL, &len, additional_data.base,
608
0
              additional_data.length) != 1)
609
0
    {
610
0
      CLEANUP(ISC_R_CRYPTOFAILURE);
611
0
    }
612
0
  }
613
614
0
  len = out.length;
615
0
  if (EVP_DecryptUpdate(aead, out.base, &len, ciphertext.base, len) != 1)
616
0
  {
617
0
    CLEANUP(ISC_R_CRYPTOFAILURE);
618
0
  }
619
620
0
  opened = len;
621
622
0
  out.base += len;
623
0
  len = out.length - len;
624
0
  if (EVP_DecryptFinal_ex(aead, out.base, &len) != 1) {
625
0
    CLEANUP(ISC_R_CRYPTOFAILURE);
626
0
  }
627
628
0
  *out_opened_len = opened;
629
0
  result = ISC_R_SUCCESS;
630
0
cleanup:
631
0
  ERR_pop_to_mark();
632
0
  return result;
633
0
}
634
635
isc_result_t
636
isc_crypto_hkdf_extract(isc_region_t out, isc_md_type_t md,
637
0
      isc_constregion_t secret, isc_constregion_t salt) {
638
0
  isc_result_t result;
639
0
  EVP_KDF_CTX *ctx;
640
0
  int mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
641
642
0
  REQUIRE(md != ISC_MD_UNKNOWN && md < ISC_MD_MAX);
643
0
  REQUIRE(out.base != NULL && out.length != 0);
644
0
  REQUIRE(secret.base != NULL && secret.length != 0);
645
0
  REQUIRE(salt.base != NULL && salt.length != 0);
646
647
0
  if (isc__crypto_md[md] == NULL) {
648
0
    return ISC_R_NOTIMPLEMENTED;
649
0
  }
650
651
0
  const OSSL_PARAM params[] = {
652
0
    OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, &mode),
653
0
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST,
654
0
               UNCONST(md_to_name[md].base),
655
0
               md_to_name[md].length),
656
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY,
657
0
          UNCONST(secret.base), secret.length),
658
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, UNCONST(salt.base),
659
0
          salt.length),
660
0
    OSSL_PARAM_END,
661
0
  };
662
663
0
  ctx = EVP_KDF_CTX_new(evp_hkdf);
664
0
  if (ctx == NULL) {
665
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_CTX_new"));
666
0
  }
667
668
0
  if (EVP_KDF_derive(ctx, out.base, out.length, params) != 1) {
669
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_derive"));
670
0
  }
671
672
0
  result = ISC_R_SUCCESS;
673
0
cleanup:
674
0
  EVP_KDF_CTX_free(ctx);
675
0
  return result;
676
0
}
677
678
isc_result_t
679
isc_crypto_hkdf_expand(isc_region_t out, isc_md_type_t md,
680
0
           isc_constregion_t prk, isc_constregion_t info) {
681
0
  isc_result_t result;
682
0
  EVP_KDF_CTX *ctx;
683
0
  int mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
684
685
0
  REQUIRE(md != ISC_MD_UNKNOWN && md < ISC_MD_MAX);
686
0
  REQUIRE(out.base != NULL && out.length != 0);
687
0
  REQUIRE(prk.base != NULL && prk.length != 0);
688
0
  REQUIRE(info.base != NULL && info.length != 0);
689
690
0
  if (isc__crypto_md[md] == NULL) {
691
0
    return ISC_R_NOTIMPLEMENTED;
692
0
  }
693
694
0
  const OSSL_PARAM params[] = {
695
0
    OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, &mode),
696
0
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST,
697
0
               UNCONST(md_to_name[md].base),
698
0
               md_to_name[md].length),
699
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, UNCONST(prk.base),
700
0
          prk.length),
701
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, UNCONST(info.base),
702
0
          info.length),
703
0
    OSSL_PARAM_END,
704
0
  };
705
706
0
  ctx = EVP_KDF_CTX_new(evp_hkdf);
707
0
  if (ctx == NULL) {
708
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_CTX_new"));
709
0
  }
710
711
0
  if (EVP_KDF_derive(ctx, out.base, out.length, params) != 1) {
712
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_derive"));
713
0
  }
714
715
0
  result = ISC_R_SUCCESS;
716
0
cleanup:
717
0
  EVP_KDF_CTX_free(ctx);
718
0
  return result;
719
0
}
720
721
isc_result_t
722
isc_crypto_hkdf_expand_label(isc_region_t out, isc_md_type_t md,
723
           isc_constregion_t secret,
724
0
           isc_constregion_t label) {
725
0
  isc_result_t result;
726
0
  EVP_KDF_CTX *ctx;
727
0
  int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
728
729
0
  REQUIRE(out.base != NULL && out.length != 0);
730
0
  REQUIRE(md != ISC_MD_UNKNOWN && md < ISC_MD_MAX);
731
0
  REQUIRE(secret.base != NULL && secret.length != 0);
732
0
  REQUIRE(label.base != NULL && label.length != 0);
733
734
0
  if (isc__crypto_md[md] == NULL) {
735
0
    return ISC_R_NOTIMPLEMENTED;
736
0
  }
737
738
0
  const OSSL_PARAM params[] = {
739
0
    OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, &mode),
740
0
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST,
741
0
               UNCONST(md_to_name[md].base),
742
0
               md_to_name[md].length),
743
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PREFIX,
744
0
          UNCONST("tls13 "),
745
0
          sizeof("tls13 ") - 1),
746
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY,
747
0
          UNCONST(secret.base), secret.length),
748
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL,
749
0
          UNCONST(label.base), label.length),
750
0
    OSSL_PARAM_END,
751
0
  };
752
753
  /* Please see the comment in `evp_tls_1_3_kdf` */
754
0
  ctx = EVP_KDF_CTX_new(evp_tls_1_3_kdf);
755
0
  if (ctx == NULL) {
756
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_CTX_new"));
757
0
  }
758
759
0
  if (EVP_KDF_derive(ctx, out.base, out.length, params) != 1) {
760
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_derive"));
761
0
  }
762
763
0
  result = ISC_R_SUCCESS;
764
0
cleanup:
765
0
  EVP_KDF_CTX_free(ctx);
766
0
  return result;
767
0
}
768
769
isc_result_t
770
isc_crypto_hkdf(isc_region_t out, isc_md_type_t md, isc_constregion_t ikm,
771
0
    isc_constregion_t salt, isc_constregion_t info) {
772
0
  isc_result_t result;
773
0
  EVP_KDF_CTX *ctx;
774
0
  int mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
775
776
0
  REQUIRE(md != ISC_MD_UNKNOWN && md < ISC_MD_MAX);
777
0
  REQUIRE(out.base != NULL && out.length != 0);
778
0
  REQUIRE(ikm.base != NULL && ikm.length != 0);
779
0
  REQUIRE(salt.base != NULL && salt.length != 0);
780
0
  REQUIRE(info.base != NULL && info.length != 0);
781
782
0
  if (isc__crypto_md[md] == NULL) {
783
0
    return ISC_R_NOTIMPLEMENTED;
784
0
  }
785
786
0
  const OSSL_PARAM params[] = {
787
0
    OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, &mode),
788
0
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST,
789
0
               UNCONST(md_to_name[md].base),
790
0
               md_to_name[md].length),
791
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, UNCONST(ikm.base),
792
0
          ikm.length),
793
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, UNCONST(info.base),
794
0
          info.length),
795
0
    OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, UNCONST(salt.base),
796
0
          salt.length),
797
0
    OSSL_PARAM_END,
798
0
  };
799
800
0
  ctx = EVP_KDF_CTX_new(evp_hkdf);
801
0
  if (ctx == NULL) {
802
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_CTX_new"));
803
0
  }
804
805
0
  if (EVP_KDF_derive(ctx, out.base, out.length, params) != 1) {
806
0
    CLEANUP(CRYPTO_ERROR("EVP_KDF_derive"));
807
0
  }
808
809
0
  result = ISC_R_SUCCESS;
810
0
cleanup:
811
0
  EVP_KDF_CTX_free(ctx);
812
0
  return result;
813
0
}
814
815
void
816
0
isc_crypto_quic_hp_protect_destroy(isc_crypto_quic_hp_protect_t **protp) {
817
0
  isc_crypto_quic_hp_protect_t *prot;
818
819
0
  REQUIRE(protp != NULL && *protp != NULL &&
820
0
    (*protp)->magic == quic_hp_protect_magic);
821
822
0
  prot = MOVE_OWNERSHIP(*protp);
823
0
  prot->magic = 0x00;
824
0
  EVP_CIPHER_CTX_free(prot->ctx);
825
0
  isc_mem_putanddetach(&prot->mctx, prot, sizeof(*prot));
826
0
}
827
828
isc_result_t
829
isc_crypto_quic_hp_protect_create(
830
  isc_mem_t *mctx, isc_constregion_t key,
831
  isc_crypto_quic_hp_protect_algorithm_t algorithm,
832
0
  isc_crypto_quic_hp_protect_t **protp) {
833
0
  isc_crypto_quic_hp_protect_t *prot;
834
0
  const EVP_CIPHER *evp;
835
0
  EVP_CIPHER_CTX *ctx;
836
0
  size_t len;
837
838
0
  REQUIRE(protp != NULL && *protp == NULL);
839
0
  REQUIRE(key.base != NULL);
840
841
0
  switch (algorithm) {
842
0
  case ISC_CRYPTO_QUIC_HP_PROTECT_ALGORITHM_AES128:
843
0
    len = isc_crypto_aes128gcm_key_length;
844
0
    evp = evp_aes_128_ctr;
845
0
    break;
846
0
  case ISC_CRYPTO_QUIC_HP_PROTECT_ALGORITHM_AES256:
847
0
    len = isc_crypto_aes256gcm_key_length;
848
0
    evp = evp_aes_256_ctr;
849
0
    break;
850
0
  case ISC_CRYPTO_QUIC_HP_PROTECT_ALGORITHM_CHACHA20:
851
0
    len = isc_crypto_chacha20poly1305_key_length;
852
0
    evp = evp_chacha20;
853
0
    break;
854
0
  default:
855
0
    UNREACHABLE();
856
0
  }
857
858
0
  INSIST(key.length == len);
859
860
0
  if (evp == NULL) {
861
0
    return ISC_R_NOTIMPLEMENTED;
862
0
  }
863
864
0
  ctx = EVP_CIPHER_CTX_new();
865
0
  if (ctx == NULL) {
866
0
    return CRYPTO_ERROR("EVP_CIPHER_CTX_new");
867
0
  }
868
869
0
  if (EVP_CipherInit_ex2(ctx, evp, key.base, NULL, 1, NULL) != 1) {
870
0
    EVP_CIPHER_CTX_free(ctx);
871
0
    return CRYPTO_ERROR("EVP_CipherInit_ex2");
872
0
  }
873
874
0
  prot = isc_mem_get(mctx, sizeof(*prot));
875
0
  *prot = (isc_crypto_quic_hp_protect_t){
876
0
    .magic = quic_hp_protect_magic,
877
0
    .ctx = ctx,
878
0
  };
879
0
  isc_mem_attach(mctx, &prot->mctx);
880
881
0
  *protp = prot;
882
883
0
  return ISC_R_SUCCESS;
884
0
}
885
886
isc_result_t
887
isc_crypto_quic_hp_protect_mask(isc_crypto_quic_hp_protect_t *prot,
888
0
        uint8_t *out, const uint8_t *sample) {
889
0
  static const uint8_t zeros[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
890
0
  isc_result_t result;
891
0
  int len;
892
893
0
  REQUIRE(prot != NULL && prot->magic == quic_hp_protect_magic);
894
0
  REQUIRE(out != NULL && sample != NULL);
895
896
0
  if (EVP_EncryptInit_ex2(prot->ctx, NULL, NULL, sample, NULL) != 1) {
897
0
    CLEANUP(CRYPTO_ERROR("EVP_EncryptInit_ex2"));
898
0
  }
899
900
0
  if (EVP_EncryptUpdate(prot->ctx, out, &len, zeros, sizeof(zeros)) != 1)
901
0
  {
902
0
    CLEANUP(CRYPTO_ERROR("EVP_EncryptUpdate"));
903
0
  }
904
905
0
  if (EVP_EncryptFinal_ex(prot->ctx, out + sizeof(zeros), &len) != 1) {
906
0
    CLEANUP(CRYPTO_ERROR("EVP_EncryptFinal_ex"));
907
0
  }
908
909
0
  result = ISC_R_SUCCESS;
910
911
0
cleanup:
912
0
  return result;
913
0
}
914
915
bool
916
22
isc_crypto_fips_mode(void) {
917
22
  return EVP_default_properties_is_fips_enabled(NULL) != 0;
918
22
}
919
920
isc_result_t
921
0
isc_crypto_fips_enable(void) {
922
0
  if (isc_crypto_fips_mode()) {
923
0
    return ISC_R_SUCCESS;
924
0
  }
925
926
0
  INSIST(fips == NULL);
927
0
  fips = OSSL_PROVIDER_load(NULL, "fips");
928
0
  if (fips == NULL) {
929
0
    return isc_ossl_wrap_logged_toresult(
930
0
      ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
931
0
      "OSSL_PROVIDER_load", ISC_R_CRYPTOFAILURE);
932
0
  }
933
934
0
  INSIST(base == NULL);
935
0
  base = OSSL_PROVIDER_load(NULL, "base");
936
0
  if (base == NULL) {
937
0
    OSSL_PROVIDER_unload(fips);
938
0
    return isc_ossl_wrap_logged_toresult(
939
0
      ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
940
0
      "OSS_PROVIDER_load", ISC_R_CRYPTOFAILURE);
941
0
  }
942
943
0
  if (EVP_default_properties_enable_fips(NULL, 1) == 0) {
944
0
    return isc_ossl_wrap_logged_toresult(
945
0
      ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
946
0
      "EVP_default_properties_enable_fips",
947
0
      ISC_R_CRYPTOFAILURE);
948
0
  }
949
950
0
  unregister_algorithms();
951
0
  register_algorithms();
952
953
0
  return ISC_R_SUCCESS;
954
0
}
955
956
/*
957
 * OPENSSL_cleanup() in OpenSSL 4 doesn't free the memory, which is not
958
 * compatible with BIND 9's memory leak detection code, that is why the memory
959
 * tracking has been disabled in this module, and this function is a no-op.
960
 * This can be cleaned up once OpenSSL 1.1.x support is removed.
961
 *
962
 * See https://github.com/openssl/openssl/pull/29721
963
 */
964
void
965
0
isc__crypto_setdestroycheck(bool check) {
966
0
  UNUSED(check);
967
0
}
968
969
void
970
22
isc__crypto_initialize(void) {
971
  /*
972
   * We call OPENSSL_cleanup() manually, in a correct order, thus disable
973
   * the automatic atexit() handler.
974
   */
975
22
  uint64_t opts = OPENSSL_INIT_LOAD_CONFIG | OPENSSL_INIT_NO_ATEXIT;
976
977
22
  RUNTIME_CHECK(OPENSSL_init_ssl(opts, NULL) == 1);
978
979
22
  register_algorithms();
980
981
#if defined(ENABLE_FIPS_MODE)
982
  if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
983
    ERR_clear_error();
984
    FATAL_ERROR("Failed to toggle FIPS mode but is "
985
          "required for this build");
986
  }
987
#endif
988
989
  /* Protect ourselves against unseeded PRNG */
990
22
  if (RAND_status() != 1) {
991
0
    isc_ossl_wrap_logged_toresult(
992
0
      ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
993
0
      "RAND_status", ISC_R_CRYPTOFAILURE);
994
0
    FATAL_ERROR("OpenSSL pseudorandom number generator "
995
0
          "cannot be initialized (see the `PRNG not "
996
0
          "seeded' message in the OpenSSL FAQ)");
997
0
  }
998
22
}
999
1000
void
1001
0
isc__crypto_shutdown(void) {
1002
0
  unregister_algorithms();
1003
1004
0
  if (base != NULL) {
1005
0
    OSSL_PROVIDER_unload(base);
1006
0
  }
1007
1008
0
  if (fips != NULL) {
1009
0
    OSSL_PROVIDER_unload(fips);
1010
0
  }
1011
1012
0
  OPENSSL_cleanup();
1013
0
}