hc
2023-11-07 f45e756958099c35d6afb746df1d40a1c6302cfc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2019 Google LLC
 */
 
#ifndef __LINUX_KEYSLOT_MANAGER_H
#define __LINUX_KEYSLOT_MANAGER_H
 
#include <linux/bio.h>
 
/* Inline crypto feature bits.  Must set at least one. */
enum {
   /* Support for standard software-specified keys */
   BLK_CRYPTO_FEATURE_STANDARD_KEYS = BIT(0),
 
   /* Support for hardware-wrapped keys */
   BLK_CRYPTO_FEATURE_WRAPPED_KEYS = BIT(1),
};
 
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
 
struct keyslot_manager;
 
/**
 * struct keyslot_mgmt_ll_ops - functions to manage keyslots in hardware
 * @keyslot_program:    Program the specified key into the specified slot in the
 *            inline encryption hardware.
 * @keyslot_evict:    Evict key from the specified keyslot in the hardware.
 *            The key is provided so that e.g. dm layers can evict
 *            keys from the devices that they map over.
 *            Returns 0 on success, -errno otherwise.
 * @derive_raw_secret:    (Optional) Derive a software secret from a
 *            hardware-wrapped key.  Returns 0 on success, -EOPNOTSUPP
 *            if unsupported on the hardware, or another -errno code.
 *
 * This structure should be provided by storage device drivers when they set up
 * a keyslot manager - this structure holds the function ptrs that the keyslot
 * manager will use to manipulate keyslots in the hardware.
 */
struct keyslot_mgmt_ll_ops {
   int (*keyslot_program)(struct keyslot_manager *ksm,
                  const struct blk_crypto_key *key,
                  unsigned int slot);
   int (*keyslot_evict)(struct keyslot_manager *ksm,
                const struct blk_crypto_key *key,
                unsigned int slot);
   int (*derive_raw_secret)(struct keyslot_manager *ksm,
                const u8 *wrapped_key,
                unsigned int wrapped_key_size,
                u8 *secret, unsigned int secret_size);
};
 
struct keyslot_manager *keyslot_manager_create(
   struct device *dev,
   unsigned int num_slots,
   const struct keyslot_mgmt_ll_ops *ksm_ops,
   unsigned int features,
   const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
   void *ll_priv_data);
 
void keyslot_manager_set_max_dun_bytes(struct keyslot_manager *ksm,
                      unsigned int max_dun_bytes);
 
int keyslot_manager_get_slot_for_key(struct keyslot_manager *ksm,
                    const struct blk_crypto_key *key);
 
void keyslot_manager_get_slot(struct keyslot_manager *ksm, unsigned int slot);
 
void keyslot_manager_put_slot(struct keyslot_manager *ksm, unsigned int slot);
 
bool keyslot_manager_crypto_mode_supported(struct keyslot_manager *ksm,
                      enum blk_crypto_mode_num crypto_mode,
                      unsigned int dun_bytes,
                      unsigned int data_unit_size,
                      bool is_hw_wrapped_key);
 
int keyslot_manager_evict_key(struct keyslot_manager *ksm,
                 const struct blk_crypto_key *key);
 
void keyslot_manager_reprogram_all_keys(struct keyslot_manager *ksm);
 
void *keyslot_manager_private(struct keyslot_manager *ksm);
 
void keyslot_manager_destroy(struct keyslot_manager *ksm);
 
struct keyslot_manager *keyslot_manager_create_passthrough(
   struct device *dev,
   const struct keyslot_mgmt_ll_ops *ksm_ops,
   unsigned int features,
   const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
   void *ll_priv_data);
 
void keyslot_manager_intersect_modes(struct keyslot_manager *parent,
                    const struct keyslot_manager *child);
 
int keyslot_manager_derive_raw_secret(struct keyslot_manager *ksm,
                     const u8 *wrapped_key,
                     unsigned int wrapped_key_size,
                     u8 *secret, unsigned int secret_size);
 
#endif /* CONFIG_BLK_INLINE_ENCRYPTION */
 
#endif /* __LINUX_KEYSLOT_MANAGER_H */