Coverage Report

Created: 2025-11-25 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptsetup/lib/luks2/hw_opal/hw_opal.c
Line
Count
Source
1
// SPDX-License-Identifier: LGPL-2.1-or-later
2
/*
3
 * OPAL utilities
4
 *
5
 * Copyright (C) 2022-2023 Luca Boccassi <bluca@debian.org>
6
 * Copyright (C) 2023-2025 Ondrej Kozina <okozina@redhat.com>
7
 * Copyright (C) 2024-2025 Milan Broz
8
 */
9
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <stdint.h>
13
#include <string.h>
14
#include <unistd.h>
15
#include <errno.h>
16
#include <assert.h>
17
#include <sys/ioctl.h>
18
#include <sys/types.h>
19
#include <sys/stat.h>
20
#if HAVE_SYS_SYSMACROS_H
21
# include <sys/sysmacros.h>     /* for major, minor */
22
#endif
23
24
#include "internal.h"
25
#include "libcryptsetup.h"
26
#include "luks2/hw_opal/hw_opal.h"
27
#include "utils_device_locking.h"
28
29
#if HAVE_HW_OPAL
30
31
#include <linux/sed-opal.h>
32
#include <linux/fs.h>
33
34
/* Error codes are defined in the specification:
35
 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
36
 * Section 5.1.5: Method Status Codes
37
 * Names and values from table 166 */
38
typedef enum OpalStatus {
39
  OPAL_STATUS_SUCCESS = 0x00,
40
  OPAL_STATUS_NOT_AUTHORIZED = 0x01,
41
  OPAL_STATUS_OBSOLETE0 = 0x02, /* Undefined but possible return values are called 'obsolete' */
42
  OPAL_STATUS_SP_BUSY = 0x03,
43
  OPAL_STATUS_SP_FAILED = 0x04,
44
  OPAL_STATUS_SP_DISABLED = 0x05,
45
  OPAL_STATUS_SP_FROZEN = 0x06,
46
  OPAL_STATUS_NO_SESSIONS_AVAILABLE = 0x07,
47
  OPAL_STATUS_UNIQUENESS_CONFLICT = 0x08,
48
  OPAL_STATUS_INSUFFICIENT_SPACE = 0x09,
49
  OPAL_STATUS_INSUFFICIENT_ROWS = 0x0a,
50
  OPAL_STATUS_OBSOLETE1 = 0x0b, /* Undefined but possible return values are called 'obsolete' */
51
  OPAL_STATUS_INVALID_PARAMETER = 0x0c,
52
  OPAL_STATUS_OBSOLETE2 = 0x0d,
53
  OPAL_STATUS_OBSOLETE3 = 0x0e,
54
  OPAL_STATUS_TPER_MALFUNCTION = 0x0f,
55
  OPAL_STATUS_TRANSACTION_FAILURE = 0x10,
56
  OPAL_STATUS_RESPONSE_OVERFLOW = 0x11,
57
  OPAL_STATUS_AUTHORITY_LOCKED_OUT = 0x12,
58
  _OPAL_STATUS_MAX = 0x13,
59
} OpalStatus;
60
61
/*
62
 * Also defined in TCG Core spec Section 5.1.5 but
63
 * do not inflate the opal_status_table below
64
 */
65
#define  OPAL_STATUS_FAIL 0x3f
66
67
static const char* const opal_status_table[_OPAL_STATUS_MAX] = {
68
  [OPAL_STATUS_SUCCESS]               = "success",
69
  [OPAL_STATUS_NOT_AUTHORIZED]        = "not authorized",
70
  [OPAL_STATUS_OBSOLETE0]             = "obsolete (0x02)",
71
  [OPAL_STATUS_SP_BUSY]               = "SP busy",
72
  [OPAL_STATUS_SP_FAILED]             = "SP failed",
73
  [OPAL_STATUS_SP_DISABLED]           = "SP disabled",
74
  [OPAL_STATUS_SP_FROZEN]             = "SP frozen",
75
  [OPAL_STATUS_NO_SESSIONS_AVAILABLE] = "no sessions available",
76
  [OPAL_STATUS_UNIQUENESS_CONFLICT]   = "uniqueness conflict",
77
  [OPAL_STATUS_INSUFFICIENT_SPACE]    = "insufficient space",
78
  [OPAL_STATUS_INSUFFICIENT_ROWS]     = "insufficient rows",
79
  [OPAL_STATUS_OBSOLETE1]             = "obsolete (0x0b)",
80
  [OPAL_STATUS_INVALID_PARAMETER]     = "invalid parameter",
81
  [OPAL_STATUS_OBSOLETE2]             = "obsolete (0x0d)",
82
  [OPAL_STATUS_OBSOLETE3]             = "obsolete (0x0e)",
83
  [OPAL_STATUS_TPER_MALFUNCTION]      = "TPer malfunction",
84
  [OPAL_STATUS_TRANSACTION_FAILURE]   = "transaction failure",
85
  [OPAL_STATUS_RESPONSE_OVERFLOW]     = "response overflow",
86
  [OPAL_STATUS_AUTHORITY_LOCKED_OUT]  = "authority locked out",
87
};
88
89
static const char *opal_status_to_string(int t)
90
{
91
  if (t < 0)
92
    return strerror(-t);
93
94
  /* This will be checked upon 'Reactivate' method */
95
  if (t == OPAL_STATUS_FAIL)
96
    return "FAIL status";
97
98
  if (t >= _OPAL_STATUS_MAX)
99
    return "unknown error";
100
101
  return opal_status_table[t];
102
}
103
104
static const char *opal_ioctl_to_string(unsigned long rq)
105
{
106
  switch(rq) {
107
  case IOC_OPAL_GET_STATUS:      return "GET_STATUS";
108
  case IOC_OPAL_GET_GEOMETRY:    return "GET_GEOMETRY";
109
  case IOC_OPAL_GET_LR_STATUS:   return "GET_LR_STATUS";
110
  case IOC_OPAL_TAKE_OWNERSHIP:  return "TAKE_OWNERSHIP";
111
  case IOC_OPAL_ACTIVATE_USR:    return "ACTIVATE_USR";
112
  case IOC_OPAL_ACTIVATE_LSP:    return "ACTIVATE_LSP";
113
  case IOC_OPAL_ERASE_LR:        return "ERASE_LR";
114
  case IOC_OPAL_SECURE_ERASE_LR: return "SECURE_ERASE_LR";
115
  case IOC_OPAL_ADD_USR_TO_LR:   return "ADD_USR_TO_LR";
116
  case IOC_OPAL_SET_PW:          return "SET_PW";
117
  case IOC_OPAL_LR_SETUP:        return "LR_SETUP";
118
  case IOC_OPAL_LOCK_UNLOCK:     return "LOCK_UNLOCK";
119
  case IOC_OPAL_SAVE:            return "SAVE";
120
  case IOC_OPAL_PSID_REVERT_TPR: return "PSID_REVERT_TPR";
121
  }
122
123
  assert(false && "unknown OPAL ioctl");
124
  return NULL;
125
}
126
127
static void opal_ioctl_debug(struct crypt_device *cd,
128
            unsigned long rq,
129
            void *args,
130
            bool post,
131
            int ret)
132
{
133
  const char *cmd = opal_ioctl_to_string(rq);
134
135
  if (ret) {
136
    log_dbg(cd, "OPAL %s failed: %s", cmd, opal_status_to_string(ret));
137
    return;
138
  }
139
140
  if (post) switch(rq) {
141
  case IOC_OPAL_GET_STATUS: { /* OUT */
142
    struct opal_status *st = args;
143
    log_dbg(cd, "OPAL %s: flags:%" PRIu32, cmd, st->flags);
144
    };
145
    break;
146
  case IOC_OPAL_GET_GEOMETRY: { /* OUT */
147
    struct opal_geometry *geo = args;
148
    log_dbg(cd, "OPAL %s: align:%" PRIu8 ", lb_size:%" PRIu32 ", gran:%" PRIu64 ", lowest_lba:%" PRIu64,
149
      cmd, geo->align, geo->logical_block_size, geo->alignment_granularity, geo->lowest_aligned_lba);
150
    };
151
    break;
152
  case IOC_OPAL_GET_LR_STATUS: { /* OUT */
153
    struct opal_lr_status *lrs = args;
154
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
155
      ", start:%" PRIu64 ", length:%" PRIu64 ", rle:%" PRIu32 ", rwe:%" PRIu32 ", state:%" PRIu32,
156
      cmd, lrs->session.sum, lrs->session.who, lrs->session.opal_key.lr,
157
      lrs->range_start, lrs->range_length, lrs->RLE, lrs->WLE, lrs->l_state);
158
    };
159
    break;
160
  } else switch (rq) {
161
  case IOC_OPAL_TAKE_OWNERSHIP: { /* IN */
162
    log_dbg(cd, "OPAL %s", cmd);
163
    };
164
    break;
165
  case IOC_OPAL_ACTIVATE_USR: { /* IN */
166
    struct opal_session_info *ui = args;
167
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
168
      cmd, ui->sum, ui->who, ui->opal_key.lr);
169
    };
170
    break;
171
  case IOC_OPAL_ACTIVATE_LSP: { /* IN */
172
    struct opal_lr_act *act = args;
173
    log_dbg(cd, "OPAL %s: k.lr:%" PRIu8 ", sum:%" PRIu32 ", num_lrs:%" PRIu8 ", lr:"
174
      "%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8,
175
      cmd, act->key.lr, act->sum, act->num_lrs,
176
      act->lr[0], act->lr[1], act->lr[2], act->lr[3], act->lr[4],
177
      act->lr[5], act->lr[6], act->lr[7], act->lr[8]);
178
    };
179
    break;
180
  case IOC_OPAL_ERASE_LR: { /* IN */
181
    struct opal_session_info *ui = args;
182
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
183
      cmd, ui->sum, ui->who, ui->opal_key.lr);
184
    };
185
    break;
186
  case IOC_OPAL_SECURE_ERASE_LR: { /* IN */
187
    struct opal_session_info *ui = args;
188
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
189
      cmd, ui->sum, ui->who, ui->opal_key.lr);
190
    };
191
    break;
192
  case IOC_OPAL_ADD_USR_TO_LR: { /* IN */
193
    struct opal_lock_unlock *lu = args;
194
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
195
      ", l_state:%" PRIu32 ", flags:%" PRIu16,
196
      cmd, lu->session.sum, lu->session.who, lu->session.opal_key.lr,
197
      lu->l_state, lu->flags);
198
    };
199
    break;
200
  case IOC_OPAL_SET_PW: { /* IN */
201
    struct opal_new_pw *pw = args;
202
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
203
      cmd, pw->session.sum, pw->session.who, pw->session.opal_key.lr);
204
    };
205
    break;
206
  case IOC_OPAL_LR_SETUP: { /* IN */
207
    struct opal_user_lr_setup *lrs = args;
208
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
209
      ", start:%" PRIu64 ", length:%" PRIu64 ", rle:%" PRIu32 ", rwe:%" PRIu32,
210
      cmd, lrs->session.sum, lrs->session.who, lrs->session.opal_key.lr,
211
      lrs->range_start, lrs->range_length, lrs->RLE, lrs->WLE);
212
    };
213
    break;
214
  case IOC_OPAL_LOCK_UNLOCK: { /* IN */
215
    struct opal_lock_unlock *lu = args;
216
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
217
      ", l_state:%" PRIu32 ", flags:%" PRIu16,
218
      cmd, lu->session.sum, lu->session.who, lu->session.opal_key.lr,
219
      lu->l_state, lu->flags);
220
    };
221
    break;
222
  case IOC_OPAL_SAVE: { /* IN */
223
    struct opal_lock_unlock *lu = args;
224
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
225
      ", l_state:%" PRIu32 ", flags:%" PRIu16,
226
      cmd, lu->session.sum, lu->session.who, lu->session.opal_key.lr,
227
      lu->l_state, lu->flags);
228
    };
229
    break;
230
  case IOC_OPAL_PSID_REVERT_TPR: { /* IN */
231
    struct opal_key *key = args;
232
    log_dbg(cd, "OPAL %s: lr:%" PRIu8,
233
      cmd, key->lr);
234
    };
235
    break;
236
  }
237
}
238
239
static int opal_ioctl(struct crypt_device *cd, int fd, unsigned long rq, void *args)
240
{
241
  int r;
242
243
  opal_ioctl_debug(cd, rq, args, false, 0);
244
  r = ioctl(fd, rq, args);
245
  if (r < 0)
246
    r = -errno;
247
  opal_ioctl_debug(cd, rq, args, true, r);
248
249
  return r;
250
}
251
252
static int opal_geometry_fd(struct crypt_device *cd,
253
          int fd,
254
          bool *ret_align,
255
          uint32_t *ret_block_size,
256
          uint64_t *ret_alignment_granularity_blocks,
257
          uint64_t *ret_lowest_lba_blocks)
258
{
259
  int r;
260
  struct opal_geometry geo;
261
262
  assert(fd >= 0);
263
264
  r = opal_ioctl(cd, fd, IOC_OPAL_GET_GEOMETRY, &geo);
265
  if (r != OPAL_STATUS_SUCCESS)
266
    return r;
267
268
  if (ret_align)
269
    *ret_align = (geo.align == 1);
270
  if (ret_block_size)
271
    *ret_block_size = geo.logical_block_size;
272
  if (ret_alignment_granularity_blocks)
273
    *ret_alignment_granularity_blocks = geo.alignment_granularity;
274
  if (ret_lowest_lba_blocks)
275
    *ret_lowest_lba_blocks = geo.lowest_aligned_lba;
276
277
  return r;
278
}
279
280
static int opal_range_check_attributes_fd(struct crypt_device *cd,
281
  int fd,
282
  uint32_t segment_number,
283
  const struct volume_key *vk,
284
  const uint64_t *check_offset_sectors,
285
  const uint64_t *check_length_sectors,
286
  bool *check_read_locked,
287
  bool *check_write_locked,
288
  bool *ret_read_locked,
289
  bool *ret_write_locked)
290
{
291
  int r;
292
  struct opal_lr_status *lrs;
293
  int device_block_bytes;
294
  uint32_t opal_block_bytes = 0;
295
  uint64_t offset, length;
296
  bool read_locked, write_locked;
297
298
  assert(fd >= 0);
299
  assert(cd);
300
  assert(vk);
301
  assert(check_offset_sectors);
302
  assert(check_length_sectors);
303
304
  r = opal_geometry_fd(cd, fd, NULL, &opal_block_bytes, NULL, NULL);
305
  if (r != OPAL_STATUS_SUCCESS)
306
    return -EINVAL;
307
308
  /* Keep this as warning only */
309
  if (ioctl(fd, BLKSSZGET, &device_block_bytes) < 0 ||
310
      (uint32_t)device_block_bytes != opal_block_bytes)
311
    log_err(cd, _("Bogus OPAL logical block size differs from device block size."));
312
313
  lrs = crypt_safe_alloc(sizeof(*lrs));
314
  if (!lrs)
315
    return -ENOMEM;
316
317
  *lrs = (struct opal_lr_status) {
318
    .session = {
319
      .who = segment_number + 1,
320
      .opal_key = {
321
        .key_len = crypt_volume_key_length(vk),
322
        .lr = segment_number
323
      }
324
    }
325
  };
326
  crypt_safe_memcpy(lrs->session.opal_key.key, crypt_volume_key_get_key(vk),
327
        crypt_volume_key_length(vk));
328
329
  r = opal_ioctl(cd, fd, IOC_OPAL_GET_LR_STATUS, lrs);
330
  if (r != OPAL_STATUS_SUCCESS) {
331
    log_dbg(cd, "Failed to get locking range status on device '%s'.",
332
      crypt_get_device_name(cd));
333
    r = -EINVAL;
334
    goto out;
335
  }
336
337
  r = 0;
338
339
  offset = lrs->range_start * opal_block_bytes / SECTOR_SIZE;
340
  if (offset != *check_offset_sectors) {
341
    log_err(cd, _("OPAL range %d offset %" PRIu64 " does not match expected values %" PRIu64 "."),
342
      segment_number, offset, *check_offset_sectors);
343
    r = -EINVAL;
344
  }
345
346
  length = lrs->range_length * opal_block_bytes / SECTOR_SIZE;
347
  if (length != *check_length_sectors) {
348
    log_err(cd, _("OPAL range %d length %" PRIu64" does not match device length %" PRIu64 "."),
349
      segment_number, length, *check_length_sectors);
350
    r = -EINVAL;
351
  }
352
353
  if (!lrs->RLE || !lrs->WLE) {
354
    log_err(cd, _("OPAL range %d locking is disabled."), segment_number);
355
    r = -EINVAL;
356
  }
357
358
  read_locked = (lrs->l_state == OPAL_LK);
359
  write_locked = !!(lrs->l_state & (OPAL_RO | OPAL_LK));
360
361
  if (check_read_locked && (read_locked != *check_read_locked)) {
362
    log_dbg(cd, "OPAL range %d read lock is %slocked.",
363
      segment_number, *check_read_locked ? "" : "not ");
364
    log_err(cd, _("Unexpected OPAL range %d lock state."), segment_number);
365
    r = -EINVAL;
366
  }
367
368
  if (check_write_locked && (write_locked != *check_write_locked)) {
369
    log_dbg(cd, "OPAL range %d write lock is %slocked.",
370
      segment_number, *check_write_locked ? "" : "not ");
371
    log_err(cd, _("Unexpected OPAL range %d lock state."), segment_number);
372
    r = -EINVAL;
373
  }
374
375
  if (ret_read_locked)
376
    *ret_read_locked = read_locked;
377
  if (ret_write_locked)
378
    *ret_write_locked = write_locked;
379
out:
380
  crypt_safe_free(lrs);
381
382
  return r;
383
}
384
385
static int opal_query_status(struct crypt_device *cd, struct device *dev, unsigned expected)
386
{
387
  struct opal_status st = { };
388
  int fd, r;
389
390
  assert(cd);
391
  assert(dev);
392
393
  fd = device_open(cd, dev, O_RDONLY);
394
  if (fd < 0)
395
    return -EIO;
396
397
  r = opal_ioctl(cd, fd, IOC_OPAL_GET_STATUS, &st);
398
399
  return r < 0 ? -EINVAL : (st.flags & expected) ? 1 : 0;
400
}
401
402
static int opal_enabled(struct crypt_device *cd, struct device *dev)
403
{
404
  return opal_query_status(cd, dev, OPAL_FL_LOCKING_ENABLED);
405
}
406
407
static int opal_activate_lsp(struct crypt_device *cd, int fd,
408
           const void *admin_key, size_t admin_key_len)
409
{
410
  int r;
411
  struct opal_lr_act *activate = crypt_safe_alloc(sizeof(*activate));
412
413
  if (!activate)
414
    return -ENOMEM;
415
416
  *activate = (struct opal_lr_act) {
417
    .key = {
418
      .key_len = admin_key_len,
419
    },
420
    /* useless but due to kernel bug it requires (num_lrs > 0 && num_lrs <= 9) */
421
    .num_lrs = 1,
422
  };
423
  crypt_safe_memcpy(activate->key.key, admin_key, admin_key_len);
424
425
  r = opal_ioctl(cd, fd, IOC_OPAL_TAKE_OWNERSHIP, &activate->key);
426
  if (r < 0) {
427
    r = -ENOTSUP;
428
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
429
    goto out;
430
  }
431
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
432
    r = -EPERM;
433
    log_dbg(cd, "Failed to take ownership of OPAL device '%s': permission denied",
434
      crypt_get_device_name(cd));
435
    goto out;
436
  }
437
  if (r != OPAL_STATUS_SUCCESS) {
438
    log_dbg(cd, "Failed to take ownership of OPAL device '%s': %s",
439
      crypt_get_device_name(cd), opal_status_to_string(r));
440
    r = -EINVAL;
441
    goto out;
442
  }
443
444
  r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_LSP, activate);
445
  if (r < 0)
446
    goto out;
447
  if (r != OPAL_STATUS_SUCCESS) {
448
    log_dbg(cd, "Failed to activate OPAL device '%s': %s",
449
      crypt_get_device_name(cd), opal_status_to_string(r));
450
    r = -EINVAL;
451
  }
452
out:
453
  crypt_safe_free(activate);
454
455
  return r;
456
}
457
458
static int opal_reuse_active_lsp(struct crypt_device *cd, int fd,
459
         uint32_t segment_number,
460
         const void *admin_key, size_t admin_key_len)
461
{
462
  int r;
463
  struct opal_session_info *user_session = crypt_safe_alloc(sizeof(*user_session));
464
465
  if (!user_session)
466
    return -ENOMEM;
467
468
  *user_session = (struct opal_session_info) {
469
    .who = OPAL_ADMIN1, /* irrelevant in SUM */
470
    .opal_key = {
471
      .lr = segment_number,
472
      .key_len = admin_key_len,
473
    },
474
  };
475
476
  /* If it is already enabled, wipe the locking range first */
477
  crypt_safe_memcpy(user_session->opal_key.key, admin_key, admin_key_len);
478
479
  r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session);
480
  if (r < 0)
481
    goto out;
482
  if (r != OPAL_STATUS_SUCCESS) {
483
    log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s",
484
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
485
    r = -EINVAL;
486
  }
487
out:
488
  crypt_safe_free(user_session);
489
490
  return r;
491
}
492
493
static int opal_setup_range(struct crypt_device *cd, int fd, uint32_t segment_number,
494
          uint64_t range_start_blocks, uint64_t range_length_blocks,
495
          const void *admin_key, size_t admin_key_len)
496
{
497
  int r;
498
  struct opal_user_lr_setup *setup = crypt_safe_alloc(sizeof(*setup));
499
500
  if (!setup)
501
    return -ENOMEM;
502
503
  *setup = (struct opal_user_lr_setup) {
504
    .range_start = range_start_blocks,
505
    .range_length = range_length_blocks,
506
    /* Some drives do not enable Locking Ranges on setup. This have some
507
     * interesting consequences: Lock command called later below will pass,
508
     * but locking range will _not_ be locked at all.
509
     */
510
    .RLE = 1,
511
    .WLE = 1,
512
    .session = {
513
      .who = OPAL_ADMIN1,
514
      .opal_key = {
515
        .key_len = admin_key_len,
516
        .lr = segment_number,
517
      },
518
    },
519
  };
520
  crypt_safe_memcpy(setup->session.opal_key.key, admin_key, admin_key_len);
521
522
  r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup);
523
  if (r < 0)
524
    goto out;
525
  if (r != OPAL_STATUS_SUCCESS) {
526
    log_dbg(cd, "Failed to setup locking range of length %llu at offset %llu on OPAL device '%s': %s",
527
      setup->range_length, setup->range_start, crypt_get_device_name(cd),
528
      opal_status_to_string(r));
529
    r = -EINVAL;
530
  }
531
out:
532
  crypt_safe_free(setup);
533
534
  return r;
535
}
536
537
static int opal_setup_user(struct crypt_device *cd, int fd, uint32_t segment_number,
538
         const void *admin_key, size_t admin_key_len)
539
{
540
  int r;
541
  struct opal_lock_unlock *user_add_to_lr = crypt_safe_alloc(sizeof(*user_add_to_lr));
542
543
  if (!user_add_to_lr)
544
    return -ENOMEM;
545
546
  *user_add_to_lr = (struct opal_lock_unlock) {
547
    .session = {
548
      .who = segment_number + 1,
549
      .opal_key = {
550
        .lr = segment_number,
551
        .key_len = admin_key_len,
552
      },
553
    },
554
    .l_state = OPAL_RO,
555
  };
556
557
  crypt_safe_memcpy(user_add_to_lr->session.opal_key.key, admin_key, admin_key_len);
558
559
  r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_USR, &user_add_to_lr->session);
560
  if (r < 0)
561
    goto out;
562
  if (r != OPAL_STATUS_SUCCESS) {
563
    log_dbg(cd, "Failed to activate OPAL user on device '%s': %s",
564
      crypt_get_device_name(cd), opal_status_to_string(r));
565
    r = -EINVAL;
566
    goto out;
567
  }
568
569
  r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr);
570
  if (r < 0)
571
    goto out;
572
  if (r != OPAL_STATUS_SUCCESS) {
573
    log_dbg(cd, "Failed to add OPAL user to locking range %u (RO) on device '%s': %s",
574
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
575
    r = -EINVAL;
576
    goto out;
577
  }
578
579
  user_add_to_lr->l_state = OPAL_RW;
580
581
  r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr);
582
  if (r < 0)
583
    goto out;
584
  if (r != OPAL_STATUS_SUCCESS) {
585
    log_dbg(cd, "Failed to add OPAL user to locking range %u (RW) on device '%s': %s",
586
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
587
    r = -EINVAL;
588
  }
589
out:
590
  crypt_safe_free(user_add_to_lr);
591
592
  return r;
593
}
594
595
/* requires opal lock */
596
int opal_setup_ranges(struct crypt_device *cd,
597
          struct device *dev,
598
          const struct volume_key *vk,
599
          uint64_t range_start_blocks,
600
          uint64_t range_length_blocks,
601
          uint32_t opal_block_bytes,
602
          uint32_t segment_number,
603
          const void *admin_key,
604
          size_t admin_key_len)
605
{
606
  struct opal_lock_unlock *lock = NULL;
607
  struct opal_new_pw *new_pw = NULL;
608
  int r, fd;
609
610
  assert(cd);
611
  assert(dev);
612
  assert(vk);
613
  assert(admin_key);
614
  assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
615
  assert(opal_block_bytes >= SECTOR_SIZE);
616
617
  if (admin_key_len > OPAL_KEY_MAX)
618
    return -EINVAL;
619
620
  if (((UINT64_MAX / opal_block_bytes) < range_start_blocks) ||
621
      ((UINT64_MAX / opal_block_bytes) < range_length_blocks))
622
    return -EINVAL;
623
624
  fd = device_open(cd, dev, O_RDONLY);
625
  if (fd < 0)
626
    return -EIO;
627
628
  r = opal_enabled(cd, dev);
629
  if (r < 0)
630
    return r;
631
632
  /* If OPAL has never been enabled, we need to take ownership and do basic setup first */
633
  if (r == 0)
634
    r = opal_activate_lsp(cd, fd, admin_key, admin_key_len);
635
  else
636
    r = opal_reuse_active_lsp(cd, fd, segment_number, admin_key, admin_key_len);
637
  if (r < 0)
638
    goto out;
639
640
  r = opal_setup_user(cd, fd, segment_number, admin_key, admin_key_len);
641
  if (r < 0)
642
    goto out;
643
644
  new_pw = crypt_safe_alloc(sizeof(struct opal_new_pw));
645
  if (!new_pw) {
646
    r = -ENOMEM;
647
    goto out;
648
  }
649
  *new_pw = (struct opal_new_pw) {
650
    .session = {
651
      .who = OPAL_ADMIN1,
652
      .opal_key = {
653
        .lr = segment_number,
654
        .key_len = admin_key_len,
655
      },
656
    },
657
    .new_user_pw = {
658
      .who = segment_number + 1,
659
      .opal_key = {
660
        .key_len = crypt_volume_key_length(vk),
661
        .lr = segment_number,
662
      },
663
    },
664
  };
665
  crypt_safe_memcpy(new_pw->new_user_pw.opal_key.key, crypt_volume_key_get_key(vk),
666
        crypt_volume_key_length(vk));
667
  crypt_safe_memcpy(new_pw->session.opal_key.key, admin_key, admin_key_len);
668
669
  r = opal_ioctl(cd, fd, IOC_OPAL_SET_PW, new_pw);
670
  if (r < 0)
671
    goto out;
672
  if (r != OPAL_STATUS_SUCCESS) {
673
    log_dbg(cd, "Failed to set OPAL user password on device '%s': (%d) %s",
674
      crypt_get_device_name(cd), r, opal_status_to_string(r));
675
    r = -EINVAL;
676
    goto out;
677
  }
678
679
  r = opal_setup_range(cd, fd, segment_number, range_start_blocks, range_length_blocks,
680
           admin_key, admin_key_len);
681
  if (r < 0)
682
    goto out;
683
684
  /* After setup an OPAL device is unlocked, but the expectation with cryptsetup is that it needs
685
   * to be activated separately, so lock it immediately. */
686
  lock = crypt_safe_alloc(sizeof(struct opal_lock_unlock));
687
  if (!lock) {
688
    r = -ENOMEM;
689
    goto out;
690
  }
691
  *lock = (struct opal_lock_unlock) {
692
    .l_state = OPAL_LK,
693
    .session = {
694
      .who = segment_number + 1,
695
      .opal_key = {
696
        .key_len = crypt_volume_key_length(vk),
697
        .lr = segment_number,
698
      },
699
    }
700
  };
701
  crypt_safe_memcpy(lock->session.opal_key.key, crypt_volume_key_get_key(vk),
702
        crypt_volume_key_length(vk));
703
704
  r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, lock);
705
  if (r < 0)
706
    goto out;
707
  if (r != OPAL_STATUS_SUCCESS) {
708
    log_dbg(cd, "Failed to lock OPAL device '%s': %s",
709
      crypt_get_device_name(cd), opal_status_to_string(r));
710
    r = -EINVAL;
711
    goto out;
712
  }
713
714
  /* Double check the locking range is locked and the ranges are set up as configured */
715
  r = opal_range_check_attributes_fd(cd, fd, segment_number, vk,
716
             &(uint64_t) {range_start_blocks * opal_block_bytes / SECTOR_SIZE},
717
             &(uint64_t) {range_length_blocks * opal_block_bytes / SECTOR_SIZE},
718
             &(bool) {true}, &(bool){true}, NULL, NULL);
719
out:
720
  crypt_safe_free(new_pw);
721
  crypt_safe_free(lock);
722
723
  return r;
724
}
725
726
static int opal_lock_unlock(struct crypt_device *cd,
727
          struct device *dev,
728
          uint32_t segment_number,
729
          const struct volume_key *vk,
730
          bool lock)
731
{
732
  struct opal_lock_unlock unlock = {
733
    .l_state = lock ? OPAL_LK : OPAL_RW,
734
    .session = {
735
      .who = segment_number + 1,
736
      .opal_key = {
737
        .lr = segment_number,
738
      },
739
    },
740
  };
741
  int r, fd;
742
743
  if (opal_supported(cd, dev) <= 0)
744
    return -ENOTSUP;
745
  if (!lock && !vk)
746
    return -EINVAL;
747
748
  fd = device_open(cd, dev, O_RDONLY);
749
  if (fd < 0)
750
    return -EIO;
751
752
  if (!lock) {
753
    assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
754
755
    unlock.session.opal_key.key_len = crypt_volume_key_length(vk);
756
    crypt_safe_memcpy(unlock.session.opal_key.key, crypt_volume_key_get_key(vk),
757
          crypt_volume_key_length(vk));
758
  }
759
760
  r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, &unlock);
761
  if (r < 0) {
762
    r = -ENOTSUP;
763
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
764
    goto out;
765
  }
766
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
767
    r = -EPERM;
768
    log_dbg(cd, "Failed to %slock OPAL device '%s': permission denied",
769
      lock ? "" : "un", crypt_get_device_name(cd));
770
    goto out;
771
  }
772
  if (r != OPAL_STATUS_SUCCESS) {
773
    log_dbg(cd, "Failed to %slock OPAL device '%s': %s",
774
      lock ? "" : "un", crypt_get_device_name(cd), opal_status_to_string(r));
775
    r = -EINVAL;
776
    goto out;
777
  }
778
779
  /* If we are unlocking, also tell the kernel to automatically unlock when resuming
780
   * from suspend, otherwise the drive will be locked and everything will go up in flames.
781
   * Also set the flag to allow locking without having to pass the key again.
782
   * But do not error out if this fails, as the device will already be unlocked.
783
   *
784
   * On a lock path we have to overwrite the cached key from kernel otherwise the locking range
785
   * gets unlocked automatically after system resume even when cryptsetup previously locked it
786
   * on purpose (crypt_deactivate* or crypt_suspend)
787
   */
788
  if (!lock)
789
    unlock.flags = OPAL_SAVE_FOR_LOCK;
790
791
  r = opal_ioctl(cd, fd, IOC_OPAL_SAVE, &unlock);
792
  if (r < 0)
793
    goto out;
794
  if (r != OPAL_STATUS_SUCCESS) {
795
    if (!lock)
796
      log_std(cd, "Failed to prepare OPAL device '%s' for sleep resume, be aware before suspending: %s",
797
        crypt_get_device_name(cd), opal_status_to_string(r));
798
    else
799
      log_std(cd, "Failed to erase OPAL key for device '%s' from kernel: %s",
800
        crypt_get_device_name(cd), opal_status_to_string(r));
801
    r = 0;
802
  }
803
out:
804
  if (!lock)
805
    crypt_safe_memzero(unlock.session.opal_key.key, unlock.session.opal_key.key_len);
806
807
  return r;
808
}
809
810
/* requires opal lock */
811
int opal_lock(struct crypt_device *cd, struct device *dev, uint32_t segment_number)
812
{
813
  return opal_lock_unlock(cd, dev, segment_number, NULL, /* lock= */ true);
814
}
815
816
/* requires opal lock */
817
int opal_unlock(struct crypt_device *cd,
818
    struct device *dev,
819
    uint32_t segment_number,
820
    const struct volume_key *vk)
821
{
822
  return opal_lock_unlock(cd, dev, segment_number, vk, /* lock= */ false);
823
}
824
825
/*
826
 * It does not require opal lock. This completely destroys
827
 * data on whole OPAL block device. Serialization does not
828
 * make sense here.
829
 */
830
int opal_factory_reset(struct crypt_device *cd,
831
           struct device *dev,
832
           const char *password,
833
           size_t password_len)
834
{
835
  struct opal_key reset = {
836
    .key_len = password_len,
837
  };
838
  int r, fd;
839
840
  assert(cd);
841
  assert(dev);
842
  assert(password);
843
844
  if (password_len > OPAL_KEY_MAX)
845
    return -EINVAL;
846
847
  /*
848
   * Submit PSID reset on R/W file descriptor so it
849
   * triggers blkid rescan after we close it.
850
   */
851
  fd = device_open(cd, dev, O_RDWR);
852
  if (fd < 0)
853
    return -EIO;
854
855
  crypt_safe_memcpy(reset.key, password, password_len);
856
857
  r = opal_ioctl(cd, fd, IOC_OPAL_PSID_REVERT_TPR, &reset);
858
  if (r < 0) {
859
    r = -ENOTSUP;
860
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
861
    goto out;
862
  }
863
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
864
    r = -EPERM;
865
    log_dbg(cd, "Failed to reset OPAL device '%s', incorrect PSID?",
866
      crypt_get_device_name(cd));
867
    goto out;
868
  }
869
  if (r != OPAL_STATUS_SUCCESS) {
870
    r = -EINVAL;
871
    log_dbg(cd, "Failed to reset OPAL device '%s' with PSID: %s",
872
      crypt_get_device_name(cd), opal_status_to_string(r));
873
    goto out;
874
  }
875
out:
876
  crypt_safe_memzero(reset.key, reset.key_len);
877
878
  return r;
879
}
880
881
/* requires opal lock */
882
int opal_reset_segment(struct crypt_device *cd,
883
           struct device *dev,
884
           uint32_t segment_number,
885
           const char *password,
886
           size_t password_len)
887
{
888
  struct opal_session_info *user_session = NULL;
889
  struct opal_user_lr_setup *setup = NULL;
890
  int r, fd;
891
892
  assert(cd);
893
  assert(dev);
894
  assert(password);
895
896
  if (password_len > OPAL_KEY_MAX)
897
    return -EINVAL;
898
899
  if (opal_enabled(cd, dev) <= 0)
900
    return -EINVAL;
901
902
  user_session = crypt_safe_alloc(sizeof(struct opal_session_info));
903
  if (!user_session)
904
    return -ENOMEM;
905
  *user_session = (struct opal_session_info) {
906
    .who = OPAL_ADMIN1,
907
    .opal_key = {
908
      .lr = segment_number,
909
      .key_len = password_len,
910
    },
911
  };
912
  crypt_safe_memcpy(user_session->opal_key.key, password, password_len);
913
914
  fd = device_open(cd, dev, O_RDONLY);
915
  if (fd < 0) {
916
    r = -EIO;
917
    goto out;
918
  }
919
920
  r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session);
921
  if (r < 0)
922
    goto out;
923
  if (r != OPAL_STATUS_SUCCESS) {
924
    log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s",
925
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
926
    r = -EINVAL;
927
    goto out;
928
  }
929
930
  /* Disable the locking range */
931
  setup = crypt_safe_alloc(sizeof(struct opal_user_lr_setup));
932
  if (!setup) {
933
    r = -ENOMEM;
934
    goto out;
935
  }
936
  *setup = (struct opal_user_lr_setup) {
937
    .range_start = 0,
938
    .range_length = 0,
939
    .session = {
940
      .who = OPAL_ADMIN1,
941
      .opal_key = user_session->opal_key,
942
    },
943
  };
944
945
  r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup);
946
  if (r < 0)
947
    goto out;
948
  if (r != OPAL_STATUS_SUCCESS) {
949
    log_dbg(cd, "Failed to disable locking range on OPAL device '%s': %s",
950
      crypt_get_device_name(cd), opal_status_to_string(r));
951
    r = -EINVAL;
952
    goto out;
953
  }
954
out:
955
  crypt_safe_free(user_session);
956
  crypt_safe_free(setup);
957
958
  return r;
959
}
960
961
/*
962
 * Does not require opal lock (immutable).
963
 */
964
int opal_supported(struct crypt_device *cd, struct device *dev)
965
{
966
  return opal_query_status(cd, dev, OPAL_FL_SUPPORTED|OPAL_FL_LOCKING_SUPPORTED);
967
}
968
969
/*
970
 * Does not require opal lock (immutable).
971
 */
972
int opal_geometry(struct crypt_device *cd,
973
      struct device *dev,
974
      bool *ret_align,
975
      uint32_t *ret_block_size,
976
      uint64_t *ret_alignment_granularity_blocks,
977
      uint64_t *ret_lowest_lba_blocks)
978
{
979
  int fd;
980
981
  assert(cd);
982
  assert(dev);
983
984
  fd = device_open(cd, dev, O_RDONLY);
985
  if (fd < 0)
986
    return -EIO;
987
988
  return opal_geometry_fd(cd, fd, ret_align, ret_block_size,
989
        ret_alignment_granularity_blocks, ret_lowest_lba_blocks);
990
}
991
992
/* requires opal lock */
993
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
994
         struct device *dev,
995
         uint32_t segment_number,
996
         const struct volume_key *vk,
997
         const uint64_t *check_offset_sectors,
998
         const uint64_t *check_length_sectors,
999
         bool *ret_read_locked,
1000
         bool *ret_write_locked)
1001
{
1002
  int fd;
1003
1004
  assert(cd);
1005
  assert(dev);
1006
  assert(vk);
1007
1008
  fd = device_open(cd, dev, O_RDONLY);
1009
  if (fd < 0)
1010
    return -EIO;
1011
1012
  return opal_range_check_attributes_fd(cd, fd, segment_number, vk,
1013
                check_offset_sectors, check_length_sectors, NULL,
1014
                NULL, ret_read_locked, ret_write_locked);
1015
}
1016
1017
static int opal_lock_internal(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1018
{
1019
  char *lock_resource;
1020
  int devfd, r;
1021
  struct stat st;
1022
1023
  if (!crypt_metadata_locking_enabled()) {
1024
    *opal_lock = NULL;
1025
    return 0;
1026
  }
1027
1028
  /*
1029
   * This also asserts we do not hold any metadata lock on the same device to
1030
   * avoid deadlock (OPAL lock must be taken first)
1031
   */
1032
  devfd = device_open(cd, opal_device, O_RDONLY);
1033
  if (devfd < 0)
1034
    return -EINVAL;
1035
1036
  if (fstat(devfd, &st) || !S_ISBLK(st.st_mode))
1037
    return -EINVAL;
1038
1039
  r = asprintf(&lock_resource, "OPAL_%d:%d", major(st.st_rdev), minor(st.st_rdev));
1040
  if (r < 0)
1041
    return -ENOMEM;
1042
1043
  r = crypt_write_lock(cd, lock_resource, true, opal_lock);
1044
1045
  free(lock_resource);
1046
1047
  return r;
1048
}
1049
1050
int opal_exclusive_lock(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1051
{
1052
  if (!cd || !opal_device || (crypt_get_type(cd) && strcmp(crypt_get_type(cd), CRYPT_LUKS2)))
1053
    return -EINVAL;
1054
1055
  return opal_lock_internal(cd, opal_device, opal_lock);
1056
}
1057
1058
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock)
1059
{
1060
  crypt_unlock_internal(cd, opal_lock);
1061
}
1062
1063
#else
1064
#pragma GCC diagnostic ignored "-Wunused-parameter"
1065
1066
int opal_setup_ranges(struct crypt_device *cd,
1067
          struct device *dev,
1068
          const struct volume_key *vk,
1069
          uint64_t range_start_blocks,
1070
          uint64_t range_length_blocks,
1071
          uint32_t opal_block_bytes,
1072
          uint32_t segment_number,
1073
          const void *admin_key,
1074
          size_t admin_key_len)
1075
0
{
1076
0
  return -ENOTSUP;
1077
0
}
1078
1079
int opal_lock(struct crypt_device *cd, struct device *dev, uint32_t segment_number)
1080
0
{
1081
0
  return -ENOTSUP;
1082
0
}
1083
1084
int opal_unlock(struct crypt_device *cd,
1085
    struct device *dev,
1086
    uint32_t segment_number,
1087
    const struct volume_key *vk)
1088
0
{
1089
0
  return -ENOTSUP;
1090
0
}
1091
1092
int opal_supported(struct crypt_device *cd, struct device *dev)
1093
0
{
1094
0
  return -ENOTSUP;
1095
0
}
1096
1097
int opal_factory_reset(struct crypt_device *cd,
1098
           struct device *dev,
1099
           const char *password,
1100
           size_t password_len)
1101
0
{
1102
0
  return -ENOTSUP;
1103
0
}
1104
1105
int opal_reset_segment(struct crypt_device *cd,
1106
           struct device *dev,
1107
           uint32_t segment_number,
1108
           const char *password,
1109
           size_t password_len)
1110
0
{
1111
0
  return -ENOTSUP;
1112
0
}
1113
1114
int opal_geometry(struct crypt_device *cd,
1115
      struct device *dev,
1116
      bool *ret_align,
1117
      uint32_t *ret_block_size,
1118
      uint64_t *ret_alignment_granularity_blocks,
1119
      uint64_t *ret_lowest_lba_blocks)
1120
0
{
1121
0
  return -ENOTSUP;
1122
0
}
1123
1124
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
1125
         struct device *dev,
1126
         uint32_t segment_number,
1127
         const struct volume_key *vk,
1128
         const uint64_t *check_offset_sectors,
1129
         const uint64_t *check_length_sectors,
1130
         bool *ret_read_locked,
1131
         bool *ret_write_locked)
1132
0
{
1133
0
  return -ENOTSUP;
1134
0
}
1135
1136
int opal_exclusive_lock(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1137
0
{
1138
0
  return -ENOTSUP;
1139
0
}
1140
1141
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock)
1142
0
{
1143
0
}
1144
1145
#endif