Coverage Report

Created: 2026-10-28 07:07

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-2026 Ondrej Kozina <okozina@redhat.com>
7
 * Copyright (C) 2024-2026 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 crypt_hw_opal_feature_state opal_segment_in_sum(uint32_t segment_number, const struct opal_sum_ranges *sranges)
698
{
699
  int i;
700
701
  assert(sranges);
702
703
  for (i = 0; i < sranges->num_lrs ; i++) {
704
    if (sranges->lr[i] == segment_number)
705
      return CRYPT_HW_OPAL_FEATURE_ENABLED;
706
  }
707
708
  return CRYPT_HW_OPAL_FEATURE_DISABLED;
709
}
710
711
static int opal_get_sum_status_anybody(struct crypt_device *cd, int fd, uint32_t segment_number,
712
               uint8_t *r_policy, uint8_t *r_segment_in_sum)
713
{
714
  int r;
715
  struct opal_sum_ranges sum_ranges = {};
716
717
  r = opal_get_sum_ranges_anybody(cd, fd, &sum_ranges);
718
  if (r < 0)
719
    return r;
720
721
  if (r_segment_in_sum)
722
    *r_segment_in_sum = opal_segment_in_sum(segment_number, &sum_ranges);
723
724
  if (r_policy)
725
    *r_policy = sum_ranges.range_policy;
726
727
  return 0;
728
}
729
730
static int opal_sum_range_start_length(struct crypt_device *cd, int fd,
731
               struct opal_user_lr_setup *setup)
732
{
733
  int r;
734
735
  assert(setup);
736
737
  r = opal_ioctl(cd, fd, IOC_OPAL_LR_SET_START_LEN, setup);
738
  if (r < 0)
739
    return -EINVAL;
740
  if (r != OPAL_STATUS_SUCCESS) {
741
    log_dbg(cd, "Failed to setup locking range of length %llu at offset %llu on OPAL device '%s': %s",
742
      setup->range_length, setup->range_start, crypt_get_device_name(cd),
743
      opal_status_to_string(r));
744
    r = -EINVAL;
745
  }
746
747
  return r;
748
}
749
750
static int opal_sum_range_enable(struct crypt_device *cd, int fd,
751
         struct opal_user_lr_setup *setup)
752
{
753
  int r;
754
755
  assert(setup);
756
757
  r = opal_ioctl(cd, fd, IOC_OPAL_ENABLE_DISABLE_LR, setup);
758
  if (r < 0)
759
    return -EINVAL;
760
  if (r != OPAL_STATUS_SUCCESS) {
761
    log_dbg(cd, "Failed to enable locking range on OPAL device '%s': %s",
762
      crypt_get_device_name(cd), opal_status_to_string(r));
763
    r = -EINVAL;
764
  }
765
766
  return r;
767
}
768
769
static int opal_activate_lsp(struct crypt_device *cd, int fd, uint32_t sum,
770
           const void *admin_key, size_t admin_key_len,
771
           uint8_t *r_range_policy, uint8_t *r_segment_in_sum)
772
{
773
  int r;
774
  struct opal_lr_act *activate = crypt_safe_alloc(sizeof(*activate));
775
  uint8_t range_policy = 0, segment_in_sum = 0;
776
777
  assert(r_range_policy);
778
  assert(r_segment_in_sum);
779
780
  if (!activate)
781
    return -ENOMEM;
782
783
  *activate = (struct opal_lr_act) {
784
    .key = {
785
      .key_len = admin_key_len,
786
    },
787
    /* useless but due to kernel bug it requires (num_lrs > 0 && num_lrs <= 9) */
788
    .num_lrs = 1,
789
  };
790
  crypt_safe_memcpy(activate->key.key, admin_key, admin_key_len);
791
792
  r = opal_ioctl(cd, fd, IOC_OPAL_TAKE_OWNERSHIP, &activate->key);
793
  if (r < 0) {
794
    r = -ENOTSUP;
795
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
796
    goto out;
797
  }
798
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
799
    r = -EPERM;
800
    log_dbg(cd, "Failed to take ownership of OPAL device '%s': permission denied",
801
      crypt_get_device_name(cd));
802
    goto out;
803
  }
804
  if (r != OPAL_STATUS_SUCCESS) {
805
    log_dbg(cd, "Failed to take ownership of OPAL device '%s': %s",
806
      crypt_get_device_name(cd), opal_status_to_string(r));
807
    r = -EINVAL;
808
    goto out;
809
  }
810
811
  r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_LSP, activate);
812
  if (r < 0)
813
    goto out;
814
  if (r != OPAL_STATUS_SUCCESS) {
815
    log_dbg(cd, "Failed to activate OPAL device '%s': %s",
816
      crypt_get_device_name(cd), opal_status_to_string(r));
817
    r = -EINVAL;
818
    goto out;
819
  }
820
821
  /*
822
   * We can not activate LSP directly in SUM since kernel does
823
   * not support setting range policy in 'Activate' directly
824
   * in sed-opal iface.
825
   *
826
   * Some devices does not support SUM correctly. We have to
827
   * check if the device has set SUM parameters accordingly.
828
   *
829
   * If not we drop the RangePolicy flag first. If it does not
830
   * help we disable the SUM via Reactivate completely.
831
   */
832
  if (sum) {
833
    r = opal_sum_setup(cd, fd, admin_key, admin_key_len);
834
    if (!r) /* check the actual SUM state */
835
      r = opal_get_sum_status_anybody(cd, fd, 1, &range_policy, &segment_in_sum);
836
    if (r < 0)
837
      goto out;
838
  }
839
840
  *r_range_policy = range_policy;
841
  *r_segment_in_sum = segment_in_sum;
842
out:
843
  crypt_safe_free(activate);
844
845
  return r;
846
}
847
848
static int opal_reuse_active_lsp(struct crypt_device *cd, int fd, uint32_t sum,
849
         uint32_t segment_number,
850
         const void *admin_key, size_t admin_key_len,
851
         uint8_t *r_range_policy, uint8_t *r_segment_in_sum)
852
{
853
  int r;
854
  uint8_t range_policy = 0, segment_in_sum = 0;
855
  struct opal_session_info *user_session = crypt_safe_alloc(sizeof(*user_session));
856
857
  assert(r_range_policy);
858
  assert(r_segment_in_sum);
859
860
  if (!user_session)
861
    return -ENOMEM;
862
863
  *user_session = (struct opal_session_info) {
864
    .who = OPAL_ADMIN1, /* irrelevant in SUM */
865
    .opal_key = {
866
      .lr = segment_number,
867
      .key_len = admin_key_len,
868
    },
869
  };
870
871
  if (sum) {
872
    /* If device supports SUM let's get list of SUM enabled LRs */
873
    r = opal_get_sum_status_anybody(cd, fd, segment_number, &range_policy, &segment_in_sum);
874
    if (r < 0)
875
      goto out;
876
  }
877
878
  /* If it is already enabled, wipe the locking range first */
879
  crypt_safe_memcpy(user_session->opal_key.key, admin_key, admin_key_len);
880
881
  if (segment_in_sum) {
882
    /* If segment is already in SUM we need to call Erase method */
883
    r = opal_ioctl(cd, fd, IOC_OPAL_ERASE_LR, user_session);
884
    if (r > OPAL_STATUS_SUCCESS)
885
      log_dbg(cd, "Failed to erase SUM OPAL locking range %u on device '%s': %s",
886
        segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
887
  } else {
888
    r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session);
889
    if (r > OPAL_STATUS_SUCCESS)
890
      log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s",
891
        segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
892
  }
893
894
  if (r != OPAL_STATUS_SUCCESS) {
895
    r = -EINVAL;
896
    goto out;
897
  }
898
899
  *r_range_policy = range_policy;
900
  *r_segment_in_sum = segment_in_sum;
901
out:
902
  crypt_safe_free(user_session);
903
904
  return r;
905
}
906
907
static int opal_setup_range(struct crypt_device *cd, int fd, uint32_t segment_in_sum,
908
          uint32_t range_policy, uint32_t segment_number,
909
          uint64_t range_start_blocks, uint64_t range_length_blocks,
910
          const struct volume_key *user_vk, const void *admin_key,
911
          size_t admin_key_len)
912
{
913
  int r;
914
  struct opal_user_lr_setup *setup = crypt_safe_alloc(sizeof(*setup));
915
916
  if (!setup)
917
    return -ENOMEM;
918
919
  *setup = (struct opal_user_lr_setup) {
920
    .range_start = range_start_blocks,
921
    .range_length = range_length_blocks,
922
    /* Some drives do not enable Locking Ranges on setup. This have some
923
     * interesting consequences: Lock command called later below will pass,
924
     * but locking range will _not_ be locked at all.
925
     */
926
    .RLE = 1,
927
    .WLE = 1,
928
    .session = {
929
      .who = OPAL_ADMIN1,
930
      .opal_key = {
931
        .key_len = admin_key_len,
932
        .lr = segment_number,
933
      },
934
    },
935
  };
936
937
  crypt_safe_memcpy(setup->session.opal_key.key, admin_key, admin_key_len);
938
939
  /*
940
   * In SUM if PolicyRange is set to 1, Admin1 authority remains
941
   * in control of each individual locking range offset and length attributes.
942
   * But the User authority associated with the locking range is still
943
   * the sole owner of RLE, WLE and Lock/Unlock permissions. Therefore,
944
   * the Admin1 credentials are used to setup Offset and Length
945
   * only and User credentias are used for enabling RLE and WLE
946
   * fields.
947
   */
948
  if (segment_in_sum && range_policy) {
949
    r = opal_sum_range_start_length(cd, fd, setup);
950
    if (r < 0) {
951
      /*
952
       * Device advertises PolicyRange flag but does not allow Admin1 to
953
       * setup SUM locking range offset and length. It's broken.
954
       */
955
      log_err(cd, _("The device declared support for OPAL Single User Mode (SUM) but behaved unexpectedly."));
956
      log_err(cd, _("Revert device to factory settings and try to format with --disable-sum option."));
957
      goto out;
958
    }
959
  }
960
961
  if (segment_in_sum) {
962
    /* Switch to User credentials for the remaining method calls*/
963
    setup->session = (struct opal_session_info) {
964
      .sum = 1,
965
      .opal_key = {
966
        .key_len = crypt_volume_key_length(user_vk),
967
        .lr = segment_number
968
      }
969
    };
970
    crypt_safe_memcpy(setup->session.opal_key.key, crypt_volume_key_get_key(user_vk),
971
          crypt_volume_key_length(user_vk));
972
  }
973
974
  if (segment_in_sum && range_policy) {
975
    /* Enable the Locking Range in SUM */
976
    r = opal_sum_range_enable(cd, fd, setup);
977
  } else {
978
    /* Set the LR in single step since the RangePolicy flag is not set */
979
    r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup);
980
    if (r < 0)
981
      goto out;
982
    if (r != OPAL_STATUS_SUCCESS) {
983
      log_dbg(cd, "Failed to setup locking range of length %llu at offset %llu on OPAL device '%s': %s",
984
        setup->range_length, setup->range_start, crypt_get_device_name(cd),
985
        opal_status_to_string(r));
986
      r = -EINVAL;
987
    }
988
  }
989
out:
990
  crypt_safe_free(setup);
991
992
  return r;
993
}
994
995
static int opal_setup_user(struct crypt_device *cd, int fd, uint32_t segment_number,
996
         const void *admin_key, size_t admin_key_len)
997
{
998
  int r;
999
  struct opal_lock_unlock *user_add_to_lr = crypt_safe_alloc(sizeof(*user_add_to_lr));
1000
1001
  if (!user_add_to_lr)
1002
    return -ENOMEM;
1003
1004
  *user_add_to_lr = (struct opal_lock_unlock) {
1005
    .session = {
1006
      .who = segment_number + 1,
1007
      .opal_key = {
1008
        .lr = segment_number,
1009
        .key_len = admin_key_len,
1010
      },
1011
    },
1012
    .l_state = OPAL_RO,
1013
  };
1014
1015
  crypt_safe_memcpy(user_add_to_lr->session.opal_key.key, admin_key, admin_key_len);
1016
1017
  r = opal_ioctl(cd, fd, IOC_OPAL_ACTIVATE_USR, &user_add_to_lr->session);
1018
  if (r < 0)
1019
    goto out;
1020
  if (r != OPAL_STATUS_SUCCESS) {
1021
    log_dbg(cd, "Failed to activate OPAL user on device '%s': %s",
1022
      crypt_get_device_name(cd), opal_status_to_string(r));
1023
    r = -EINVAL;
1024
    goto out;
1025
  }
1026
1027
  r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr);
1028
  if (r < 0)
1029
    goto out;
1030
  if (r != OPAL_STATUS_SUCCESS) {
1031
    log_dbg(cd, "Failed to add OPAL user to locking range %u (RO) on device '%s': %s",
1032
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1033
    r = -EINVAL;
1034
    goto out;
1035
  }
1036
1037
  user_add_to_lr->l_state = OPAL_RW;
1038
1039
  r = opal_ioctl(cd, fd, IOC_OPAL_ADD_USR_TO_LR, user_add_to_lr);
1040
  if (r < 0)
1041
    goto out;
1042
  if (r != OPAL_STATUS_SUCCESS) {
1043
    log_dbg(cd, "Failed to add OPAL user to locking range %u (RW) on device '%s': %s",
1044
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1045
    r = -EINVAL;
1046
  }
1047
out:
1048
  crypt_safe_free(user_add_to_lr);
1049
1050
  return r;
1051
}
1052
1053
/* requires opal lock */
1054
int opal_setup_ranges(struct crypt_device *cd,
1055
          struct device *dev,
1056
          const struct volume_key *vk,
1057
          uint64_t range_start_blocks,
1058
          uint64_t range_length_blocks,
1059
          uint32_t opal_block_bytes,
1060
          uint32_t segment_number,
1061
          const void *admin_key,
1062
          size_t admin_key_len,
1063
          bool disable_sum,
1064
          uint8_t *r_opal_req_version)
1065
{
1066
  struct opal_lock_unlock *lock = NULL;
1067
  struct opal_new_pw *new_pw = NULL;
1068
  int r, fd;
1069
  uint8_t sum_supported, range_policy = 0, segment_in_sum = 0;
1070
1071
  assert(cd);
1072
  assert(dev);
1073
  assert(vk);
1074
  assert(admin_key);
1075
  assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
1076
  assert(opal_block_bytes >= SECTOR_SIZE);
1077
  assert(r_opal_req_version);
1078
1079
  if (admin_key_len > OPAL_KEY_MAX)
1080
    return -EINVAL;
1081
1082
  if (((UINT64_MAX / opal_block_bytes) < range_start_blocks) ||
1083
      ((UINT64_MAX / opal_block_bytes) < range_length_blocks))
1084
    return -EINVAL;
1085
1086
  fd = device_open(cd, dev, O_RDONLY);
1087
  if (fd < 0)
1088
    return -EIO;
1089
1090
  /* Not all drivers support Single User Mode, so query and adjust the setup accordingly */
1091
  r = opal_sum_supported(cd, dev);
1092
  if (r < 0)
1093
    return r;
1094
  /* sum supported */
1095
  sum_supported = !!r;
1096
1097
  r = opal_enabled(cd, dev);
1098
  if (r < 0)
1099
    return r;
1100
1101
  /* If device was already activated with SUM we do not plan to disable it */
1102
  if (r && sum_supported && disable_sum)
1103
    log_err(cd, _("Device %s already activated for HW OPAL. Flag --disable-sum ignored."),
1104
      crypt_get_device_name(cd));
1105
1106
  /* If OPAL has never been enabled, we need to take ownership and do basic setup first */
1107
  if (r == 0)
1108
    r = opal_activate_lsp(cd, fd, sum_supported && !disable_sum, admin_key, admin_key_len,
1109
              &range_policy, &segment_in_sum);
1110
  else
1111
    r = opal_reuse_active_lsp(cd, fd, sum_supported, segment_number, admin_key,
1112
            admin_key_len, &range_policy, &segment_in_sum);
1113
  if (r < 0)
1114
    goto out;
1115
1116
  /* In SUM, user is already active and properly assigned to LR */
1117
  if (!segment_in_sum) {
1118
    r = opal_setup_user(cd, fd, segment_number, admin_key, admin_key_len);
1119
    if (r < 0)
1120
      goto out;
1121
  }
1122
1123
  new_pw = crypt_safe_alloc(sizeof(struct opal_new_pw));
1124
  if (!new_pw) {
1125
    r = -ENOMEM;
1126
    goto out;
1127
  }
1128
1129
  /*
1130
   * In SUM we have to authenticate using the User authority (associated with the locking
1131
   * range) even though it was just created and it has empty passhrase (per OPAL2 SUM std.).
1132
   *
1133
   * Admin authority can not change User authority passphrase. It would defeat the purpose
1134
   * of the SUM extension.
1135
   */
1136
  *new_pw = (struct opal_new_pw) {
1137
    .session = {
1138
      .sum = segment_in_sum,
1139
      .who = segment_in_sum ? segment_number + 1 : OPAL_ADMIN1,
1140
      .opal_key = {
1141
        .lr = segment_number,
1142
        .key_len = segment_in_sum ? 0 : admin_key_len,
1143
      },
1144
    },
1145
    .new_user_pw = {
1146
      .who = segment_number + 1,
1147
      .opal_key = {
1148
        .key_len = crypt_volume_key_length(vk),
1149
        .lr = segment_number,
1150
      },
1151
    },
1152
  };
1153
  crypt_safe_memcpy(new_pw->new_user_pw.opal_key.key, crypt_volume_key_get_key(vk),
1154
        crypt_volume_key_length(vk));
1155
  if (!segment_in_sum)
1156
    crypt_safe_memcpy(new_pw->session.opal_key.key, admin_key, admin_key_len);
1157
1158
  r = opal_ioctl(cd, fd, IOC_OPAL_SET_PW, new_pw);
1159
  if (r < 0)
1160
    goto out;
1161
  if (r != OPAL_STATUS_SUCCESS) {
1162
    log_dbg(cd, "Failed to set OPAL user password on device '%s': (%d) %s",
1163
      crypt_get_device_name(cd), r, opal_status_to_string(r));
1164
    r = -EINVAL;
1165
    goto out;
1166
  }
1167
1168
  r = opal_setup_range(cd, fd, segment_in_sum, range_policy, segment_number,
1169
           range_start_blocks, range_length_blocks, vk, admin_key, admin_key_len);
1170
  if (r < 0)
1171
    goto out;
1172
1173
  /* After setup an OPAL device is unlocked, but the expectation with cryptsetup is that it needs
1174
   * to be activated separately, so lock it immediately. */
1175
  lock = crypt_safe_alloc(sizeof(struct opal_lock_unlock));
1176
  if (!lock) {
1177
    r = -ENOMEM;
1178
    goto out;
1179
  }
1180
  *lock = (struct opal_lock_unlock) {
1181
    .l_state = OPAL_LK,
1182
    .session = {
1183
      .who = segment_number + 1,
1184
      .opal_key = {
1185
        .key_len = crypt_volume_key_length(vk),
1186
        .lr = segment_number,
1187
      },
1188
    }
1189
  };
1190
  crypt_safe_memcpy(lock->session.opal_key.key, crypt_volume_key_get_key(vk),
1191
        crypt_volume_key_length(vk));
1192
1193
  r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, lock);
1194
  if (r < 0)
1195
    goto out;
1196
  if (r != OPAL_STATUS_SUCCESS) {
1197
    log_dbg(cd, "Failed to lock OPAL device '%s': %s",
1198
      crypt_get_device_name(cd), opal_status_to_string(r));
1199
    r = -EINVAL;
1200
    goto out;
1201
  }
1202
1203
  /* Double check the locking range is locked and the ranges are set up as configured */
1204
  r = opal_range_check_attributes_fd(cd, fd, segment_number, vk,
1205
             &(uint64_t) {range_start_blocks * opal_block_bytes / SECTOR_SIZE},
1206
             &(uint64_t) {range_length_blocks * opal_block_bytes / SECTOR_SIZE},
1207
             &(bool) {true}, &(bool){true}, NULL, NULL);
1208
1209
  /* Only if SUM was configured successfully add explicit SUM LUKS2 requirement flag */
1210
  *r_opal_req_version = segment_in_sum ? LUKS2_OPAL_SUM_REQ_VERSION : LUKS2_OPAL_BASE_REQ_VERSION;
1211
out:
1212
  crypt_safe_free(new_pw);
1213
  crypt_safe_free(lock);
1214
1215
  return r;
1216
}
1217
1218
static int opal_lock_unlock(struct crypt_device *cd,
1219
          struct device *dev,
1220
          uint32_t segment_number,
1221
          const struct volume_key *vk,
1222
          bool lock)
1223
{
1224
  struct opal_lock_unlock unlock = {
1225
    .l_state = lock ? OPAL_LK : OPAL_RW,
1226
    .session = {
1227
      .who = segment_number + 1,
1228
      .opal_key = {
1229
        .lr = segment_number,
1230
      },
1231
    },
1232
  };
1233
  int r, fd;
1234
1235
  if (opal_supported(cd, dev) <= 0)
1236
    return -ENOTSUP;
1237
  if (!lock && !vk)
1238
    return -EINVAL;
1239
1240
  fd = device_open(cd, dev, O_RDONLY);
1241
  if (fd < 0)
1242
    return -EIO;
1243
1244
  if (!lock) {
1245
    assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
1246
1247
    unlock.session.opal_key.key_len = crypt_volume_key_length(vk);
1248
    crypt_safe_memcpy(unlock.session.opal_key.key, crypt_volume_key_get_key(vk),
1249
          crypt_volume_key_length(vk));
1250
  }
1251
1252
  r = opal_ioctl(cd, fd, IOC_OPAL_LOCK_UNLOCK, &unlock);
1253
  if (r < 0) {
1254
    r = -ENOTSUP;
1255
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
1256
    goto out;
1257
  }
1258
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
1259
    r = -EPERM;
1260
    log_dbg(cd, "Failed to %slock OPAL device '%s': permission denied",
1261
      lock ? "" : "un", crypt_get_device_name(cd));
1262
    goto out;
1263
  }
1264
  if (r != OPAL_STATUS_SUCCESS) {
1265
    log_dbg(cd, "Failed to %slock OPAL device '%s': %s",
1266
      lock ? "" : "un", crypt_get_device_name(cd), opal_status_to_string(r));
1267
    r = -EINVAL;
1268
    goto out;
1269
  }
1270
1271
  /* If we are unlocking, also tell the kernel to automatically unlock when resuming
1272
   * from suspend, otherwise the drive will be locked and everything will go up in flames.
1273
   * Also set the flag to allow locking without having to pass the key again.
1274
   * But do not error out if this fails, as the device will already be unlocked.
1275
   *
1276
   * On a lock path we have to overwrite the cached key from kernel otherwise the locking range
1277
   * gets unlocked automatically after system resume even when cryptsetup previously locked it
1278
   * on purpose (crypt_deactivate* or crypt_suspend)
1279
   */
1280
  if (!lock)
1281
    unlock.flags = OPAL_SAVE_FOR_LOCK;
1282
1283
  r = opal_ioctl(cd, fd, IOC_OPAL_SAVE, &unlock);
1284
  if (r < 0)
1285
    goto out;
1286
  if (r != OPAL_STATUS_SUCCESS) {
1287
    if (!lock)
1288
      log_std(cd, "Failed to prepare OPAL device '%s' for sleep resume, be aware before suspending: %s",
1289
        crypt_get_device_name(cd), opal_status_to_string(r));
1290
    else
1291
      log_std(cd, "Failed to erase OPAL key for device '%s' from kernel: %s",
1292
        crypt_get_device_name(cd), opal_status_to_string(r));
1293
    r = 0;
1294
  }
1295
out:
1296
  if (!lock)
1297
    crypt_safe_memzero(unlock.session.opal_key.key, unlock.session.opal_key.key_len);
1298
1299
  return r;
1300
}
1301
1302
/* requires opal lock */
1303
int opal_lock(struct crypt_device *cd, struct device *dev, uint32_t segment_number)
1304
{
1305
  return opal_lock_unlock(cd, dev, segment_number, NULL, /* lock= */ true);
1306
}
1307
1308
/* requires opal lock */
1309
int opal_unlock(struct crypt_device *cd,
1310
    struct device *dev,
1311
    uint32_t segment_number,
1312
    const struct volume_key *vk)
1313
{
1314
  return opal_lock_unlock(cd, dev, segment_number, vk, /* lock= */ false);
1315
}
1316
1317
/*
1318
 * It does not require opal lock. This completely destroys
1319
 * data on whole OPAL block device. Serialization does not
1320
 * make sense here.
1321
 */
1322
int opal_factory_reset(struct crypt_device *cd,
1323
           struct device *dev,
1324
           const char *password,
1325
           size_t password_len)
1326
{
1327
  struct opal_key reset = {
1328
    .key_len = password_len,
1329
  };
1330
  int r, fd;
1331
1332
  assert(cd);
1333
  assert(dev);
1334
  assert(password);
1335
1336
  if (password_len > OPAL_KEY_MAX)
1337
    return -EINVAL;
1338
1339
  /*
1340
   * Submit PSID reset on R/W file descriptor so it
1341
   * triggers blkid rescan after we close it.
1342
   */
1343
  fd = device_open(cd, dev, O_RDWR);
1344
  if (fd < 0)
1345
    return -EIO;
1346
1347
  crypt_safe_memcpy(reset.key, password, password_len);
1348
1349
  r = opal_ioctl(cd, fd, IOC_OPAL_PSID_REVERT_TPR, &reset);
1350
  if (r < 0) {
1351
    r = -ENOTSUP;
1352
    log_dbg(cd, "OPAL not supported on this kernel version, refusing.");
1353
    goto out;
1354
  }
1355
  if (r == OPAL_STATUS_NOT_AUTHORIZED) /* We'll try again with a different key. */ {
1356
    r = -EPERM;
1357
    log_dbg(cd, "Failed to reset OPAL device '%s', incorrect PSID?",
1358
      crypt_get_device_name(cd));
1359
    goto out;
1360
  }
1361
  if (r != OPAL_STATUS_SUCCESS) {
1362
    r = -EINVAL;
1363
    log_dbg(cd, "Failed to reset OPAL device '%s' with PSID: %s",
1364
      crypt_get_device_name(cd), opal_status_to_string(r));
1365
    goto out;
1366
  }
1367
out:
1368
  crypt_safe_memzero(reset.key, reset.key_len);
1369
1370
  return r;
1371
}
1372
1373
/* requires opal lock */
1374
int opal_reset_segment(struct crypt_device *cd,
1375
           struct device *dev,
1376
           uint32_t segment_number,
1377
           const char *password,
1378
           size_t password_len)
1379
{
1380
  int r, fd;
1381
  struct opal_session_info *user_session = NULL;
1382
  struct opal_user_lr_setup *setup = NULL;
1383
  uint32_t sum_supported;
1384
  uint8_t segment_in_sum = 0;
1385
1386
  assert(cd);
1387
  assert(dev);
1388
  assert(password);
1389
1390
  if (password_len > OPAL_KEY_MAX)
1391
    return -EINVAL;
1392
1393
  if (opal_enabled(cd, dev) <= 0)
1394
    return -EINVAL;
1395
1396
  /* Not all drivers support Single User Mode, so query and adjust the setup accordingly */
1397
  r = opal_sum_supported(cd, dev);
1398
  if (r < 0)
1399
    return r;
1400
  sum_supported = !!r;
1401
1402
  fd = device_open(cd, dev, O_RDONLY);
1403
  if (fd < 0) {
1404
    r = -EIO;
1405
    goto out;
1406
  }
1407
1408
  user_session = crypt_safe_alloc(sizeof(struct opal_session_info));
1409
  if (!user_session)
1410
    return -ENOMEM;
1411
  *user_session = (struct opal_session_info) {
1412
    .who = OPAL_ADMIN1,
1413
    .opal_key = {
1414
      .lr = segment_number,
1415
      .key_len = password_len,
1416
    },
1417
  };
1418
  crypt_safe_memcpy(user_session->opal_key.key, password, password_len);
1419
1420
  if (sum_supported) {
1421
    r = opal_get_sum_status_anybody(cd, fd, segment_number, NULL, &segment_in_sum);
1422
    if (r < 0)
1423
      goto out;
1424
  }
1425
1426
  if (segment_in_sum) {
1427
    r = opal_ioctl(cd, fd, IOC_OPAL_ERASE_LR, user_session);
1428
    if (r == OPAL_STATUS_NOT_AUTHORIZED) {
1429
      log_dbg(cd, "Failed to erase SUM OPAL locking range for device '%s', incorrect password?",
1430
        crypt_get_device_name(cd));
1431
      r = -EPERM;
1432
    } else if (r != OPAL_STATUS_SUCCESS) {
1433
      log_dbg(cd, "Failed to erase SUM OPAL locking range %u on device '%s': %s",
1434
        segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1435
      r = -EINVAL;
1436
    }
1437
1438
    /* Locking range in SUM is properly disabled after 'Erase' method. Exit early. */
1439
    goto out;
1440
  }
1441
1442
  r = opal_ioctl(cd, fd, IOC_OPAL_SECURE_ERASE_LR, user_session);
1443
  if (r < 0)
1444
    goto out;
1445
  else if (r == OPAL_STATUS_NOT_AUTHORIZED) {
1446
    log_dbg(cd, "Failed to reset (secure erase) OPAL locking range for device '%s', incorrect password?",
1447
      crypt_get_device_name(cd));
1448
    r = -EPERM;
1449
    goto out;
1450
  } else if (r != OPAL_STATUS_SUCCESS) {
1451
    log_dbg(cd, "Failed to reset (secure erase) OPAL locking range %u on device '%s': %s",
1452
      segment_number, crypt_get_device_name(cd), opal_status_to_string(r));
1453
    r = -EINVAL;
1454
    goto out;
1455
  }
1456
1457
  /* Disable the locking range */
1458
  setup = crypt_safe_alloc(sizeof(struct opal_user_lr_setup));
1459
  if (!setup) {
1460
    r = -ENOMEM;
1461
    goto out;
1462
  }
1463
  *setup = (struct opal_user_lr_setup) {
1464
    .session = {
1465
      .who = OPAL_ADMIN1,
1466
      .opal_key = user_session->opal_key,
1467
    },
1468
  };
1469
1470
  r = opal_ioctl(cd, fd, IOC_OPAL_LR_SETUP, setup);
1471
  if (r < 0)
1472
    goto out;
1473
  if (r != OPAL_STATUS_SUCCESS) {
1474
    log_dbg(cd, "Failed to disable locking range on OPAL device '%s': %s",
1475
      crypt_get_device_name(cd), opal_status_to_string(r));
1476
    r = -EINVAL;
1477
    goto out;
1478
  }
1479
out:
1480
  crypt_safe_free(user_session);
1481
  crypt_safe_free(setup);
1482
1483
  return r;
1484
}
1485
1486
/*
1487
 * Does not require opal lock (immutable).
1488
 */
1489
int opal_supported(struct crypt_device *cd, struct device *dev)
1490
{
1491
  return opal_query_status(cd, dev, OPAL_FL_SUPPORTED|OPAL_FL_LOCKING_SUPPORTED);
1492
}
1493
1494
/*
1495
 * Does not require opal lock (immutable).
1496
 */
1497
int opal_geometry(struct crypt_device *cd,
1498
      struct device *dev,
1499
      bool *ret_align,
1500
      uint32_t *ret_block_size,
1501
      uint64_t *ret_alignment_granularity_blocks,
1502
      uint64_t *ret_lowest_lba_blocks)
1503
{
1504
  int fd;
1505
1506
  assert(cd);
1507
  assert(dev);
1508
1509
  fd = device_open(cd, dev, O_RDONLY);
1510
  if (fd < 0)
1511
    return -EIO;
1512
1513
  return opal_geometry_fd(cd, fd, ret_align, ret_block_size,
1514
        ret_alignment_granularity_blocks, ret_lowest_lba_blocks);
1515
}
1516
1517
/* requires opal lock */
1518
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
1519
         struct device *dev,
1520
         uint32_t segment_number,
1521
         const struct volume_key *vk,
1522
         const uint64_t *check_offset_sectors,
1523
         const uint64_t *check_length_sectors,
1524
         bool *ret_read_locked,
1525
         bool *ret_write_locked)
1526
{
1527
  int fd;
1528
1529
  assert(cd);
1530
  assert(dev);
1531
  assert(vk);
1532
1533
  fd = device_open(cd, dev, O_RDONLY);
1534
  if (fd < 0)
1535
    return -EIO;
1536
1537
  return opal_range_check_attributes_fd(cd, fd, segment_number, vk,
1538
                check_offset_sectors, check_length_sectors, NULL,
1539
                NULL, ret_read_locked, ret_write_locked);
1540
}
1541
1542
static int opal_lock_internal(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1543
{
1544
  char *lock_resource;
1545
  int devfd, r;
1546
  struct stat st;
1547
1548
  if (!crypt_metadata_locking_enabled()) {
1549
    *opal_lock = NULL;
1550
    return 0;
1551
  }
1552
1553
  /*
1554
   * This also asserts we do not hold any metadata lock on the same device to
1555
   * avoid deadlock (OPAL lock must be taken first)
1556
   */
1557
  devfd = device_open(cd, opal_device, O_RDONLY);
1558
  if (devfd < 0)
1559
    return -EINVAL;
1560
1561
  if (fstat(devfd, &st) || !S_ISBLK(st.st_mode))
1562
    return -EINVAL;
1563
1564
  r = asprintf(&lock_resource, "OPAL_%d:%d", major(st.st_rdev), minor(st.st_rdev));
1565
  if (r < 0)
1566
    return -ENOMEM;
1567
1568
  r = crypt_write_lock(cd, lock_resource, true, opal_lock);
1569
1570
  free(lock_resource);
1571
1572
  return r;
1573
}
1574
1575
int opal_exclusive_lock(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
1576
{
1577
  if (!cd || !opal_device || (crypt_get_type(cd) && strcmp(crypt_get_type(cd), CRYPT_LUKS2)))
1578
    return -EINVAL;
1579
1580
  return opal_lock_internal(cd, opal_device, opal_lock);
1581
}
1582
1583
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock)
1584
{
1585
  crypt_unlock_internal(cd, opal_lock);
1586
}
1587
1588
struct level_0_discovery_header {
1589
  uint32_t length;
1590
  uint32_t revision;
1591
  uint8_t reserved[8];
1592
  uint8_t vendor_specific[32];
1593
}  __attribute__ ((packed));
1594
1595
struct level_0_discovery_feature_shared {
1596
  uint16_t feature_code;
1597
  uint8_t reserved_minor : 4;
1598
  uint8_t descriptor_version : 4;
1599
  uint8_t length;
1600
}  __attribute__ ((packed));
1601
1602
static crypt_status_hw_encryption_info opal_discovery0(struct crypt_device *cd)
1603
{
1604
  int fd;
1605
  int r, feat_length;
1606
  struct opal_discovery discovery;
1607
  struct level_0_discovery_header *dh;
1608
  struct level_0_discovery_feature_shared *feat_hdr;
1609
  char buf[4096];
1610
  const char *feature;
1611
  void *feat_ptr, *feat_end;
1612
  crypt_status_hw_encryption_info hw_enc, hw_enc_final;
1613
1614
  fd = device_open(cd, crypt_data_device(cd), O_RDONLY);
1615
  if (fd < 0)
1616
    return CRYPT_HW_INVALID;
1617
1618
  discovery.data = (uintptr_t)buf;
1619
  discovery.size = sizeof(buf);
1620
  memset(buf, 0, sizeof(buf));
1621
1622
  r = opal_ioctl(cd, fd, IOC_OPAL_DISCOVERY, &discovery);
1623
  if (r < 0)
1624
    return CRYPT_HW_INVALID;
1625
1626
  dh = (struct level_0_discovery_header *)buf;
1627
  feat_ptr = buf + sizeof(*dh);
1628
  feat_end = buf + be32_to_cpu(dh->length);
1629
1630
  hw_enc = hw_enc_final = CRYPT_HW_INVALID;
1631
  while (feat_ptr < feat_end) {
1632
    feat_hdr = feat_ptr;
1633
    /* Length defines data following the header [3.3.6 Core spec] */
1634
    feat_length = feat_hdr->length + sizeof(*feat_hdr);
1635
1636
    switch (be16_to_cpu(feat_hdr->feature_code)) {
1637
    /*   0x0000: reserved */
1638
    case 0x0001: feature = "TPer"; break;
1639
    case 0x0002: feature = "Locking"; break;
1640
    case 0x0003: feature = "Geometry"; break;
1641
    case 0x0004: feature = "Secure messaging"; break;
1642
    case 0x0005: feature = "SIIS"; break;
1643
    /*   0x00ff: reserved */
1644
    /*   0x0100 - 0x03ff: SSCs */
1645
    case 0x0100: feature = "Enterprise"; hw_enc = CRYPT_HW_OTHER; break;
1646
    case 0x0200: feature = "Opal1"; hw_enc = CRYPT_HW_OTHER; break;
1647
    case 0x0201: feature = "SUM"; hw_enc = CRYPT_HW_OPAL_SUM; break;
1648
    case 0x0202: feature = "Data store"; break;
1649
    case 0x0203: feature = "Opal2"; hw_enc = CRYPT_HW_OPAL; break;
1650
    case 0x0301: feature = "Opalite"; hw_enc = CRYPT_HW_OTHER;  break;
1651
    case 0x0302: feature = "Pyrite1"; hw_enc = CRYPT_HW_OTHER;  break;
1652
    case 0x0303: feature = "Pyrite2"; hw_enc = CRYPT_HW_OTHER;  break;
1653
    case 0x0304: feature = "Ruby"; hw_enc = CRYPT_HW_OTHER; break;
1654
    case 0x0305: feature = "KPIO"; break;
1655
    /*   0x0400 - 0xbfff reserved */
1656
    case 0x0401: feature = "Locking LBA ranges"; break;
1657
    case 0x0402: feature = "Block SID"; break;
1658
    case 0x0403: feature = "NS locking"; break;
1659
    case 0x0404: feature = "Data removal"; break;
1660
    case 0x0405: feature = "NS geometry"; break;
1661
    case 0x0407: feature = "NS Shadow MBR"; break;
1662
    case 0x0409: feature = "CPIN"; break;
1663
    case 0x040a: feature = "NS KPIO"; break;
1664
    /*   0xC000 - 0xffff vendor specific */
1665
    default: feature = "(unknown)"; break;
1666
    }
1667
1668
    log_dbg(cd, "Feature 0x%03x %s", be16_to_cpu(feat_hdr->feature_code), feature);
1669
1670
    feat_ptr = (char *)feat_ptr + feat_length;
1671
    if (hw_enc > hw_enc_final)
1672
      hw_enc_final = hw_enc;
1673
  }
1674
1675
  return hw_enc_final;
1676
}
1677
1678
crypt_status_hw_encryption_info crypt_status_hw_encryption(struct crypt_device *cd)
1679
{
1680
  int r;
1681
1682
  r = opal_discovery0(cd);
1683
  if (r > CRYPT_HW_INVALID)
1684
    return r;
1685
1686
  /* Fallback if Discovery is not available */
1687
  if (opal_supported(cd, crypt_data_device(cd)) <= 0)
1688
    return CRYPT_HW_INVALID;
1689
1690
  r = opal_sum_supported(cd, crypt_data_device(cd));
1691
  return r > 0 ? CRYPT_HW_OPAL_SUM : CRYPT_HW_OPAL;
1692
}
1693
1694
int crypt_get_hw_opal_enabled(struct crypt_device *cd)
1695
{
1696
  int fd, r;
1697
1698
  if (!cd)
1699
    return -EINVAL;
1700
1701
  fd = device_open(cd, crypt_data_device(cd), O_RDONLY);
1702
  if (fd < 0)
1703
    return -EIO;
1704
1705
  /* If OPAL2 locking is not supported, return immediately */
1706
  r = opal_query_status_fd(cd, fd, OPAL_FL_SUPPORTED | OPAL_FL_LOCKING_SUPPORTED);
1707
  if (r <= 0)
1708
    return r;
1709
1710
  return opal_query_status_fd(cd, fd, OPAL_FL_LOCKING_ENABLED);
1711
}
1712
1713
int crypt_hw_opal_locking_ranges_max(struct crypt_device *cd __attribute__((unused)))
1714
{
1715
  return OPAL_MAX_LRS;
1716
}
1717
1718
static crypt_hw_opal_lock_state opal_lock_state_translate(unsigned int sed_opal_lock_state)
1719
{
1720
  switch(sed_opal_lock_state) {
1721
  case OPAL_RW:
1722
    return CRYPT_HW_OPAL_RW;
1723
  case OPAL_RO:
1724
    return CRYPT_HW_OPAL_RO;
1725
  case OPAL_LK:
1726
  default: /* fall-through */
1727
    return CRYPT_HW_OPAL_LOCKED;
1728
  }
1729
}
1730
1731
/* returns 1 on success, 0 if LR is not active, negative errno on fatal error */
1732
static int opal_get_range(struct crypt_device *cd,
1733
      int fd,
1734
      uint32_t opal_block_size,
1735
      bool sum_undefined,
1736
      struct opal_lr_status *lrs,
1737
      const struct opal_sum_ranges *sum_ranges,
1738
      struct crypt_hw_opal_range *ret_opal_range)
1739
{
1740
  int r;
1741
  crypt_hw_opal_feature_state sum, range_policy;
1742
1743
  assert(lrs);
1744
  assert(sum_ranges);
1745
  assert(ret_opal_range);
1746
1747
  r = opal_ioctl(cd, fd, IOC_OPAL_GET_LR_STATUS, lrs);
1748
  if (r < 0)
1749
    return r;
1750
  if (r == OPAL_STATUS_NOT_AUTHORIZED)
1751
    return -EPERM;
1752
  if (r != OPAL_STATUS_SUCCESS)
1753
    return 0;
1754
1755
  /* FIXME: fine tune condition when do not report LR back to the caller */
1756
  if (!lrs->range_start && !lrs->range_length && !lrs->RLE && !lrs->WLE)
1757
    return 0;
1758
1759
  if (sum_undefined)
1760
    sum = CRYPT_HW_OPAL_FEATURE_UNDEFINED;
1761
  else
1762
    sum = opal_segment_in_sum(lrs->session.opal_key.lr, sum_ranges);
1763
1764
  /*
1765
   * Do not confuse callers by range policy set to enabled when LR is not in
1766
   * properly configured for SUM.
1767
   */
1768
  if (sum != CRYPT_HW_OPAL_FEATURE_ENABLED)
1769
    range_policy = sum;
1770
  else if (sum_ranges->range_policy)
1771
    range_policy = CRYPT_HW_OPAL_FEATURE_ENABLED;
1772
  else
1773
    range_policy = CRYPT_HW_OPAL_FEATURE_DISABLED;
1774
1775
  *ret_opal_range = (struct crypt_hw_opal_range) {
1776
      .id = lrs->session.opal_key.lr,
1777
      .offset = lrs->range_start * opal_block_size,
1778
      .length = lrs->range_length * opal_block_size,
1779
      .read_locking_enabled = lrs->RLE,
1780
      .write_locking_enabled = lrs->WLE,
1781
      .lock_state = opal_lock_state_translate(lrs->l_state),
1782
      .sum = sum,
1783
      .range_policy = range_policy,
1784
  };
1785
1786
  return 1;
1787
}
1788
1789
int opal_get_single_range_params(struct crypt_device *cd,
1790
       struct device *dev,
1791
       uint32_t opal_user_id,
1792
       uint8_t opal_locking_range_id,
1793
       const void *opal_key,
1794
       size_t opal_key_size,
1795
       struct crypt_hw_opal_range *ret_opal_range)
1796
{
1797
  int fd, r;
1798
  uint32_t opal_block_size;
1799
  struct opal_lr_status *lrs;
1800
  struct opal_sum_ranges sum_ranges = {};
1801
  bool sum_undefined = false;
1802
1803
  assert(ret_opal_range);
1804
1805
  if (opal_key_size > OPAL_KEY_MAX)
1806
    return -EINVAL;
1807
1808
  fd = device_open(cd, dev, O_RDONLY);
1809
  if (fd < 0)
1810
    return -EIO;
1811
1812
  r = opal_geometry_fd(cd, fd, NULL, &opal_block_size, NULL, NULL);
1813
  if (r != OPAL_STATUS_SUCCESS)
1814
    return -EINVAL;
1815
1816
  /* check if kernel recognizes the device as SUM capable */
1817
  r = opal_query_status_fd(cd, fd, OPAL_FL_SUM_SUPPORTED);
1818
  if (r < 0)
1819
    return r;
1820
1821
  /* Check locking ranges SUM state only if the device advertises SUM support */
1822
  if (r) {
1823
    r = opal_get_sum_ranges_anybody(cd, fd, &sum_ranges);
1824
    sum_undefined = (r < 0);
1825
  }
1826
1827
  lrs = crypt_safe_alloc(sizeof(*lrs));
1828
  if (!lrs)
1829
    return -ENOMEM;
1830
1831
  *lrs = (struct opal_lr_status) {
1832
    .session = {
1833
      .who = opal_user_id,
1834
      .opal_key = {
1835
        .lr = opal_locking_range_id,
1836
        .key_len = opal_key_size,
1837
      }
1838
    }
1839
  };
1840
  crypt_safe_memcpy(lrs->session.opal_key.key, opal_key, opal_key_size);
1841
1842
  r = opal_get_range(cd, fd, opal_block_size, sum_undefined, lrs, &sum_ranges, ret_opal_range);
1843
1844
  crypt_safe_free(lrs);
1845
1846
  return r;
1847
}
1848
1849
int opal_get_ranges_params(struct crypt_device *cd,
1850
       struct device *dev,
1851
       uint32_t opal_user_id,
1852
       const void *opal_key,
1853
       size_t opal_key_size,
1854
       struct crypt_hw_opal_range *opal_ranges,
1855
       size_t opal_ranges_count)
1856
{
1857
  int fd, r;
1858
  uint32_t opal_block_size;
1859
  uint8_t lr = 0;
1860
  struct opal_lr_status *lrs;
1861
  struct opal_sum_ranges sum_ranges = {};
1862
  struct crypt_hw_opal_range tmp = {};
1863
  size_t stored_ranges = 0;
1864
  bool sum_undefined = false;
1865
1866
  assert(opal_ranges);
1867
  assert(opal_ranges_count > 0);
1868
1869
  if (opal_key_size > OPAL_KEY_MAX)
1870
    return -EINVAL;
1871
1872
  fd = device_open(cd, dev, O_RDONLY);
1873
  if (fd < 0)
1874
    return -EIO;
1875
1876
  r = opal_geometry_fd(cd, fd, NULL, &opal_block_size, NULL, NULL);
1877
  if (r != OPAL_STATUS_SUCCESS)
1878
    return -EINVAL;
1879
1880
  /* check if kernel recognizes the device as SUM capable */
1881
  r = opal_query_status_fd(cd, fd, OPAL_FL_SUM_SUPPORTED);
1882
  if (r < 0)
1883
    return r;
1884
1885
  /* Check locking ranges SUM state only if the device advertises SUM support */
1886
  if (r) {
1887
    r = opal_get_sum_ranges_anybody(cd, fd, &sum_ranges);
1888
    sum_undefined = (r < 0);
1889
  }
1890
1891
  lrs = crypt_safe_alloc(sizeof(*lrs));
1892
  if (!lrs)
1893
    return -ENOMEM;
1894
1895
  *lrs = (struct opal_lr_status) {
1896
    .session = {
1897
      .who = opal_user_id,
1898
      .opal_key = {
1899
        .key_len = opal_key_size,
1900
      }
1901
    }
1902
  };
1903
  crypt_safe_memcpy(lrs->session.opal_key.key, opal_key, opal_key_size);
1904
1905
  for (lr = 0; lr < OPAL_MAX_LRS; lr++) {
1906
    lrs->session.opal_key.lr = lr;
1907
1908
    r = opal_get_range(cd, fd, opal_block_size, sum_undefined, lrs, &sum_ranges, &tmp);
1909
    if (r == 1) {
1910
      if (stored_ranges < opal_ranges_count)
1911
        opal_ranges[stored_ranges++] = tmp;
1912
      else
1913
        r = -ENOSPC;
1914
    }
1915
    if (r < 0)
1916
      goto out;
1917
  }
1918
1919
  r = stored_ranges;
1920
out:
1921
  crypt_safe_free(lrs);
1922
  if (r < 0)
1923
    memset(opal_ranges, 0, opal_ranges_count * sizeof(*opal_ranges));
1924
1925
  return r;
1926
}
1927
#else
1928
#pragma GCC diagnostic ignored "-Wunused-parameter"
1929
1930
int opal_setup_ranges(struct crypt_device *cd,
1931
          struct device *dev,
1932
          const struct volume_key *vk,
1933
          uint64_t range_start_blocks,
1934
          uint64_t range_length_blocks,
1935
          uint32_t opal_block_bytes,
1936
          uint32_t segment_number,
1937
          const void *admin_key,
1938
          size_t admin_key_len,
1939
          bool disable_sum,
1940
          uint8_t *r_opal_req_version)
1941
0
{
1942
0
  return -ENOTSUP;
1943
0
}
1944
1945
int opal_lock(struct crypt_device *cd, struct device *dev, uint32_t segment_number)
1946
0
{
1947
0
  return -ENOTSUP;
1948
0
}
1949
1950
int opal_unlock(struct crypt_device *cd,
1951
    struct device *dev,
1952
    uint32_t segment_number,
1953
    const struct volume_key *vk)
1954
0
{
1955
0
  return -ENOTSUP;
1956
0
}
1957
1958
int opal_supported(struct crypt_device *cd, struct device *dev)
1959
0
{
1960
0
  return -ENOTSUP;
1961
0
}
1962
1963
int opal_factory_reset(struct crypt_device *cd,
1964
           struct device *dev,
1965
           const char *password,
1966
           size_t password_len)
1967
0
{
1968
0
  return -ENOTSUP;
1969
0
}
1970
1971
int opal_reset_segment(struct crypt_device *cd,
1972
           struct device *dev,
1973
           uint32_t segment_number,
1974
           const char *password,
1975
           size_t password_len)
1976
0
{
1977
0
  return -ENOTSUP;
1978
0
}
1979
1980
int opal_geometry(struct crypt_device *cd,
1981
      struct device *dev,
1982
      bool *ret_align,
1983
      uint32_t *ret_block_size,
1984
      uint64_t *ret_alignment_granularity_blocks,
1985
      uint64_t *ret_lowest_lba_blocks)
1986
0
{
1987
0
  return -ENOTSUP;
1988
0
}
1989
1990
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
1991
         struct device *dev,
1992
         uint32_t segment_number,
1993
         const struct volume_key *vk,
1994
         const uint64_t *check_offset_sectors,
1995
         const uint64_t *check_length_sectors,
1996
         bool *ret_read_locked,
1997
         bool *ret_write_locked)
1998
0
{
1999
0
  return -ENOTSUP;
2000
0
}
2001
2002
int opal_exclusive_lock(struct crypt_device *cd, struct device *opal_device, struct crypt_lock_handle **opal_lock)
2003
0
{
2004
0
  return -ENOTSUP;
2005
0
}
2006
2007
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock)
2008
0
{
2009
0
}
2010
2011
crypt_status_hw_encryption_info crypt_status_hw_encryption(struct crypt_device *cd)
2012
0
{
2013
0
  return CRYPT_HW_INVALID;
2014
0
}
2015
2016
int crypt_get_hw_opal_enabled(struct crypt_device *cd)
2017
0
{
2018
0
  return -ENOTSUP;
2019
0
}
2020
2021
int crypt_hw_opal_locking_ranges_max(struct crypt_device *cd)
2022
0
{
2023
0
  return -ENOTSUP;
2024
0
}
2025
2026
int opal_get_single_range_params(struct crypt_device *cd,
2027
       struct device *dev,
2028
       uint32_t opal_user_id,
2029
       uint8_t opal_locking_range_id,
2030
       const void *opal_key,
2031
       size_t opal_key_size,
2032
       struct crypt_hw_opal_range *ret_opal_range)
2033
0
{
2034
0
  return -ENOTSUP;
2035
0
}
2036
2037
int opal_get_ranges_params(struct crypt_device *cd,
2038
       struct device *dev,
2039
       uint32_t opal_user_id,
2040
       const void *opal_key,
2041
       size_t opal_key_size,
2042
       struct crypt_hw_opal_range *opal_ranges,
2043
       size_t opal_ranges_count)
2044
0
{
2045
  return -ENOTSUP;
2046
0
}
2047
#endif