Coverage Report

Created: 2026-05-30 06:06

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
#ifndef IOC_OPAL_REACTIVATE_LSP
35
36
/*
37
 * Use following ioctl parameters and ioctl numbers
38
 * from kernel sed-opal interface where the SUM extensions
39
 * are implemented. If the current kernel (headers) does not
40
 * have these extensions we can detect it runtime and turn off
41
 * the SUM support. See kernel_opal_sum_supported() below.
42
 */
43
44
struct opal_lr_react {
45
  struct opal_key key;
46
  struct opal_key new_admin_key; /* Set new Admin1 PIN if key_len is > 0 */
47
  __u8 num_lrs; /*
48
           * Configure selected ranges (from lr[]) in SUM.
49
           * If num_lrs > 0 the 'entire_table' must be 0
50
           */
51
  __u8 lr[OPAL_MAX_LRS];
52
  __u8 range_policy; /* Set RangePolicy parameter */
53
  __u8 entire_table; /* Set all locking objects in SUM */
54
  __u8 align[4]; /* Align to 8 byte boundary */
55
};
56
57
struct opal_sum_ranges {
58
  struct opal_key key;
59
  __u8 num_lrs;
60
  __u8 lr[OPAL_MAX_LRS];
61
  __u8 range_policy;
62
  __u8 align[5]; /* Align to 8 byte boundary */
63
};
64
65
#define IOC_OPAL_REACTIVATE_LSP     _IOW('p', 242, struct opal_lr_react)
66
#define IOC_OPAL_LR_SET_START_LEN   _IOW('p', 243, struct opal_user_lr_setup)
67
#define IOC_OPAL_ENABLE_DISABLE_LR  _IOW('p', 244, struct opal_user_lr_setup)
68
#define IOC_OPAL_GET_SUM_STATUS     _IOW('p', 245, struct opal_sum_ranges)
69
70
#endif
71
72
/* supported opal requirement versions */
73
#define LUKS2_OPAL_BASE_REQ_VERSION         UINT8_C(1)
74
#define LUKS2_OPAL_SUM_REQ_VERSION          UINT8_C(2) /* Device is configured with SUM */
75
76
/* Error codes are defined in the specification:
77
 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
78
 * Section 5.1.5: Method Status Codes
79
 * Names and values from table 166 */
80
typedef enum OpalStatus {
81
  OPAL_STATUS_SUCCESS = 0x00,
82
  OPAL_STATUS_NOT_AUTHORIZED = 0x01,
83
  OPAL_STATUS_OBSOLETE0 = 0x02, /* Undefined but possible return values are called 'obsolete' */
84
  OPAL_STATUS_SP_BUSY = 0x03,
85
  OPAL_STATUS_SP_FAILED = 0x04,
86
  OPAL_STATUS_SP_DISABLED = 0x05,
87
  OPAL_STATUS_SP_FROZEN = 0x06,
88
  OPAL_STATUS_NO_SESSIONS_AVAILABLE = 0x07,
89
  OPAL_STATUS_UNIQUENESS_CONFLICT = 0x08,
90
  OPAL_STATUS_INSUFFICIENT_SPACE = 0x09,
91
  OPAL_STATUS_INSUFFICIENT_ROWS = 0x0a,
92
  OPAL_STATUS_OBSOLETE1 = 0x0b, /* Undefined but possible return values are called 'obsolete' */
93
  OPAL_STATUS_INVALID_PARAMETER = 0x0c,
94
  OPAL_STATUS_OBSOLETE2 = 0x0d,
95
  OPAL_STATUS_OBSOLETE3 = 0x0e,
96
  OPAL_STATUS_TPER_MALFUNCTION = 0x0f,
97
  OPAL_STATUS_TRANSACTION_FAILURE = 0x10,
98
  OPAL_STATUS_RESPONSE_OVERFLOW = 0x11,
99
  OPAL_STATUS_AUTHORITY_LOCKED_OUT = 0x12,
100
  _OPAL_STATUS_MAX = 0x13,
101
} OpalStatus;
102
103
/*
104
 * Also defined in TCG Core spec Section 5.1.5 but
105
 * do not inflate the opal_status_table below
106
 */
107
#define  OPAL_STATUS_FAIL 0x3f
108
109
static const char* const opal_status_table[_OPAL_STATUS_MAX] = {
110
  [OPAL_STATUS_SUCCESS]               = "success",
111
  [OPAL_STATUS_NOT_AUTHORIZED]        = "not authorized",
112
  [OPAL_STATUS_OBSOLETE0]             = "obsolete (0x02)",
113
  [OPAL_STATUS_SP_BUSY]               = "SP busy",
114
  [OPAL_STATUS_SP_FAILED]             = "SP failed",
115
  [OPAL_STATUS_SP_DISABLED]           = "SP disabled",
116
  [OPAL_STATUS_SP_FROZEN]             = "SP frozen",
117
  [OPAL_STATUS_NO_SESSIONS_AVAILABLE] = "no sessions available",
118
  [OPAL_STATUS_UNIQUENESS_CONFLICT]   = "uniqueness conflict",
119
  [OPAL_STATUS_INSUFFICIENT_SPACE]    = "insufficient space",
120
  [OPAL_STATUS_INSUFFICIENT_ROWS]     = "insufficient rows",
121
  [OPAL_STATUS_OBSOLETE1]             = "obsolete (0x0b)",
122
  [OPAL_STATUS_INVALID_PARAMETER]     = "invalid parameter",
123
  [OPAL_STATUS_OBSOLETE2]             = "obsolete (0x0d)",
124
  [OPAL_STATUS_OBSOLETE3]             = "obsolete (0x0e)",
125
  [OPAL_STATUS_TPER_MALFUNCTION]      = "TPer malfunction",
126
  [OPAL_STATUS_TRANSACTION_FAILURE]   = "transaction failure",
127
  [OPAL_STATUS_RESPONSE_OVERFLOW]     = "response overflow",
128
  [OPAL_STATUS_AUTHORITY_LOCKED_OUT]  = "authority locked out",
129
};
130
131
static const char *opal_status_to_string(int t)
132
{
133
  if (t < 0)
134
    return strerror(-t);
135
136
  /* This will be checked upon 'Reactivate' method */
137
  if (t == OPAL_STATUS_FAIL)
138
    return "FAIL status";
139
140
  if (t >= _OPAL_STATUS_MAX)
141
    return "unknown error";
142
143
  return opal_status_table[t];
144
}
145
146
static const char *opal_ioctl_to_string(unsigned long rq)
147
{
148
  switch(rq) {
149
  case IOC_OPAL_DISCOVERY:       return "DISCOVERY";
150
  case IOC_OPAL_GET_STATUS:      return "GET_STATUS";
151
  case IOC_OPAL_GET_GEOMETRY:    return "GET_GEOMETRY";
152
  case IOC_OPAL_GET_LR_STATUS:   return "GET_LR_STATUS";
153
  case IOC_OPAL_TAKE_OWNERSHIP:  return "TAKE_OWNERSHIP";
154
  case IOC_OPAL_ACTIVATE_USR:    return "ACTIVATE_USR";
155
  case IOC_OPAL_ACTIVATE_LSP:    return "ACTIVATE_LSP";
156
  case IOC_OPAL_ERASE_LR:        return "ERASE_LR";
157
  case IOC_OPAL_SECURE_ERASE_LR: return "SECURE_ERASE_LR";
158
  case IOC_OPAL_ADD_USR_TO_LR:   return "ADD_USR_TO_LR";
159
  case IOC_OPAL_SET_PW:          return "SET_PW";
160
  case IOC_OPAL_LR_SETUP:        return "LR_SETUP";
161
  case IOC_OPAL_LOCK_UNLOCK:     return "LOCK_UNLOCK";
162
  case IOC_OPAL_SAVE:            return "SAVE";
163
  case IOC_OPAL_PSID_REVERT_TPR: return "PSID_REVERT_TPR";
164
  case IOC_OPAL_REACTIVATE_LSP:    return "REACTIVATE_LSP";
165
  case IOC_OPAL_LR_SET_START_LEN:  return "LR_SETUP_START_LENGTH";
166
  case IOC_OPAL_ENABLE_DISABLE_LR: return "LR_ENABLE_DISABLE";
167
  case IOC_OPAL_GET_SUM_STATUS:    return "GET_SUM_STATUS";
168
  }
169
170
  assert(false && "unknown OPAL ioctl");
171
  return NULL;
172
}
173
174
static void opal_ioctl_debug(struct crypt_device *cd,
175
            unsigned long rq,
176
            void *args,
177
            bool post,
178
            int ret)
179
{
180
  const char *cmd = opal_ioctl_to_string(rq);
181
182
  /* Discovery ioctl returns response size */
183
  if (ret < 0 || (ret && rq != IOC_OPAL_DISCOVERY)) {
184
    log_dbg(cd, "OPAL %s failed: %s", cmd, opal_status_to_string(ret));
185
    return;
186
  }
187
188
  if (post) switch(rq) {
189
  case IOC_OPAL_DISCOVERY: { /* OUT */
190
    log_dbg(cd, "OPAL %s", cmd);
191
    };
192
    break;
193
  case IOC_OPAL_GET_STATUS: { /* OUT */
194
    struct opal_status *st = args;
195
    log_dbg(cd, "OPAL %s: flags:%" PRIu32, cmd, st->flags);
196
    };
197
    break;
198
  case IOC_OPAL_GET_GEOMETRY: { /* OUT */
199
    struct opal_geometry *geo = args;
200
    log_dbg(cd, "OPAL %s: align:%" PRIu8 ", lb_size:%" PRIu32 ", gran:%" PRIu64 ", lowest_lba:%" PRIu64,
201
      cmd, geo->align, geo->logical_block_size, geo->alignment_granularity, geo->lowest_aligned_lba);
202
    };
203
    break;
204
  case IOC_OPAL_GET_LR_STATUS: { /* OUT */
205
    struct opal_lr_status *lrs = args;
206
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
207
      ", start:%" PRIu64 ", length:%" PRIu64 ", rle:%" PRIu32 ", rwe:%" PRIu32 ", state:%" PRIu32,
208
      cmd, lrs->session.sum, lrs->session.who, lrs->session.opal_key.lr,
209
      lrs->range_start, lrs->range_length, lrs->RLE, lrs->WLE, lrs->l_state);
210
    };
211
    break;
212
  case IOC_OPAL_GET_SUM_STATUS: { /* OUT */
213
    struct opal_sum_ranges *sr = args;
214
    log_dbg(cd, "OPAL %s: lr_plcy: %" PRIu8 ", num_lrs:%" PRIu8 ", lr:"
215
      "%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8,
216
      cmd, sr->range_policy, sr->num_lrs,
217
      sr->lr[0], sr->lr[1], sr->lr[2], sr->lr[3], sr->lr[4],
218
      sr->lr[5], sr->lr[6], sr->lr[7], sr->lr[8]);
219
    };
220
    break;
221
  } else switch (rq) {
222
  case IOC_OPAL_TAKE_OWNERSHIP: { /* IN */
223
    log_dbg(cd, "OPAL %s", cmd);
224
    };
225
    break;
226
  case IOC_OPAL_ACTIVATE_USR: { /* IN */
227
    struct opal_session_info *ui = args;
228
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
229
      cmd, ui->sum, ui->who, ui->opal_key.lr);
230
    };
231
    break;
232
  case IOC_OPAL_ACTIVATE_LSP: { /* IN */
233
    struct opal_lr_act *act = args;
234
    log_dbg(cd, "OPAL %s: k.lr:%" PRIu8 ", sum:%" PRIu32 ", num_lrs:%" PRIu8 ", lr:"
235
      "%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8,
236
      cmd, act->key.lr, act->sum, act->num_lrs,
237
      act->lr[0], act->lr[1], act->lr[2], act->lr[3], act->lr[4],
238
      act->lr[5], act->lr[6], act->lr[7], act->lr[8]);
239
    };
240
    break;
241
  case IOC_OPAL_ERASE_LR: { /* IN */
242
    struct opal_session_info *ui = args;
243
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
244
      cmd, ui->sum, ui->who, ui->opal_key.lr);
245
    };
246
    break;
247
  case IOC_OPAL_SECURE_ERASE_LR: { /* IN */
248
    struct opal_session_info *ui = args;
249
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
250
      cmd, ui->sum, ui->who, ui->opal_key.lr);
251
    };
252
    break;
253
  case IOC_OPAL_ADD_USR_TO_LR: { /* IN */
254
    struct opal_lock_unlock *lu = args;
255
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
256
      ", l_state:%" PRIu32 ", flags:%" PRIu16,
257
      cmd, lu->session.sum, lu->session.who, lu->session.opal_key.lr,
258
      lu->l_state, lu->flags);
259
    };
260
    break;
261
  case IOC_OPAL_SET_PW: { /* IN */
262
    struct opal_new_pw *pw = args;
263
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8,
264
      cmd, pw->session.sum, pw->session.who, pw->session.opal_key.lr);
265
    };
266
    break;
267
  case IOC_OPAL_LR_SETUP: { /* IN */
268
    struct opal_user_lr_setup *lrs = args;
269
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
270
      ", start:%" PRIu64 ", length:%" PRIu64 ", rle:%" PRIu32 ", rwe:%" PRIu32,
271
      cmd, lrs->session.sum, lrs->session.who, lrs->session.opal_key.lr,
272
      lrs->range_start, lrs->range_length, lrs->RLE, lrs->WLE);
273
    };
274
    break;
275
  case IOC_OPAL_LOCK_UNLOCK: { /* IN */
276
    struct opal_lock_unlock *lu = args;
277
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
278
      ", l_state:%" PRIu32 ", flags:%" PRIu16,
279
      cmd, lu->session.sum, lu->session.who, lu->session.opal_key.lr,
280
      lu->l_state, lu->flags);
281
    };
282
    break;
283
  case IOC_OPAL_SAVE: { /* IN */
284
    struct opal_lock_unlock *lu = args;
285
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
286
      ", l_state:%" PRIu32 ", flags:%" PRIu16,
287
      cmd, lu->session.sum, lu->session.who, lu->session.opal_key.lr,
288
      lu->l_state, lu->flags);
289
    };
290
    break;
291
  case IOC_OPAL_PSID_REVERT_TPR: { /* IN */
292
    struct opal_key *key = args;
293
    log_dbg(cd, "OPAL %s: lr:%" PRIu8,
294
      cmd, key->lr);
295
    };
296
    break;
297
  case IOC_OPAL_REACTIVATE_LSP: { /* IN */
298
    struct opal_lr_react *act = args;
299
    log_dbg(cd, "OPAL %s: new_admin_key:%" PRIu8 ", lck_table:%" PRIu8 ", lr_plcy:%" PRIu8
300
      ", num_lrs:%" PRIu8 ", lr:"
301
      "%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8"|%"PRIu8,
302
      cmd, act->new_admin_key.key_len != 0, act->entire_table, act->range_policy,
303
      act->num_lrs, act->lr[0], act->lr[1], act->lr[2], act->lr[3], act->lr[4],
304
      act->lr[5], act->lr[6], act->lr[7], act->lr[8]);
305
    };
306
    break;
307
  case IOC_OPAL_LR_SET_START_LEN: { /* IN */
308
    struct opal_user_lr_setup *lrs = args;
309
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
310
      ", start:%" PRIu64 ", length:%" PRIu64,
311
      cmd, lrs->session.sum, lrs->session.who, lrs->session.opal_key.lr,
312
      lrs->range_start, lrs->range_length);
313
    };
314
    break;
315
  case IOC_OPAL_ENABLE_DISABLE_LR: { /* IN */
316
    struct opal_user_lr_setup *lrs = args;
317
    log_dbg(cd, "OPAL %s: sum:%" PRIu32 ", who:%" PRIu32 ", lr:%" PRIu8
318
      ", rle:%" PRIu32 ", rwe:%" PRIu32,
319
      cmd, lrs->session.sum, lrs->session.who, lrs->session.opal_key.lr,
320
      lrs->RLE, lrs->WLE);
321
    };
322
    break;
323
  case IOC_OPAL_GET_SUM_STATUS: { /* IN */
324
    log_dbg(cd, "OPAL %s", cmd);
325
    };
326
    break;
327
  }
328
}
329
330
static int opal_ioctl(struct crypt_device *cd, int fd, unsigned long rq, void *args)
331
{
332
  int r;
333
334
  opal_ioctl_debug(cd, rq, args, false, 0);
335
  r = ioctl(fd, rq, args);
336
  if (r < 0)
337
    r = -errno;
338
  opal_ioctl_debug(cd, rq, args, true, r);
339
340
  return r;
341
}
342
343
static int opal_geometry_fd(struct crypt_device *cd,
344
          int fd,
345
          bool *ret_align,
346
          uint32_t *ret_block_size,
347
          uint64_t *ret_alignment_granularity_blocks,
348
          uint64_t *ret_lowest_lba_blocks)
349
{
350
  int r;
351
  struct opal_geometry geo;
352
353
  assert(fd >= 0);
354
355
  r = opal_ioctl(cd, fd, IOC_OPAL_GET_GEOMETRY, &geo);
356
  if (r != OPAL_STATUS_SUCCESS)
357
    return r;
358
359
  if (ret_align)
360
    *ret_align = (geo.align == 1);
361
  if (ret_block_size)
362
    *ret_block_size = geo.logical_block_size;
363
  if (ret_alignment_granularity_blocks)
364
    *ret_alignment_granularity_blocks = geo.alignment_granularity;
365
  if (ret_lowest_lba_blocks)
366
    *ret_lowest_lba_blocks = geo.lowest_aligned_lba;
367
368
  return r;
369
}
370
371
static int opal_range_check_attributes_fd(struct crypt_device *cd,
372
  int fd,
373
  uint32_t segment_number,
374
  const struct volume_key *vk,
375
  const uint64_t *check_offset_sectors,
376
  const uint64_t *check_length_sectors,
377
  bool *check_read_locked,
378
  bool *check_write_locked,
379
  bool *ret_read_locked,
380
  bool *ret_write_locked)
381
{
382
  int r;
383
  struct opal_lr_status *lrs;
384
  int device_block_bytes;
385
  uint32_t opal_block_bytes = 0;
386
  uint64_t offset, length;
387
  bool read_locked, write_locked;
388
389
  assert(fd >= 0);
390
  assert(cd);
391
  assert(vk);
392
  assert(check_offset_sectors);
393
  assert(check_length_sectors);
394
395
  r = opal_geometry_fd(cd, fd, NULL, &opal_block_bytes, NULL, NULL);
396
  if (r != OPAL_STATUS_SUCCESS)
397
    return -EINVAL;
398
399
  /* Keep this as warning only */
400
  if (ioctl(fd, BLKSSZGET, &device_block_bytes) < 0 ||
401
      (uint32_t)device_block_bytes != opal_block_bytes)
402
    log_err(cd, _("Bogus OPAL logical block size differs from device block size."));
403
404
  lrs = crypt_safe_alloc(sizeof(*lrs));
405
  if (!lrs)
406
    return -ENOMEM;
407
408
  *lrs = (struct opal_lr_status) {
409
    .session = {
410
      .who = segment_number + 1,
411
      .opal_key = {
412
        .key_len = crypt_volume_key_length(vk),
413
        .lr = segment_number
414
      }
415
    }
416
  };
417
  crypt_safe_memcpy(lrs->session.opal_key.key, crypt_volume_key_get_key(vk),
418
        crypt_volume_key_length(vk));
419
420
  r = opal_ioctl(cd, fd, IOC_OPAL_GET_LR_STATUS, lrs);
421
  if (r != OPAL_STATUS_SUCCESS) {
422
    log_dbg(cd, "Failed to get locking range status on device '%s'.",
423
      crypt_get_device_name(cd));
424
    r = -EINVAL;
425
    goto out;
426
  }
427
428
  r = 0;
429
430
  offset = lrs->range_start * opal_block_bytes / SECTOR_SIZE;
431
  if (offset != *check_offset_sectors) {
432
    log_err(cd, _("OPAL range %d offset %" PRIu64 " does not match expected values %" PRIu64 "."),
433
      segment_number, offset, *check_offset_sectors);
434
    r = -EINVAL;
435
  }
436
437
  length = lrs->range_length * opal_block_bytes / SECTOR_SIZE;
438
  if (length != *check_length_sectors) {
439
    log_err(cd, _("OPAL range %d length %" PRIu64" does not match device length %" PRIu64 "."),
440
      segment_number, length, *check_length_sectors);
441
    r = -EINVAL;
442
  }
443
444
  if (!lrs->RLE || !lrs->WLE) {
445
    log_err(cd, _("OPAL range %d locking is disabled."), segment_number);
446
    r = -EINVAL;
447
  }
448
449
  read_locked = (lrs->l_state == OPAL_LK);
450
  write_locked = !!(lrs->l_state & (OPAL_RO | OPAL_LK));
451
452
  if (check_read_locked && (read_locked != *check_read_locked)) {
453
    log_dbg(cd, "OPAL range %d read lock is %slocked.",
454
      segment_number, *check_read_locked ? "" : "not ");
455
    log_err(cd, _("Unexpected OPAL range %d lock state."), segment_number);
456
    r = -EINVAL;
457
  }
458
459
  if (check_write_locked && (write_locked != *check_write_locked)) {
460
    log_dbg(cd, "OPAL range %d write lock is %slocked.",
461
      segment_number, *check_write_locked ? "" : "not ");
462
    log_err(cd, _("Unexpected OPAL range %d lock state."), segment_number);
463
    r = -EINVAL;
464
  }
465
466
  if (ret_read_locked)
467
    *ret_read_locked = read_locked;
468
  if (ret_write_locked)
469
    *ret_write_locked = write_locked;
470
out:
471
  crypt_safe_free(lrs);
472
473
  return r;
474
}
475
476
static int opal_query_status_fd(struct crypt_device *cd, int fd, unsigned expected)
477
{
478
  struct opal_status st = { };
479
  int r = opal_ioctl(cd, fd, IOC_OPAL_GET_STATUS, &st);
480
481
  return r < 0 ? -EINVAL : (st.flags & expected) ? 1 : 0;
482
}
483
484
static int opal_query_status(struct crypt_device *cd, struct device *dev, unsigned expected)
485
{
486
  int fd;
487
488
  assert(cd);
489
  assert(dev);
490
491
  fd = device_open(cd, dev, O_RDONLY);
492
  if (fd < 0)
493
    return -EIO;
494
495
  return opal_query_status_fd(cd, fd, expected);
496
}
497
498
static int opal_enabled(struct crypt_device *cd, struct device *dev)
499
{
500
  return opal_query_status(cd, dev, OPAL_FL_LOCKING_ENABLED);
501
}
502
503
/* fd contains open descriptor for a device with SUM support advertised */
504
static int kernel_opal_sum_supported(struct crypt_device *cd, int fd)
505
{
506
  static int kernel_sum_supported = 0;
507
  static bool checked = false;
508
509
  int r;
510
  struct opal_sum_ranges sum_ranges_anybody = {};
511
512
  if (!checked) {
513
    /*
514
     * Check only if kernel recognizes IOC_OPAL_GET_SUM_STATUS ioctl number.
515
     * Irrelevant what OPAL2 sub-system eventually returned.
516
     */
517
    r = opal_ioctl(cd, fd, IOC_OPAL_GET_SUM_STATUS, &sum_ranges_anybody);
518
    if (r >= 0)
519
      kernel_sum_supported = 1;
520
521
    checked = true;
522
  }
523
524
  return kernel_sum_supported;
525
}
526
527
static int opal_sum_supported(struct crypt_device *cd, struct device *dev)
528
{
529
  int r, fd;
530
531
  fd = device_open(cd, dev, O_RDONLY);
532
  if (fd < 0)
533
    return -EIO;
534
535
  /* check if kernel recognizes the device as SUM capable */
536
  r = opal_query_status_fd(cd, fd, OPAL_FL_SUM_SUPPORTED);
537
  if (r < 0)
538
    return r;
539
540
  if (r) {
541
    /* device declared SUM support, now check if kernel supports necessary
542
     * ioctl numbers/structures added post original sed-opal interface */
543
    r = kernel_opal_sum_supported(cd, fd);
544
  }
545
546
  return r;
547
}
548
549
static int opal_get_sum_ranges_anybody(struct crypt_device *cd, int fd, struct opal_sum_ranges *r_sum_ranges)
550
{
551
  int r;
552
553
  assert(r_sum_ranges);
554
555
  r = opal_ioctl(cd, fd, IOC_OPAL_GET_SUM_STATUS, r_sum_ranges);
556
  if (r < 0)
557
    return -EINVAL;
558
  if (r == OPAL_STATUS_NOT_AUTHORIZED) {
559
    log_dbg(cd, "Can not read Locking table info as Anybody authority. Retry with Admin1");
560
    return -EPERM;
561
  }
562
  if (r != OPAL_STATUS_SUCCESS) {
563
    log_dbg(cd, "Failed to get SUM ranges status on OPAL device '%s': %s",
564
      crypt_get_device_name(cd), opal_status_to_string(r));
565
    return -EINVAL;
566
  }
567
568
  return 0;
569
}
570
571
static int opal_verify_sum_deactivated(struct crypt_device *cd, int fd)
572
{
573
  int r;
574
  struct opal_sum_ranges sum_ranges = {};
575
576
  r = opal_get_sum_ranges_anybody(cd, fd, &sum_ranges);
577
  if (r)
578
    return r;
579
580
  return sum_ranges.num_lrs != 0;
581
}
582
583
static int opal_verify_sum_activated(struct crypt_device *cd, int fd, bool admin_range_policy)
584
{
585
  int i, j, r;
586
  struct opal_sum_ranges sum_ranges = {};
587
588
  r = opal_get_sum_ranges_anybody(cd, fd, &sum_ranges);
589
  if (r)
590
    return r;
591
592
  if (admin_range_policy != (sum_ranges.range_policy > 0)) {
593
    log_dbg(cd, "OPAL device did not set range policy flag correctly.");
594
    return 1;
595
  }
596
597
  if (sum_ranges.num_lrs != 8) {
598
    log_dbg(cd, "OPAL device reports unexpected SUM ranges count.");
599
    return 1;
600
  }
601
602
  for (i = 1; i < 9; i++) {
603
    for (j = 0; j < sum_ranges.num_lrs; j++) {
604
      if (i == sum_ranges.lr[j])
605
        break;
606
    }
607
    if (j >= sum_ranges.num_lrs) {
608
      log_dbg(cd, "Locking range %u not set for SUM.", i);
609
      return 1;
610
    }
611
  }
612
613
  return 0;
614
}
615
616
/* Returns:
617
 *  - zero on success
618
 *  - negative errno on unrecoverable error
619
 *  - value > 0 if device did not conform with requested operation (i.e.: did not
620
 *    set range policy correctly)
621
 */
622
static int opal_sum_reactivate(struct crypt_device *cd, int fd, struct opal_lr_react *reactivate)
623
{
624
  int r;
625
626
  assert(reactivate);
627
628
  r = opal_ioctl(cd, fd, IOC_OPAL_REACTIVATE_LSP, reactivate);
629
  if (r < 0)
630
    return -EINVAL;
631
  if (r == OPAL_STATUS_FAIL)
632
    log_dbg(cd, "Failed to reactivate in SUM. There is at least one locking range enabled.");
633
  if (r != OPAL_STATUS_SUCCESS) {
634
    log_dbg(cd, "Failed to reactivate OPAL device '%s': %s",
635
      crypt_get_device_name(cd), opal_status_to_string(r));
636
    return -EINVAL;
637
  }
638
639
  if (reactivate->num_lrs) {
640
    r = opal_verify_sum_activated(cd, fd, reactivate->range_policy > 0);
641
    if (r < 0) {
642
      /*
643
       * GET_SUM_STATUS ioctl failed with unexpected error after successful
644
       * REACTIVATE invocation. There nothing we can do about it.
645
       */
646
      log_err(cd, _("The device declared support for OPAL Single User Mode (SUM) but behaved unexpectedly."));
647
      log_err(cd, _("Revert device to factory settings and try to format with --disable-sum option."));
648
    }
649
    return r;
650
  }
651
652
  return opal_verify_sum_deactivated(cd, fd);
653
}
654
655
static int opal_sum_setup(struct crypt_device *cd, int fd, const void *admin_key,
656
        size_t admin_key_len)
657
{
658
  int r;
659
  struct opal_lr_react *reactivate = crypt_safe_alloc(sizeof(*reactivate));
660
661
  if (!reactivate)
662
    return -ENOMEM;
663
664
  *reactivate = (struct opal_lr_react) {
665
    .key = {
666
      .key_len = admin_key_len,
667
    },
668
    .num_lrs = 8,
669
    .lr = { 1, 2, 3, 4, 5, 6, 7, 8 },
670
    .range_policy = 1,
671
  };
672
  crypt_safe_memcpy(reactivate->key.key, admin_key, admin_key_len);
673
674
  /*
675
   * By default we Reactivate device with SUM enabled and RangeStartLengthPolicy
676
   * flag set to 1. But some devices do not conform with SUM feature standard
677
   * and do not set attributes in accord with the request...
678
   */
679
  r = opal_sum_reactivate(cd, fd, reactivate);
680
  if (r > 0) {
681
    /* ... so, retry again with range RangeStartLengthPolicy disabled... */
682
    reactivate->range_policy = 0;
683
    r = opal_sum_reactivate(cd, fd, reactivate);
684
  }
685
  if (r > 0) {
686
    /* ... or disable SUM completely */
687
    reactivate->num_lrs = 0;
688
    memset(reactivate->lr, 0, sizeof(reactivate->lr));
689
    r = opal_sum_reactivate(cd, fd, reactivate);
690
  }
691
692
  crypt_safe_free(reactivate);
693
694
  return r > 0 ? -EINVAL : r;
695
}
696
697
static int opal_get_sum_status_anybody(struct crypt_device *cd, int fd, uint32_t segment_number,
698
               uint8_t *r_policy, uint8_t *r_segment_in_sum)
699
{
700
  int i, r;
701
  struct opal_sum_ranges sum_ranges = {};
702
703
  r = opal_get_sum_ranges_anybody(cd, fd, &sum_ranges);
704
  if (r < 0)
705
    return r;
706
707
  if (r_segment_in_sum) {
708
    *r_segment_in_sum = 0;
709
    for (i = 0; i < sum_ranges.num_lrs ; i++) {
710
      if (sum_ranges.lr[i] == segment_number) {
711
        *r_segment_in_sum = 1;
712
        break;
713
      }
714
    }
715
  }
716
717
  if (r_policy)
718
    *r_policy = sum_ranges.range_policy;
719
720
  return 0;
721
}
722
723
static int opal_sum_range_start_length(struct crypt_device *cd, int fd,
724
               struct opal_user_lr_setup *setup)
725
{
726
  int r;
727
728
  assert(setup);
729
730
  r = opal_ioctl(cd, fd, IOC_OPAL_LR_SET_START_LEN, setup);
731
  if (r < 0)
732
    return -EINVAL;
733
  if (r != OPAL_STATUS_SUCCESS) {
734
    log_dbg(cd, "Failed to setup locking range of length %llu at offset %llu on OPAL device '%s': %s",
735
      setup->range_length, setup->range_start, crypt_get_device_name(cd),
736
      opal_status_to_string(r));
737
    r = -EINVAL;
738
  }
739
740
  return r;
741
}
742
743
static int opal_sum_range_enable(struct crypt_device *cd, int fd,
744
         struct opal_user_lr_setup *setup)
745
{
746
  int r;
747
748
  assert(setup);
749
750
  r = opal_ioctl(cd, fd, IOC_OPAL_ENABLE_DISABLE_LR, setup);
751
  if (r < 0)
752
    return -EINVAL;
753
  if (r != OPAL_STATUS_SUCCESS) {
754
    log_dbg(cd, "Failed to enable locking range on OPAL device '%s': %s",
755
      crypt_get_device_name(cd), opal_status_to_string(r));
756
    r = -EINVAL;
757
  }
758
759
  return r;
760
}
761
762
static int opal_activate_lsp(struct crypt_device *cd, int fd, uint32_t sum,
763
           const void *admin_key, size_t admin_key_len,
764
           uint8_t *r_range_policy, uint8_t *r_segment_in_sum)
765
{
766
  int r;
767
  struct opal_lr_act *activate = crypt_safe_alloc(sizeof(*activate));
768
  uint8_t range_policy = 0, segment_in_sum = 0;
769
770
  assert(r_range_policy);
771
  assert(r_segment_in_sum);
772
773
  if (!activate)
774
    return -ENOMEM;
775
776
  *activate = (struct opal_lr_act) {
777
    .key = {
778
      .key_len = admin_key_len,
779
    },
780
    /* useless but due to kernel bug it requires (num_lrs > 0 && num_lrs <= 9) */
781
    .num_lrs = 1,
782
  };
783
  crypt_safe_memcpy(activate->key.key, admin_key, admin_key_len);
784
785
  r = opal_ioctl(cd, fd, IOC_OPAL_TAKE_OWNERSHIP, &activate->key);
786
  if (r < 0) {
787
    r = -ENOTSUP;
788
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
789
    goto out;
790
  }
791
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
792
    r = -EPERM;
793
    log_dbg(cd, "Failed to take ownership of OPAL device '%s': permission denied",
794
      crypt_get_device_name(cd));
795
    goto out;
796
  }
797
  if (r != OPAL_STATUS_SUCCESS) {
798
    log_dbg(cd, "Failed to take ownership of OPAL device '%s': %s",
799
      crypt_get_device_name(cd), opal_status_to_string(r));
800
    r = -EINVAL;
801
    goto out;
802
  }
803
804
  r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_LSP, activate);
805
  if (r < 0)
806
    goto out;
807
  if (r != OPAL_STATUS_SUCCESS) {
808
    log_dbg(cd, "Failed to activate OPAL device '%s': %s",
809
      crypt_get_device_name(cd), opal_status_to_string(r));
810
    r = -EINVAL;
811
    goto out;
812
  }
813
814
  /*
815
   * We can not activate LSP directly in SUM since kernel does
816
   * not support setting range policy in 'Activate' directly
817
   * in sed-opal iface.
818
   *
819
   * Some devices does not support SUM correctly. We have to
820
   * check if the device has set SUM parameters accordingly.
821
   *
822
   * If not we drop the RangePolicy flag first. If it does not
823
   * help we disable the SUM via Reactivate completely.
824
   */
825
  if (sum) {
826
    r = opal_sum_setup(cd, fd, admin_key, admin_key_len);
827
    if (!r) /* check the actual SUM state */
828
      r = opal_get_sum_status_anybody(cd, fd, 1, &range_policy, &segment_in_sum);
829
    if (r < 0)
830
      goto out;
831
  }
832
833
  *r_range_policy = range_policy;
834
  *r_segment_in_sum = segment_in_sum;
835
out:
836
  crypt_safe_free(activate);
837
838
  return r;
839
}
840
841
static int opal_reuse_active_lsp(struct crypt_device *cd, int fd, uint32_t sum,
842
         uint32_t segment_number,
843
         const void *admin_key, size_t admin_key_len,
844
         uint8_t *r_range_policy, uint8_t *r_segment_in_sum)
845
{
846
  int r;
847
  uint8_t range_policy = 0, segment_in_sum = 0;
848
  struct opal_session_info *user_session = crypt_safe_alloc(sizeof(*user_session));
849
850
  assert(r_range_policy);
851
  assert(r_segment_in_sum);
852
853
  if (!user_session)
854
    return -ENOMEM;
855
856
  *user_session = (struct opal_session_info) {
857
    .who = OPAL_ADMIN1, /* irrelevant in SUM */
858
    .opal_key = {
859
      .lr = segment_number,
860
      .key_len = admin_key_len,
861
    },
862
  };
863
864
  if (sum) {
865
    /* If device supports SUM let's get list of SUM enabled LRs */
866
    r = opal_get_sum_status_anybody(cd, fd, segment_number, &range_policy, &segment_in_sum);
867
    if (r < 0)
868
      goto out;
869
  }
870
871
  /* If it is already enabled, wipe the locking range first */
872
  crypt_safe_memcpy(user_session->opal_key.key, admin_key, admin_key_len);
873
874
  if (segment_in_sum) {
875
    /* If segment is already in SUM we need to call Erase method */
876
    r = opal_ioctl(cd, fd, IOC_OPAL_ERASE_LR, user_session);
877
    if (r > OPAL_STATUS_SUCCESS)
878
      log_dbg(cd, "Failed to erase SUM OPAL locking range %u on device '%s': %s",
879
        segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
880
  } else {
881
    r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session);
882
    if (r > OPAL_STATUS_SUCCESS)
883
      log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s",
884
        segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
885
  }
886
887
  if (r != OPAL_STATUS_SUCCESS) {
888
    r = -EINVAL;
889
    goto out;
890
  }
891
892
  *r_range_policy = range_policy;
893
  *r_segment_in_sum = segment_in_sum;
894
out:
895
  crypt_safe_free(user_session);
896
897
  return r;
898
}
899
900
static int opal_setup_range(struct crypt_device *cd, int fd, uint32_t segment_in_sum,
901
          uint32_t range_policy, uint32_t segment_number,
902
          uint64_t range_start_blocks, uint64_t range_length_blocks,
903
          const struct volume_key *user_vk, const void *admin_key,
904
          size_t admin_key_len)
905
{
906
  int r;
907
  struct opal_user_lr_setup *setup = crypt_safe_alloc(sizeof(*setup));
908
909
  if (!setup)
910
    return -ENOMEM;
911
912
  *setup = (struct opal_user_lr_setup) {
913
    .range_start = range_start_blocks,
914
    .range_length = range_length_blocks,
915
    /* Some drives do not enable Locking Ranges on setup. This have some
916
     * interesting consequences: Lock command called later below will pass,
917
     * but locking range will _not_ be locked at all.
918
     */
919
    .RLE = 1,
920
    .WLE = 1,
921
    .session = {
922
      .who = OPAL_ADMIN1,
923
      .opal_key = {
924
        .key_len = admin_key_len,
925
        .lr = segment_number,
926
      },
927
    },
928
  };
929
930
  crypt_safe_memcpy(setup->session.opal_key.key, admin_key, admin_key_len);
931
932
  /*
933
   * In SUM if PolicyRange is set to 1, Admin1 authority remains
934
   * in control of each individual locking range offset and length attributes.
935
   * But the User authority associated with the locking range is still
936
   * the sole owner of RLE, WLE and Lock/Unlock permissions. Therefore,
937
   * the Admin1 credentials are used to setup Offset and Length
938
   * only and User credentias are used for enabling RLE and WLE
939
   * fields.
940
   */
941
  if (segment_in_sum && range_policy) {
942
    r = opal_sum_range_start_length(cd, fd, setup);
943
    if (r < 0) {
944
      /*
945
       * Device advertises PolicyRange flag but does not allow Admin1 to
946
       * setup SUM locking range offset and length. It's broken.
947
       */
948
      log_err(cd, _("The device declared support for OPAL Single User Mode (SUM) but behaved unexpectedly."));
949
      log_err(cd, _("Revert device to factory settings and try to format with --disable-sum option."));
950
      goto out;
951
    }
952
  }
953
954
  if (segment_in_sum) {
955
    /* Switch to User credentials for the remaining method calls*/
956
    setup->session = (struct opal_session_info) {
957
      .sum = 1,
958
      .opal_key = {
959
        .key_len = crypt_volume_key_length(user_vk),
960
        .lr = segment_number
961
      }
962
    };
963
    crypt_safe_memcpy(setup->session.opal_key.key, crypt_volume_key_get_key(user_vk),
964
          crypt_volume_key_length(user_vk));
965
  }
966
967
  if (segment_in_sum && range_policy) {
968
    /* Enable the Locking Range in SUM */
969
    r = opal_sum_range_enable(cd, fd, setup);
970
  } else {
971
    /* Set the LR in single step since the RangePolicy flag is not set */
972
    r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup);
973
    if (r < 0)
974
      goto out;
975
    if (r != OPAL_STATUS_SUCCESS) {
976
      log_dbg(cd, "Failed to setup locking range of length %llu at offset %llu on OPAL device '%s': %s",
977
        setup->range_length, setup->range_start, crypt_get_device_name(cd),
978
        opal_status_to_string(r));
979
      r = -EINVAL;
980
    }
981
  }
982
out:
983
  crypt_safe_free(setup);
984
985
  return r;
986
}
987
988
static int opal_setup_user(struct crypt_device *cd, int fd, uint32_t segment_number,
989
         const void *admin_key, size_t admin_key_len)
990
{
991
  int r;
992
  struct opal_lock_unlock *user_add_to_lr = crypt_safe_alloc(sizeof(*user_add_to_lr));
993
994
  if (!user_add_to_lr)
995
    return -ENOMEM;
996
997
  *user_add_to_lr = (struct opal_lock_unlock) {
998
    .session = {
999
      .who = segment_number + 1,
1000
      .opal_key = {
1001
        .lr = segment_number,
1002
        .key_len = admin_key_len,
1003
      },
1004
    },
1005
    .l_state = OPAL_RO,
1006
  };
1007
1008
  crypt_safe_memcpy(user_add_to_lr->session.opal_key.key, admin_key, admin_key_len);
1009
1010
  r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_USR, &user_add_to_lr->session);
1011
  if (r < 0)
1012
    goto out;
1013
  if (r != OPAL_STATUS_SUCCESS) {
1014
    log_dbg(cd, "Failed to activate OPAL user on device '%s': %s",
1015
      crypt_get_device_name(cd), opal_status_to_string(r));
1016
    r = -EINVAL;
1017
    goto out;
1018
  }
1019
1020
  r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr);
1021
  if (r < 0)
1022
    goto out;
1023
  if (r != OPAL_STATUS_SUCCESS) {
1024
    log_dbg(cd, "Failed to add OPAL user to locking range %u (RO) on device '%s': %s",
1025
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1026
    r = -EINVAL;
1027
    goto out;
1028
  }
1029
1030
  user_add_to_lr->l_state = OPAL_RW;
1031
1032
  r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr);
1033
  if (r < 0)
1034
    goto out;
1035
  if (r != OPAL_STATUS_SUCCESS) {
1036
    log_dbg(cd, "Failed to add OPAL user to locking range %u (RW) on device '%s': %s",
1037
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1038
    r = -EINVAL;
1039
  }
1040
out:
1041
  crypt_safe_free(user_add_to_lr);
1042
1043
  return r;
1044
}
1045
1046
/* requires opal lock */
1047
int opal_setup_ranges(struct crypt_device *cd,
1048
          struct device *dev,
1049
          const struct volume_key *vk,
1050
          uint64_t range_start_blocks,
1051
          uint64_t range_length_blocks,
1052
          uint32_t opal_block_bytes,
1053
          uint32_t segment_number,
1054
          const void *admin_key,
1055
          size_t admin_key_len,
1056
          bool disable_sum,
1057
          uint8_t *r_opal_req_version)
1058
{
1059
  struct opal_lock_unlock *lock = NULL;
1060
  struct opal_new_pw *new_pw = NULL;
1061
  int r, fd;
1062
  uint8_t sum_supported, range_policy = 0, segment_in_sum = 0;
1063
1064
  assert(cd);
1065
  assert(dev);
1066
  assert(vk);
1067
  assert(admin_key);
1068
  assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
1069
  assert(opal_block_bytes >= SECTOR_SIZE);
1070
  assert(r_opal_req_version);
1071
1072
  if (admin_key_len > OPAL_KEY_MAX)
1073
    return -EINVAL;
1074
1075
  if (((UINT64_MAX / opal_block_bytes) < range_start_blocks) ||
1076
      ((UINT64_MAX / opal_block_bytes) < range_length_blocks))
1077
    return -EINVAL;
1078
1079
  fd = device_open(cd, dev, O_RDONLY);
1080
  if (fd < 0)
1081
    return -EIO;
1082
1083
  /* Not all drivers support Single User Mode, so query and adjust the setup accordingly */
1084
  r = opal_sum_supported(cd, dev);
1085
  if (r < 0)
1086
    return r;
1087
  /* sum supported */
1088
  sum_supported = !!r;
1089
1090
  r = opal_enabled(cd, dev);
1091
  if (r < 0)
1092
    return r;
1093
1094
  /* If device was already activated with SUM we do not plan to disable it */
1095
  if (r && sum_supported && disable_sum)
1096
    log_err(cd, _("Device %s already activated for HW OPAL. Flag --disable-sum ignored."),
1097
      crypt_get_device_name(cd));
1098
1099
  /* If OPAL has never been enabled, we need to take ownership and do basic setup first */
1100
  if (r == 0)
1101
    r = opal_activate_lsp(cd, fd, sum_supported && !disable_sum, admin_key, admin_key_len,
1102
              &range_policy, &segment_in_sum);
1103
  else
1104
    r = opal_reuse_active_lsp(cd, fd, sum_supported, segment_number, admin_key,
1105
            admin_key_len, &range_policy, &segment_in_sum);
1106
  if (r < 0)
1107
    goto out;
1108
1109
  /* In SUM, user is already active and properly assigned to LR */
1110
  if (!segment_in_sum) {
1111
    r = opal_setup_user(cd, fd, segment_number, admin_key, admin_key_len);
1112
    if (r < 0)
1113
      goto out;
1114
  }
1115
1116
  new_pw = crypt_safe_alloc(sizeof(struct opal_new_pw));
1117
  if (!new_pw) {
1118
    r = -ENOMEM;
1119
    goto out;
1120
  }
1121
1122
  /*
1123
   * In SUM we have to authenticate using the User authority (associated with the locking
1124
   * range) even though it was just created and it has empty passhrase (per OPAL2 SUM std.).
1125
   *
1126
   * Admin authority can not change User authority passphrase. It would defeat the purpose
1127
   * of the SUM extension.
1128
   */
1129
  *new_pw = (struct opal_new_pw) {
1130
    .session = {
1131
      .sum = segment_in_sum,
1132
      .who = segment_in_sum ? segment_number + 1 : OPAL_ADMIN1,
1133
      .opal_key = {
1134
        .lr = segment_number,
1135
        .key_len = segment_in_sum ? 0 : admin_key_len,
1136
      },
1137
    },
1138
    .new_user_pw = {
1139
      .who = segment_number + 1,
1140
      .opal_key = {
1141
        .key_len = crypt_volume_key_length(vk),
1142
        .lr = segment_number,
1143
      },
1144
    },
1145
  };
1146
  crypt_safe_memcpy(new_pw->new_user_pw.opal_key.key, crypt_volume_key_get_key(vk),
1147
        crypt_volume_key_length(vk));
1148
  if (!segment_in_sum)
1149
    crypt_safe_memcpy(new_pw->session.opal_key.key, admin_key, admin_key_len);
1150
1151
  r = opal_ioctl(cd, fd, IOC_OPAL_SET_PW, new_pw);
1152
  if (r < 0)
1153
    goto out;
1154
  if (r != OPAL_STATUS_SUCCESS) {
1155
    log_dbg(cd, "Failed to set OPAL user password on device '%s': (%d) %s",
1156
      crypt_get_device_name(cd), r, opal_status_to_string(r));
1157
    r = -EINVAL;
1158
    goto out;
1159
  }
1160
1161
  r = opal_setup_range(cd, fd, segment_in_sum, range_policy, segment_number,
1162
           range_start_blocks, range_length_blocks, vk, admin_key, admin_key_len);
1163
  if (r < 0)
1164
    goto out;
1165
1166
  /* After setup an OPAL device is unlocked, but the expectation with cryptsetup is that it needs
1167
   * to be activated separately, so lock it immediately. */
1168
  lock = crypt_safe_alloc(sizeof(struct opal_lock_unlock));
1169
  if (!lock) {
1170
    r = -ENOMEM;
1171
    goto out;
1172
  }
1173
  *lock = (struct opal_lock_unlock) {
1174
    .l_state = OPAL_LK,
1175
    .session = {
1176
      .who = segment_number + 1,
1177
      .opal_key = {
1178
        .key_len = crypt_volume_key_length(vk),
1179
        .lr = segment_number,
1180
      },
1181
    }
1182
  };
1183
  crypt_safe_memcpy(lock->session.opal_key.key, crypt_volume_key_get_key(vk),
1184
        crypt_volume_key_length(vk));
1185
1186
  r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, lock);
1187
  if (r < 0)
1188
    goto out;
1189
  if (r != OPAL_STATUS_SUCCESS) {
1190
    log_dbg(cd, "Failed to lock OPAL device '%s': %s",
1191
      crypt_get_device_name(cd), opal_status_to_string(r));
1192
    r = -EINVAL;
1193
    goto out;
1194
  }
1195
1196
  /* Double check the locking range is locked and the ranges are set up as configured */
1197
  r = opal_range_check_attributes_fd(cd, fd, segment_number, vk,
1198
             &(uint64_t) {range_start_blocks * opal_block_bytes / SECTOR_SIZE},
1199
             &(uint64_t) {range_length_blocks * opal_block_bytes / SECTOR_SIZE},
1200
             &(bool) {true}, &(bool){true}, NULL, NULL);
1201
1202
  /* Only if SUM was configured successfully add explicit SUM LUKS2 requirement flag */
1203
  *r_opal_req_version = segment_in_sum ? LUKS2_OPAL_SUM_REQ_VERSION : LUKS2_OPAL_BASE_REQ_VERSION;
1204
out:
1205
  crypt_safe_free(new_pw);
1206
  crypt_safe_free(lock);
1207
1208
  return r;
1209
}
1210
1211
static int opal_lock_unlock(struct crypt_device *cd,
1212
          struct device *dev,
1213
          uint32_t segment_number,
1214
          const struct volume_key *vk,
1215
          bool lock)
1216
{
1217
  struct opal_lock_unlock unlock = {
1218
    .l_state = lock ? OPAL_LK : OPAL_RW,
1219
    .session = {
1220
      .who = segment_number + 1,
1221
      .opal_key = {
1222
        .lr = segment_number,
1223
      },
1224
    },
1225
  };
1226
  int r, fd;
1227
1228
  if (opal_supported(cd, dev) <= 0)
1229
    return -ENOTSUP;
1230
  if (!lock && !vk)
1231
    return -EINVAL;
1232
1233
  fd = device_open(cd, dev, O_RDONLY);
1234
  if (fd < 0)
1235
    return -EIO;
1236
1237
  if (!lock) {
1238
    assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
1239
1240
    unlock.session.opal_key.key_len = crypt_volume_key_length(vk);
1241
    crypt_safe_memcpy(unlock.session.opal_key.key, crypt_volume_key_get_key(vk),
1242
          crypt_volume_key_length(vk));
1243
  }
1244
1245
  r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, &unlock);
1246
  if (r < 0) {
1247
    r = -ENOTSUP;
1248
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
1249
    goto out;
1250
  }
1251
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
1252
    r = -EPERM;
1253
    log_dbg(cd, "Failed to %slock OPAL device '%s': permission denied",
1254
      lock ? "" : "un", crypt_get_device_name(cd));
1255
    goto out;
1256
  }
1257
  if (r != OPAL_STATUS_SUCCESS) {
1258
    log_dbg(cd, "Failed to %slock OPAL device '%s': %s",
1259
      lock ? "" : "un", crypt_get_device_name(cd), opal_status_to_string(r));
1260
    r = -EINVAL;
1261
    goto out;
1262
  }
1263
1264
  /* If we are unlocking, also tell the kernel to automatically unlock when resuming
1265
   * from suspend, otherwise the drive will be locked and everything will go up in flames.
1266
   * Also set the flag to allow locking without having to pass the key again.
1267
   * But do not error out if this fails, as the device will already be unlocked.
1268
   *
1269
   * On a lock path we have to overwrite the cached key from kernel otherwise the locking range
1270
   * gets unlocked automatically after system resume even when cryptsetup previously locked it
1271
   * on purpose (crypt_deactivate* or crypt_suspend)
1272
   */
1273
  if (!lock)
1274
    unlock.flags = OPAL_SAVE_FOR_LOCK;
1275
1276
  r = opal_ioctl(cd, fd, IOC_OPAL_SAVE, &unlock);
1277
  if (r < 0)
1278
    goto out;
1279
  if (r != OPAL_STATUS_SUCCESS) {
1280
    if (!lock)
1281
      log_std(cd, "Failed to prepare OPAL device '%s' for sleep resume, be aware before suspending: %s",
1282
        crypt_get_device_name(cd), opal_status_to_string(r));
1283
    else
1284
      log_std(cd, "Failed to erase OPAL key for device '%s' from kernel: %s",
1285
        crypt_get_device_name(cd), opal_status_to_string(r));
1286
    r = 0;
1287
  }
1288
out:
1289
  if (!lock)
1290
    crypt_safe_memzero(unlock.session.opal_key.key, unlock.session.opal_key.key_len);
1291
1292
  return r;
1293
}
1294
1295
/* requires opal lock */
1296
int opal_lock(struct crypt_device *cd, struct device *dev, uint32_t segment_number)
1297
{
1298
  return opal_lock_unlock(cd, dev, segment_number, NULL, /* lock= */ true);
1299
}
1300
1301
/* requires opal lock */
1302
int opal_unlock(struct crypt_device *cd,
1303
    struct device *dev,
1304
    uint32_t segment_number,
1305
    const struct volume_key *vk)
1306
{
1307
  return opal_lock_unlock(cd, dev, segment_number, vk, /* lock= */ false);
1308
}
1309
1310
/*
1311
 * It does not require opal lock. This completely destroys
1312
 * data on whole OPAL block device. Serialization does not
1313
 * make sense here.
1314
 */
1315
int opal_factory_reset(struct crypt_device *cd,
1316
           struct device *dev,
1317
           const char *password,
1318
           size_t password_len)
1319
{
1320
  struct opal_key reset = {
1321
    .key_len = password_len,
1322
  };
1323
  int r, fd;
1324
1325
  assert(cd);
1326
  assert(dev);
1327
  assert(password);
1328
1329
  if (password_len > OPAL_KEY_MAX)
1330
    return -EINVAL;
1331
1332
  /*
1333
   * Submit PSID reset on R/W file descriptor so it
1334
   * triggers blkid rescan after we close it.
1335
   */
1336
  fd = device_open(cd, dev, O_RDWR);
1337
  if (fd < 0)
1338
    return -EIO;
1339
1340
  crypt_safe_memcpy(reset.key, password, password_len);
1341
1342
  r = opal_ioctl(cd, fd, IOC_OPAL_PSID_REVERT_TPR, &reset);
1343
  if (r < 0) {
1344
    r = -ENOTSUP;
1345
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
1346
    goto out;
1347
  }
1348
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
1349
    r = -EPERM;
1350
    log_dbg(cd, "Failed to reset OPAL device '%s', incorrect PSID?",
1351
      crypt_get_device_name(cd));
1352
    goto out;
1353
  }
1354
  if (r != OPAL_STATUS_SUCCESS) {
1355
    r = -EINVAL;
1356
    log_dbg(cd, "Failed to reset OPAL device '%s' with PSID: %s",
1357
      crypt_get_device_name(cd), opal_status_to_string(r));
1358
    goto out;
1359
  }
1360
out:
1361
  crypt_safe_memzero(reset.key, reset.key_len);
1362
1363
  return r;
1364
}
1365
1366
/* requires opal lock */
1367
int opal_reset_segment(struct crypt_device *cd,
1368
           struct device *dev,
1369
           uint32_t segment_number,
1370
           const char *password,
1371
           size_t password_len)
1372
{
1373
  int r, fd;
1374
  struct opal_session_info *user_session = NULL;
1375
  struct opal_user_lr_setup *setup = NULL;
1376
  uint32_t sum_supported;
1377
  uint8_t segment_in_sum = 0;
1378
1379
  assert(cd);
1380
  assert(dev);
1381
  assert(password);
1382
1383
  if (password_len > OPAL_KEY_MAX)
1384
    return -EINVAL;
1385
1386
  if (opal_enabled(cd, dev) <= 0)
1387
    return -EINVAL;
1388
1389
  /* Not all drivers support Single User Mode, so query and adjust the setup accordingly */
1390
  r = opal_sum_supported(cd, dev);
1391
  if (r < 0)
1392
    return r;
1393
  sum_supported = !!r;
1394
1395
  fd = device_open(cd, dev, O_RDONLY);
1396
  if (fd < 0) {
1397
    r = -EIO;
1398
    goto out;
1399
  }
1400
1401
  user_session = crypt_safe_alloc(sizeof(struct opal_session_info));
1402
  if (!user_session)
1403
    return -ENOMEM;
1404
  *user_session = (struct opal_session_info) {
1405
    .who = OPAL_ADMIN1,
1406
    .opal_key = {
1407
      .lr = segment_number,
1408
      .key_len = password_len,
1409
    },
1410
  };
1411
  crypt_safe_memcpy(user_session->opal_key.key, password, password_len);
1412
1413
  if (sum_supported) {
1414
    r = opal_get_sum_status_anybody(cd, fd, segment_number, NULL, &segment_in_sum);
1415
    if (r < 0)
1416
      goto out;
1417
  }
1418
1419
  if (segment_in_sum) {
1420
    r = opal_ioctl(cd, fd, IOC_OPAL_ERASE_LR, user_session);
1421
    if (r != OPAL_STATUS_SUCCESS) {
1422
      log_dbg(cd, "Failed to erase SUM OPAL locking range %u on device '%s': %s",
1423
        segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1424
      r = -EINVAL;
1425
    }
1426
1427
    /* Locking range in SUM is properly disabled after 'Erase' method. Exit early. */
1428
    goto out;
1429
  }
1430
1431
  r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session);
1432
  if (r < 0)
1433
    goto out;
1434
  if (r != OPAL_STATUS_SUCCESS) {
1435
    log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s",
1436
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1437
    r = -EINVAL;
1438
    goto out;
1439
  }
1440
1441
  /* Disable the locking range */
1442
  setup = crypt_safe_alloc(sizeof(struct opal_user_lr_setup));
1443
  if (!setup) {
1444
    r = -ENOMEM;
1445
    goto out;
1446
  }
1447
  *setup = (struct opal_user_lr_setup) {
1448
    .session = {
1449
      .who = OPAL_ADMIN1,
1450
      .opal_key = user_session->opal_key,
1451
    },
1452
  };
1453
1454
  r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup);
1455
  if (r < 0)
1456
    goto out;
1457
  if (r != OPAL_STATUS_SUCCESS) {
1458
    log_dbg(cd, "Failed to disable locking range on OPAL device '%s': %s",
1459
      crypt_get_device_name(cd), opal_status_to_string(r));
1460
    r = -EINVAL;
1461
    goto out;
1462
  }
1463
out:
1464
  crypt_safe_free(user_session);
1465
  crypt_safe_free(setup);
1466
1467
  return r;
1468
}
1469
1470
/*
1471
 * Does not require opal lock (immutable).
1472
 */
1473
int opal_supported(struct crypt_device *cd, struct device *dev)
1474
{
1475
  return opal_query_status(cd, dev, OPAL_FL_SUPPORTED|OPAL_FL_LOCKING_SUPPORTED);
1476
}
1477
1478
/*
1479
 * Does not require opal lock (immutable).
1480
 */
1481
int opal_geometry(struct crypt_device *cd,
1482
      struct device *dev,
1483
      bool *ret_align,
1484
      uint32_t *ret_block_size,
1485
      uint64_t *ret_alignment_granularity_blocks,
1486
      uint64_t *ret_lowest_lba_blocks)
1487
{
1488
  int fd;
1489
1490
  assert(cd);
1491
  assert(dev);
1492
1493
  fd = device_open(cd, dev, O_RDONLY);
1494
  if (fd < 0)
1495
    return -EIO;
1496
1497
  return opal_geometry_fd(cd, fd, ret_align, ret_block_size,
1498
        ret_alignment_granularity_blocks, ret_lowest_lba_blocks);
1499
}
1500
1501
/* requires opal lock */
1502
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
1503
         struct device *dev,
1504
         uint32_t segment_number,
1505
         const struct volume_key *vk,
1506
         const uint64_t *check_offset_sectors,
1507
         const uint64_t *check_length_sectors,
1508
         bool *ret_read_locked,
1509
         bool *ret_write_locked)
1510
{
1511
  int fd;
1512
1513
  assert(cd);
1514
  assert(dev);
1515
  assert(vk);
1516
1517
  fd = device_open(cd, dev, O_RDONLY);
1518
  if (fd < 0)
1519
    return -EIO;
1520
1521
  return opal_range_check_attributes_fd(cd, fd, segment_number, vk,
1522
                check_offset_sectors, check_length_sectors, NULL,
1523
                NULL, ret_read_locked, ret_write_locked);
1524
}
1525
1526
static int opal_lock_internal(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1527
{
1528
  char *lock_resource;
1529
  int devfd, r;
1530
  struct stat st;
1531
1532
  if (!crypt_metadata_locking_enabled()) {
1533
    *opal_lock = NULL;
1534
    return 0;
1535
  }
1536
1537
  /*
1538
   * This also asserts we do not hold any metadata lock on the same device to
1539
   * avoid deadlock (OPAL lock must be taken first)
1540
   */
1541
  devfd = device_open(cd, opal_device, O_RDONLY);
1542
  if (devfd < 0)
1543
    return -EINVAL;
1544
1545
  if (fstat(devfd, &st) || !S_ISBLK(st.st_mode))
1546
    return -EINVAL;
1547
1548
  r = asprintf(&lock_resource, "OPAL_%d:%d", major(st.st_rdev), minor(st.st_rdev));
1549
  if (r < 0)
1550
    return -ENOMEM;
1551
1552
  r = crypt_write_lock(cd, lock_resource, true, opal_lock);
1553
1554
  free(lock_resource);
1555
1556
  return r;
1557
}
1558
1559
int opal_exclusive_lock(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1560
{
1561
  if (!cd || !opal_device || (crypt_get_type(cd) && strcmp(crypt_get_type(cd), CRYPT_LUKS2)))
1562
    return -EINVAL;
1563
1564
  return opal_lock_internal(cd, opal_device, opal_lock);
1565
}
1566
1567
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock)
1568
{
1569
  crypt_unlock_internal(cd, opal_lock);
1570
}
1571
1572
struct level_0_discovery_header {
1573
  uint32_t length;
1574
  uint32_t revision;
1575
  uint8_t reserved[8];
1576
  uint8_t vendor_specific[32];
1577
}  __attribute__ ((packed));
1578
1579
struct level_0_discovery_feature_shared {
1580
  uint16_t feature_code;
1581
  uint8_t reserved_minor : 4;
1582
  uint8_t descriptor_version : 4;
1583
  uint8_t length;
1584
}  __attribute__ ((packed));
1585
1586
static crypt_status_hw_encryption_info opal_discovery0(struct crypt_device *cd)
1587
{
1588
  int fd;
1589
  int r, feat_length;
1590
  struct opal_discovery discovery;
1591
  struct level_0_discovery_header *dh;
1592
  struct level_0_discovery_feature_shared *feat_hdr;
1593
  char buf[4096];
1594
  const char *feature;
1595
  void *feat_ptr, *feat_end;
1596
  crypt_status_hw_encryption_info hw_enc, hw_enc_final;
1597
1598
  fd = device_open(cd, crypt_data_device(cd), O_RDONLY);
1599
  if (fd < 0)
1600
    return CRYPT_HW_INVALID;
1601
1602
  discovery.data = (uintptr_t)buf;
1603
  discovery.size = sizeof(buf);
1604
  memset(buf, 0, sizeof(buf));
1605
1606
  r = opal_ioctl(cd, fd, IOC_OPAL_DISCOVERY, &discovery);
1607
  if (r < 0)
1608
    return CRYPT_HW_INVALID;
1609
1610
  dh = (struct level_0_discovery_header *)buf;
1611
  feat_ptr = buf + sizeof(*dh);
1612
  feat_end = buf + be32_to_cpu(dh->length);
1613
1614
  hw_enc = hw_enc_final = CRYPT_HW_INVALID;
1615
  while (feat_ptr < feat_end) {
1616
    feat_hdr = feat_ptr;
1617
    /* Length defines data following the header [3.3.6 Core spec] */
1618
    feat_length = feat_hdr->length + sizeof(*feat_hdr);
1619
1620
    switch (be16_to_cpu(feat_hdr->feature_code)) {
1621
    /*   0x0000: reserved */
1622
    case 0x0001: feature = "TPer"; break;
1623
    case 0x0002: feature = "Locking"; break;
1624
    case 0x0003: feature = "Geometry"; break;
1625
    case 0x0004: feature = "Secure messaging"; break;
1626
    case 0x0005: feature = "SIIS"; break;
1627
    /*   0x00ff: reserved */
1628
    /*   0x0100 - 0x03ff: SSCs */
1629
    case 0x0100: feature = "Enterprise"; hw_enc = CRYPT_HW_OTHER; break;
1630
    case 0x0200: feature = "Opal1"; hw_enc = CRYPT_HW_OTHER; break;
1631
    case 0x0201: feature = "SUM"; hw_enc = CRYPT_HW_OPAL_SUM; break;
1632
    case 0x0202: feature = "Data store"; break;
1633
    case 0x0203: feature = "Opal2"; hw_enc = CRYPT_HW_OPAL; break;
1634
    case 0x0301: feature = "Opalite"; hw_enc = CRYPT_HW_OTHER;  break;
1635
    case 0x0302: feature = "Pyrite1"; hw_enc = CRYPT_HW_OTHER;  break;
1636
    case 0x0303: feature = "Pyrite2"; hw_enc = CRYPT_HW_OTHER;  break;
1637
    case 0x0304: feature = "Ruby"; hw_enc = CRYPT_HW_OTHER; break;
1638
    case 0x0305: feature = "KPIO"; break;
1639
    /*   0x0400 - 0xbfff reserved */
1640
    case 0x0401: feature = "Locking LBA ranges"; break;
1641
    case 0x0402: feature = "Block SID"; break;
1642
    case 0x0403: feature = "NS locking"; break;
1643
    case 0x0404: feature = "Data removal"; break;
1644
    case 0x0405: feature = "NS geometry"; break;
1645
    case 0x0407: feature = "NS Shadow MBR"; break;
1646
    case 0x0409: feature = "CPIN"; break;
1647
    case 0x040a: feature = "NS KPIO"; break;
1648
    /*   0xC000 - 0xffff vendor specific */
1649
    default: feature = "(unknown)"; break;
1650
    }
1651
1652
    log_dbg(cd, "Feature 0x%03x %s", be16_to_cpu(feat_hdr->feature_code), feature);
1653
1654
    feat_ptr = (char *)feat_ptr + feat_length;
1655
    if (hw_enc > hw_enc_final)
1656
      hw_enc_final = hw_enc;
1657
  }
1658
1659
  return hw_enc_final;
1660
}
1661
1662
crypt_status_hw_encryption_info crypt_status_hw_encryption(struct crypt_device *cd)
1663
{
1664
  int r;
1665
1666
  r = opal_discovery0(cd);
1667
  if (r > CRYPT_HW_INVALID)
1668
    return r;
1669
1670
  /* Fallback if Discovery is not available */
1671
  if (opal_supported(cd, crypt_data_device(cd)) <= 0)
1672
    return CRYPT_HW_INVALID;
1673
1674
  r = opal_sum_supported(cd, crypt_data_device(cd));
1675
  return r > 0 ? CRYPT_HW_OPAL_SUM : CRYPT_HW_OPAL;
1676
}
1677
1678
#else
1679
#pragma GCC diagnostic ignored "-Wunused-parameter"
1680
1681
int opal_setup_ranges(struct crypt_device *cd,
1682
          struct device *dev,
1683
          const struct volume_key *vk,
1684
          uint64_t range_start_blocks,
1685
          uint64_t range_length_blocks,
1686
          uint32_t opal_block_bytes,
1687
          uint32_t segment_number,
1688
          const void *admin_key,
1689
          size_t admin_key_len,
1690
          bool disable_sum,
1691
          uint8_t *r_opal_req_version)
1692
0
{
1693
0
  return -ENOTSUP;
1694
0
}
1695
1696
int opal_lock(struct crypt_device *cd, struct device *dev, uint32_t segment_number)
1697
0
{
1698
0
  return -ENOTSUP;
1699
0
}
1700
1701
int opal_unlock(struct crypt_device *cd,
1702
    struct device *dev,
1703
    uint32_t segment_number,
1704
    const struct volume_key *vk)
1705
0
{
1706
0
  return -ENOTSUP;
1707
0
}
1708
1709
int opal_supported(struct crypt_device *cd, struct device *dev)
1710
0
{
1711
0
  return -ENOTSUP;
1712
0
}
1713
1714
int opal_factory_reset(struct crypt_device *cd,
1715
           struct device *dev,
1716
           const char *password,
1717
           size_t password_len)
1718
0
{
1719
0
  return -ENOTSUP;
1720
0
}
1721
1722
int opal_reset_segment(struct crypt_device *cd,
1723
           struct device *dev,
1724
           uint32_t segment_number,
1725
           const char *password,
1726
           size_t password_len)
1727
0
{
1728
0
  return -ENOTSUP;
1729
0
}
1730
1731
int opal_geometry(struct crypt_device *cd,
1732
      struct device *dev,
1733
      bool *ret_align,
1734
      uint32_t *ret_block_size,
1735
      uint64_t *ret_alignment_granularity_blocks,
1736
      uint64_t *ret_lowest_lba_blocks)
1737
0
{
1738
0
  return -ENOTSUP;
1739
0
}
1740
1741
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
1742
         struct device *dev,
1743
         uint32_t segment_number,
1744
         const struct volume_key *vk,
1745
         const uint64_t *check_offset_sectors,
1746
         const uint64_t *check_length_sectors,
1747
         bool *ret_read_locked,
1748
         bool *ret_write_locked)
1749
0
{
1750
0
  return -ENOTSUP;
1751
0
}
1752
1753
int opal_exclusive_lock(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1754
0
{
1755
0
  return -ENOTSUP;
1756
0
}
1757
1758
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock)
1759
0
{
1760
0
}
1761
1762
crypt_status_hw_encryption_info crypt_status_hw_encryption(struct crypt_device *cd)
1763
0
{
1764
0
  return CRYPT_HW_INVALID;
1765
0
}
1766
1767
#endif