Coverage Report

Created: 2025-11-07 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptsetup/lib/utils_pbkdf.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * utils_pbkdf - PBKDF settings for libcryptsetup
4
 *
5
 * Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
6
 * Copyright (C) 2009-2025 Milan Broz
7
 */
8
9
#include <stdlib.h>
10
#include <errno.h>
11
12
#include "internal.h"
13
14
const struct crypt_pbkdf_type default_pbkdf2 = {
15
  .type = CRYPT_KDF_PBKDF2,
16
  .hash = DEFAULT_LUKS1_HASH,
17
  .time_ms = DEFAULT_LUKS1_ITER_TIME
18
};
19
20
const struct crypt_pbkdf_type default_argon2i = {
21
  .type = CRYPT_KDF_ARGON2I,
22
  .hash = DEFAULT_LUKS1_HASH,
23
  .time_ms = DEFAULT_LUKS2_ITER_TIME,
24
  .max_memory_kb = DEFAULT_LUKS2_MEMORY_KB,
25
  .parallel_threads = DEFAULT_LUKS2_PARALLEL_THREADS
26
};
27
28
const struct crypt_pbkdf_type default_argon2id = {
29
  .type = CRYPT_KDF_ARGON2ID,
30
  .hash = DEFAULT_LUKS1_HASH,
31
  .time_ms = DEFAULT_LUKS2_ITER_TIME,
32
  .max_memory_kb = DEFAULT_LUKS2_MEMORY_KB,
33
  .parallel_threads = DEFAULT_LUKS2_PARALLEL_THREADS
34
};
35
36
const struct crypt_pbkdf_type *crypt_get_pbkdf_type_params(const char *pbkdf_type)
37
2.20k
{
38
2.20k
  if (!pbkdf_type)
39
0
    return NULL;
40
41
2.20k
  if (!strcmp(pbkdf_type, CRYPT_KDF_PBKDF2))
42
0
    return &default_pbkdf2;
43
2.20k
  else if (!strcmp(pbkdf_type, CRYPT_KDF_ARGON2I))
44
0
    return &default_argon2i;
45
2.20k
  else if (!strcmp(pbkdf_type, CRYPT_KDF_ARGON2ID))
46
2.20k
    return &default_argon2id;
47
48
0
  return NULL;
49
2.20k
}
50
51
uint32_t pbkdf_adjusted_phys_memory_kb(void)
52
2.20k
{
53
2.20k
  uint64_t free_kb, memory_kb = crypt_getphysmemory_kb();
54
55
  /* Ignore bogus value */
56
2.20k
  if (memory_kb < (128 * 1024) || memory_kb > UINT32_MAX)
57
0
    return DEFAULT_LUKS2_MEMORY_KB;
58
59
  /*
60
   * Never use more than half of physical memory.
61
   * OOM killer is too clever...
62
   */
63
2.20k
  memory_kb /= 2;
64
65
  /*
66
   * On systems with < 4GB RAM without swap
67
   * never use more that half of available free memory.
68
   * This is a temporary hack to avoid OOM on small systems.
69
   */
70
2.20k
  if (memory_kb < (2 * 1024 * 1024) && !crypt_swapavailable()) {
71
0
    free_kb = crypt_getphysmemoryfree_kb();
72
73
    /*
74
     * Using exactly free memory causes OOM too, use only half of the value.
75
     * Ignore small values (< 64MB), user should use PBKDF2 in such environment.
76
     */
77
0
    free_kb /= 2;
78
79
0
    if (free_kb > (64 * 1024) && free_kb < memory_kb)
80
0
      return free_kb;
81
0
  }
82
83
2.20k
  return memory_kb;
84
2.20k
}
85
86
/*
87
 * PBKDF configuration interface
88
 */
89
int verify_pbkdf_params(struct crypt_device *cd,
90
      const struct crypt_pbkdf_type *pbkdf)
91
4.40k
{
92
4.40k
  struct crypt_pbkdf_limits pbkdf_limits;
93
4.40k
  const char *pbkdf_type;
94
4.40k
  int r;
95
96
4.40k
  r = init_crypto(cd);
97
4.40k
  if (r < 0)
98
0
    return r;
99
100
4.40k
  if (!pbkdf || !pbkdf->type ||
101
2.20k
      (!pbkdf->hash && !strcmp(pbkdf->type, "pbkdf2")))
102
2.20k
    return -EINVAL;
103
104
2.20k
  if (!pbkdf->time_ms && !(pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK)) {
105
0
    log_err(cd, _("Requested PBKDF target time cannot be zero."));
106
0
    return -EINVAL;
107
0
  }
108
109
2.20k
  r = crypt_parse_pbkdf(pbkdf->type, &pbkdf_type);
110
2.20k
  if (r < 0) {
111
0
    log_err(cd, _("Unknown PBKDF type %s."), pbkdf->type);
112
0
    return r;
113
0
  }
114
115
2.20k
  if (pbkdf->hash && crypt_hash_size(pbkdf->hash) < 0) {
116
0
    log_err(cd, _("Requested hash %s is not supported."), pbkdf->hash);
117
0
    return -EINVAL;
118
0
  }
119
120
2.20k
  r = crypt_pbkdf_get_limits(pbkdf->type, &pbkdf_limits);
121
2.20k
  if (r < 0)
122
0
    return r;
123
124
2.20k
  if (crypt_get_type(cd) &&
125
0
      !strcmp(crypt_get_type(cd), CRYPT_LUKS1) &&
126
0
      strcmp(pbkdf_type, CRYPT_KDF_PBKDF2)) {
127
0
    log_err(cd, _("Requested PBKDF type is not supported for LUKS1."));
128
0
    return -EINVAL;
129
0
  }
130
131
2.20k
  if (!strcmp(pbkdf_type, CRYPT_KDF_PBKDF2)) {
132
0
    if (pbkdf->max_memory_kb || pbkdf->parallel_threads) {
133
0
      log_err(cd, _("PBKDF max memory or parallel threads must not be set with pbkdf2."));
134
0
      return -EINVAL;
135
0
    }
136
0
    if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK &&
137
0
        pbkdf->iterations < pbkdf_limits.min_iterations) {
138
0
      log_err(cd, _("Forced iteration count is too low for %s (minimum is %u)."),
139
0
        pbkdf_type, pbkdf_limits.min_iterations);
140
0
      return -EINVAL;
141
0
    }
142
0
    return 0;
143
0
  }
144
145
  /* TODO: properly define minimal iterations and also minimal memory values */
146
2.20k
  if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK) {
147
0
    if (pbkdf->iterations < pbkdf_limits.min_iterations) {
148
0
      log_err(cd, _("Forced iteration count is too low for %s (minimum is %u)."),
149
0
        pbkdf_type, pbkdf_limits.min_iterations);
150
0
      r = -EINVAL;
151
0
    }
152
0
    if (pbkdf->max_memory_kb < pbkdf_limits.min_memory) {
153
0
      log_err(cd, _("Forced memory cost is too low for %s (minimum is %u kilobytes)."),
154
0
        pbkdf_type, pbkdf_limits.min_memory);
155
0
      r = -EINVAL;
156
0
    }
157
0
  }
158
159
2.20k
  if (pbkdf->max_memory_kb > pbkdf_limits.max_memory) {
160
0
    log_err(cd, _("Requested maximum PBKDF memory cost is too high (maximum is %d kilobytes)."),
161
0
      pbkdf_limits.max_memory);
162
0
    r = -EINVAL;
163
0
  }
164
2.20k
  if (1024ULL * pbkdf->max_memory_kb > SIZE_MAX) {
165
0
    log_err(cd, _("Requested maximum PBKDF memory cost is too high (limited by the integer maximal size)."));
166
0
    r = -EINVAL;
167
0
  }
168
2.20k
  if (!pbkdf->max_memory_kb) {
169
0
    log_err(cd, _("Requested maximum PBKDF memory cannot be zero."));
170
0
    r = -EINVAL;
171
0
  }
172
2.20k
  if (pbkdf->parallel_threads > pbkdf_limits.max_parallel) {
173
0
    log_err(cd, _("Requested maximum PBKDF parallel cost is too high (maximum is %d)."),
174
0
      pbkdf_limits.max_parallel);
175
0
    r = -EINVAL;
176
0
  }
177
2.20k
  if (!pbkdf->parallel_threads) {
178
0
    log_err(cd, _("Requested PBKDF parallel threads cannot be zero."));
179
0
    r = -EINVAL;
180
0
  }
181
182
2.20k
  return r;
183
2.20k
}
184
185
int init_pbkdf_type(struct crypt_device *cd,
186
        const struct crypt_pbkdf_type *pbkdf,
187
        const char *dev_type)
188
2.20k
{
189
2.20k
  struct crypt_pbkdf_type *cd_pbkdf = crypt_get_pbkdf(cd);
190
2.20k
  struct crypt_pbkdf_limits pbkdf_limits;
191
2.20k
  const char *hash, *type;
192
2.20k
  unsigned cpus;
193
2.20k
  uint32_t old_flags, memory_kb;
194
2.20k
  int r;
195
196
2.20k
  if (crypt_fips_mode()) {
197
0
    if (pbkdf && strcmp(pbkdf->type, CRYPT_KDF_PBKDF2)) {
198
0
      log_err(cd, _("Only PBKDF2 is supported in FIPS mode."));
199
0
      return -EINVAL;
200
0
    }
201
0
    if (!pbkdf)
202
0
      pbkdf = crypt_get_pbkdf_type_params(CRYPT_KDF_PBKDF2);
203
0
  }
204
205
2.20k
  if (!pbkdf && dev_type && !strcmp(dev_type, CRYPT_LUKS2))
206
2.20k
    pbkdf = crypt_get_pbkdf_type_params(DEFAULT_LUKS2_PBKDF);
207
0
  else if (!pbkdf)
208
0
    pbkdf = crypt_get_pbkdf_type_params(CRYPT_KDF_PBKDF2);
209
210
2.20k
  r = verify_pbkdf_params(cd, pbkdf);
211
2.20k
  if (r)
212
0
    return r;
213
214
2.20k
  r = crypt_pbkdf_get_limits(pbkdf->type, &pbkdf_limits);
215
2.20k
  if (r < 0)
216
0
    return r;
217
218
2.20k
  type = strdup(pbkdf->type);
219
2.20k
  hash = pbkdf->hash ? strdup(pbkdf->hash) : NULL;
220
221
2.20k
  if (!type || (!hash && pbkdf->hash)) {
222
0
    free(CONST_CAST(void*)type);
223
0
    free(CONST_CAST(void*)hash);
224
0
    return -ENOMEM;
225
0
  }
226
227
2.20k
  free(CONST_CAST(void*)cd_pbkdf->type);
228
2.20k
  free(CONST_CAST(void*)cd_pbkdf->hash);
229
2.20k
  cd_pbkdf->type = type;
230
2.20k
  cd_pbkdf->hash = hash;
231
232
2.20k
  old_flags = cd_pbkdf->flags;
233
2.20k
  cd_pbkdf->flags = pbkdf->flags;
234
235
  /* Reset iteration count so benchmark must run again. */
236
2.20k
  if (cd_pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK)
237
0
    cd_pbkdf->iterations = pbkdf->iterations;
238
2.20k
  else
239
2.20k
    cd_pbkdf->iterations = 0;
240
241
2.20k
  if (old_flags & CRYPT_PBKDF_ITER_TIME_SET)
242
0
    cd_pbkdf->flags |= CRYPT_PBKDF_ITER_TIME_SET;
243
2.20k
  else
244
2.20k
    cd_pbkdf->time_ms = pbkdf->time_ms;
245
246
2.20k
  cd_pbkdf->max_memory_kb = pbkdf->max_memory_kb;
247
2.20k
  cd_pbkdf->parallel_threads = pbkdf->parallel_threads;
248
249
  /* Do not limit threads by online CPUs if user forced values (no benchmark). */
250
2.20k
  if (cd_pbkdf->parallel_threads && !(cd_pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK)) {
251
2.20k
    cpus = crypt_cpusonline();
252
2.20k
    if (cd_pbkdf->parallel_threads > cpus) {
253
0
      log_dbg(cd, "Only %u active CPUs detected, "
254
0
        "PBKDF threads decreased from %d to %d.",
255
0
        cpus, cd_pbkdf->parallel_threads, cpus);
256
0
      cd_pbkdf->parallel_threads = cpus;
257
0
    }
258
2.20k
  }
259
260
  /* Do not limit by available physical memory if user forced values (no benchmark). */
261
2.20k
  if (cd_pbkdf->max_memory_kb && !(cd_pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK)) {
262
2.20k
    memory_kb = pbkdf_adjusted_phys_memory_kb();
263
2.20k
    if (cd_pbkdf->max_memory_kb > memory_kb) {
264
0
      log_dbg(cd, "Not enough physical memory detected, "
265
0
        "PBKDF max memory decreased from %dkB to %dkB.",
266
0
        cd_pbkdf->max_memory_kb, memory_kb);
267
0
      cd_pbkdf->max_memory_kb = memory_kb;
268
0
    }
269
2.20k
  }
270
271
2.20k
  if (!strcmp(pbkdf->type, CRYPT_KDF_PBKDF2))
272
0
    log_dbg(cd, "PBKDF %s-%s, time_ms %u (iterations %u).",
273
2.20k
      cd_pbkdf->type, cd_pbkdf->hash, cd_pbkdf->time_ms, cd_pbkdf->iterations);
274
2.20k
  else
275
2.20k
    log_dbg(cd, "PBKDF %s, time_ms %u (iterations %u), max_memory_kb %u, parallel_threads %u.",
276
2.20k
      cd_pbkdf->type, cd_pbkdf->time_ms, cd_pbkdf->iterations,
277
2.20k
      cd_pbkdf->max_memory_kb, cd_pbkdf->parallel_threads);
278
279
2.20k
  return 0;
280
2.20k
}
281
282
/* Libcryptsetup API */
283
284
int crypt_set_pbkdf_type(struct crypt_device *cd, const struct crypt_pbkdf_type *pbkdf)
285
0
{
286
0
  if (!cd)
287
0
    return -EINVAL;
288
289
0
  if (!pbkdf)
290
0
    log_dbg(cd, "Resetting pbkdf type to default");
291
292
0
  crypt_get_pbkdf(cd)->flags = 0;
293
294
0
  return init_pbkdf_type(cd, pbkdf, crypt_get_type(cd));
295
0
}
296
297
const struct crypt_pbkdf_type *crypt_get_pbkdf_type(struct crypt_device *cd)
298
0
{
299
0
  if (!cd)
300
0
    return NULL;
301
302
0
  return crypt_get_pbkdf(cd)->type ? crypt_get_pbkdf(cd) : NULL;
303
0
}
304
305
const struct crypt_pbkdf_type *crypt_get_pbkdf_default(const char *type)
306
0
{
307
0
  if (!type)
308
0
    return NULL;
309
310
0
  if (!strcmp(type, CRYPT_LUKS1) || crypt_fips_mode())
311
0
    return crypt_get_pbkdf_type_params(CRYPT_KDF_PBKDF2);
312
0
  else if (!strcmp(type, CRYPT_LUKS2))
313
0
    return crypt_get_pbkdf_type_params(DEFAULT_LUKS2_PBKDF);
314
315
0
  return NULL;
316
0
}
317
318
void crypt_set_iteration_time(struct crypt_device *cd, uint64_t iteration_time_ms)
319
0
{
320
0
  struct crypt_pbkdf_type *pbkdf;
321
0
  uint32_t old_time_ms;
322
323
0
  if (!cd || iteration_time_ms > UINT32_MAX)
324
0
    return;
325
326
0
  pbkdf = crypt_get_pbkdf(cd);
327
0
  old_time_ms = pbkdf->time_ms;
328
0
  pbkdf->time_ms = (uint32_t)iteration_time_ms;
329
330
0
  if (pbkdf->type && verify_pbkdf_params(cd, pbkdf)) {
331
0
    pbkdf->time_ms = old_time_ms;
332
0
    log_dbg(cd, "Invalid iteration time.");
333
0
    return;
334
0
  }
335
336
0
  pbkdf->flags |= CRYPT_PBKDF_ITER_TIME_SET;
337
338
  /* iterations must be benchmarked now */
339
0
  pbkdf->flags &= ~(CRYPT_PBKDF_NO_BENCHMARK);
340
0
  pbkdf->iterations = 0;
341
342
0
  log_dbg(cd, "Iteration time set to %" PRIu64 " milliseconds.", iteration_time_ms);
343
0
}