1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright 2019 Google LLC
4 */
5
6 /**
7 * DOC: The Keyslot Manager
8 *
9 * Many devices with inline encryption support have a limited number of "slots"
10 * into which encryption contexts may be programmed, and requests can be tagged
11 * with a slot number to specify the key to use for en/decryption.
12 *
13 * As the number of slots are limited, and programming keys is expensive on
14 * many inline encryption hardware, we don't want to program the same key into
15 * multiple slots - if multiple requests are using the same key, we want to
16 * program just one slot with that key and use that slot for all requests.
17 *
18 * The keyslot manager manages these keyslots appropriately, and also acts as
19 * an abstraction between the inline encryption hardware and the upper layers.
20 *
21 * Lower layer devices will set up a keyslot manager in their request queue
22 * and tell it how to perform device specific operations like programming/
23 * evicting keys from keyslots.
24 *
25 * Upper layers will call keyslot_manager_get_slot_for_key() to program a
26 * key into some slot in the inline encryption hardware.
27 */
28 #include <crypto/algapi.h>
29 #include <linux/keyslot-manager.h>
30 #include <linux/atomic.h>
31 #include <linux/mutex.h>
32 #include <linux/pm_runtime.h>
33 #include <linux/wait.h>
34 #include <linux/blkdev.h>
35
36 struct keyslot {
37 atomic_t slot_refs;
38 struct list_head idle_slot_node;
39 struct hlist_node hash_node;
40 struct blk_crypto_key key;
41 };
42
43 struct keyslot_manager {
44 unsigned int num_slots;
45 struct keyslot_mgmt_ll_ops ksm_ll_ops;
46 unsigned int features;
47 unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX];
48 unsigned int max_dun_bytes_supported;
49 void *ll_priv_data;
50
51 #ifdef CONFIG_PM
52 /* Device for runtime power management (NULL if none) */
53 struct device *dev;
54 #endif
55
56 /* Protects programming and evicting keys from the device */
57 struct rw_semaphore lock;
58
59 /* List of idle slots, with least recently used slot at front */
60 wait_queue_head_t idle_slots_wait_queue;
61 struct list_head idle_slots;
62 spinlock_t idle_slots_lock;
63
64 /*
65 * Hash table which maps key hashes to keyslots, so that we can find a
66 * key's keyslot in O(1) time rather than O(num_slots). Protected by
67 * 'lock'. A cryptographic hash function is used so that timing attacks
68 * can't leak information about the raw keys.
69 */
70 struct hlist_head *slot_hashtable;
71 unsigned int slot_hashtable_size;
72
73 /* Per-keyslot data */
74 struct keyslot slots[];
75 };
76
keyslot_manager_is_passthrough(struct keyslot_manager * ksm)77 static inline bool keyslot_manager_is_passthrough(struct keyslot_manager *ksm)
78 {
79 return ksm->num_slots == 0;
80 }
81
82 #ifdef CONFIG_PM
keyslot_manager_set_dev(struct keyslot_manager * ksm,struct device * dev)83 static inline void keyslot_manager_set_dev(struct keyslot_manager *ksm,
84 struct device *dev)
85 {
86 ksm->dev = dev;
87 }
88
89 /* If there's an underlying device and it's suspended, resume it. */
keyslot_manager_pm_get(struct keyslot_manager * ksm)90 static inline void keyslot_manager_pm_get(struct keyslot_manager *ksm)
91 {
92 if (ksm->dev)
93 pm_runtime_get_sync(ksm->dev);
94 }
95
keyslot_manager_pm_put(struct keyslot_manager * ksm)96 static inline void keyslot_manager_pm_put(struct keyslot_manager *ksm)
97 {
98 if (ksm->dev)
99 pm_runtime_put_sync(ksm->dev);
100 }
101 #else /* CONFIG_PM */
keyslot_manager_set_dev(struct keyslot_manager * ksm,struct device * dev)102 static inline void keyslot_manager_set_dev(struct keyslot_manager *ksm,
103 struct device *dev)
104 {
105 }
106
keyslot_manager_pm_get(struct keyslot_manager * ksm)107 static inline void keyslot_manager_pm_get(struct keyslot_manager *ksm)
108 {
109 }
110
keyslot_manager_pm_put(struct keyslot_manager * ksm)111 static inline void keyslot_manager_pm_put(struct keyslot_manager *ksm)
112 {
113 }
114 #endif /* !CONFIG_PM */
115
keyslot_manager_hw_enter(struct keyslot_manager * ksm)116 static inline void keyslot_manager_hw_enter(struct keyslot_manager *ksm)
117 {
118 /*
119 * Calling into the driver requires ksm->lock held and the device
120 * resumed. But we must resume the device first, since that can acquire
121 * and release ksm->lock via keyslot_manager_reprogram_all_keys().
122 */
123 keyslot_manager_pm_get(ksm);
124 down_write(&ksm->lock);
125 }
126
keyslot_manager_hw_exit(struct keyslot_manager * ksm)127 static inline void keyslot_manager_hw_exit(struct keyslot_manager *ksm)
128 {
129 up_write(&ksm->lock);
130 keyslot_manager_pm_put(ksm);
131 }
132
133 /**
134 * keyslot_manager_create() - Create a keyslot manager
135 * @dev: Device for runtime power management (NULL if none)
136 * @num_slots: The number of key slots to manage.
137 * @ksm_ll_ops: The struct keyslot_mgmt_ll_ops for the device that this keyslot
138 * manager will use to perform operations like programming and
139 * evicting keys.
140 * @features: The supported features as a bitmask of BLK_CRYPTO_FEATURE_* flags.
141 * Most drivers should set BLK_CRYPTO_FEATURE_STANDARD_KEYS here.
142 * @crypto_mode_supported: Array of size BLK_ENCRYPTION_MODE_MAX of
143 * bitmasks that represents whether a crypto mode
144 * and data unit size are supported. The i'th bit
145 * of crypto_mode_supported[crypto_mode] is set iff
146 * a data unit size of (1 << i) is supported. We
147 * only support data unit sizes that are powers of
148 * 2.
149 * @ll_priv_data: Private data passed as is to the functions in ksm_ll_ops.
150 *
151 * Allocate memory for and initialize a keyslot manager. Called by e.g.
152 * storage drivers to set up a keyslot manager in their request_queue.
153 *
154 * Context: May sleep
155 * Return: Pointer to constructed keyslot manager or NULL on error.
156 */
keyslot_manager_create(struct device * dev,unsigned int num_slots,const struct keyslot_mgmt_ll_ops * ksm_ll_ops,unsigned int features,const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],void * ll_priv_data)157 struct keyslot_manager *keyslot_manager_create(
158 struct device *dev,
159 unsigned int num_slots,
160 const struct keyslot_mgmt_ll_ops *ksm_ll_ops,
161 unsigned int features,
162 const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
163 void *ll_priv_data)
164 {
165 struct keyslot_manager *ksm;
166 unsigned int slot;
167 unsigned int i;
168
169 if (num_slots == 0)
170 return NULL;
171
172 /* Check that all ops are specified */
173 if (ksm_ll_ops->keyslot_program == NULL ||
174 ksm_ll_ops->keyslot_evict == NULL)
175 return NULL;
176
177 ksm = kvzalloc(struct_size(ksm, slots, num_slots), GFP_KERNEL);
178 if (!ksm)
179 return NULL;
180
181 ksm->num_slots = num_slots;
182 ksm->ksm_ll_ops = *ksm_ll_ops;
183 ksm->features = features;
184 memcpy(ksm->crypto_mode_supported, crypto_mode_supported,
185 sizeof(ksm->crypto_mode_supported));
186 ksm->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE;
187 ksm->ll_priv_data = ll_priv_data;
188 keyslot_manager_set_dev(ksm, dev);
189
190 init_rwsem(&ksm->lock);
191
192 init_waitqueue_head(&ksm->idle_slots_wait_queue);
193 INIT_LIST_HEAD(&ksm->idle_slots);
194
195 for (slot = 0; slot < num_slots; slot++) {
196 list_add_tail(&ksm->slots[slot].idle_slot_node,
197 &ksm->idle_slots);
198 }
199
200 spin_lock_init(&ksm->idle_slots_lock);
201
202 ksm->slot_hashtable_size = roundup_pow_of_two(num_slots);
203 ksm->slot_hashtable = kvmalloc_array(ksm->slot_hashtable_size,
204 sizeof(ksm->slot_hashtable[0]),
205 GFP_KERNEL);
206 if (!ksm->slot_hashtable)
207 goto err_free_ksm;
208 for (i = 0; i < ksm->slot_hashtable_size; i++)
209 INIT_HLIST_HEAD(&ksm->slot_hashtable[i]);
210
211 return ksm;
212
213 err_free_ksm:
214 keyslot_manager_destroy(ksm);
215 return NULL;
216 }
217 EXPORT_SYMBOL_GPL(keyslot_manager_create);
218
keyslot_manager_set_max_dun_bytes(struct keyslot_manager * ksm,unsigned int max_dun_bytes)219 void keyslot_manager_set_max_dun_bytes(struct keyslot_manager *ksm,
220 unsigned int max_dun_bytes)
221 {
222 ksm->max_dun_bytes_supported = max_dun_bytes;
223 }
224 EXPORT_SYMBOL_GPL(keyslot_manager_set_max_dun_bytes);
225
226 static inline struct hlist_head *
hash_bucket_for_key(struct keyslot_manager * ksm,const struct blk_crypto_key * key)227 hash_bucket_for_key(struct keyslot_manager *ksm,
228 const struct blk_crypto_key *key)
229 {
230 return &ksm->slot_hashtable[blk_crypto_key_hash(key) &
231 (ksm->slot_hashtable_size - 1)];
232 }
233
remove_slot_from_lru_list(struct keyslot_manager * ksm,int slot)234 static void remove_slot_from_lru_list(struct keyslot_manager *ksm, int slot)
235 {
236 unsigned long flags;
237
238 spin_lock_irqsave(&ksm->idle_slots_lock, flags);
239 list_del(&ksm->slots[slot].idle_slot_node);
240 spin_unlock_irqrestore(&ksm->idle_slots_lock, flags);
241 }
242
find_keyslot(struct keyslot_manager * ksm,const struct blk_crypto_key * key)243 static int find_keyslot(struct keyslot_manager *ksm,
244 const struct blk_crypto_key *key)
245 {
246 const struct hlist_head *head = hash_bucket_for_key(ksm, key);
247 const struct keyslot *slotp;
248
249 hlist_for_each_entry(slotp, head, hash_node) {
250 if (slotp->key.hash == key->hash &&
251 slotp->key.crypto_mode == key->crypto_mode &&
252 slotp->key.size == key->size &&
253 slotp->key.data_unit_size == key->data_unit_size &&
254 !crypto_memneq(slotp->key.raw, key->raw, key->size))
255 return slotp - ksm->slots;
256 }
257 return -ENOKEY;
258 }
259
find_and_grab_keyslot(struct keyslot_manager * ksm,const struct blk_crypto_key * key)260 static int find_and_grab_keyslot(struct keyslot_manager *ksm,
261 const struct blk_crypto_key *key)
262 {
263 int slot;
264
265 slot = find_keyslot(ksm, key);
266 if (slot < 0)
267 return slot;
268 if (atomic_inc_return(&ksm->slots[slot].slot_refs) == 1) {
269 /* Took first reference to this slot; remove it from LRU list */
270 remove_slot_from_lru_list(ksm, slot);
271 }
272 return slot;
273 }
274
275 /**
276 * keyslot_manager_get_slot_for_key() - Program a key into a keyslot.
277 * @ksm: The keyslot manager to program the key into.
278 * @key: Pointer to the key object to program, including the raw key, crypto
279 * mode, and data unit size.
280 *
281 * Get a keyslot that's been programmed with the specified key. If one already
282 * exists, return it with incremented refcount. Otherwise, wait for a keyslot
283 * to become idle and program it.
284 *
285 * Context: Process context. Takes and releases ksm->lock.
286 * Return: The keyslot on success, else a -errno value.
287 */
keyslot_manager_get_slot_for_key(struct keyslot_manager * ksm,const struct blk_crypto_key * key)288 int keyslot_manager_get_slot_for_key(struct keyslot_manager *ksm,
289 const struct blk_crypto_key *key)
290 {
291 int slot;
292 int err;
293 struct keyslot *idle_slot;
294
295 if (keyslot_manager_is_passthrough(ksm))
296 return 0;
297
298 down_read(&ksm->lock);
299 slot = find_and_grab_keyslot(ksm, key);
300 up_read(&ksm->lock);
301 if (slot != -ENOKEY)
302 return slot;
303
304 for (;;) {
305 keyslot_manager_hw_enter(ksm);
306 slot = find_and_grab_keyslot(ksm, key);
307 if (slot != -ENOKEY) {
308 keyslot_manager_hw_exit(ksm);
309 return slot;
310 }
311
312 /*
313 * If we're here, that means there wasn't a slot that was
314 * already programmed with the key. So try to program it.
315 */
316 if (!list_empty(&ksm->idle_slots))
317 break;
318
319 keyslot_manager_hw_exit(ksm);
320 wait_event(ksm->idle_slots_wait_queue,
321 !list_empty(&ksm->idle_slots));
322 }
323
324 idle_slot = list_first_entry(&ksm->idle_slots, struct keyslot,
325 idle_slot_node);
326 slot = idle_slot - ksm->slots;
327
328 err = ksm->ksm_ll_ops.keyslot_program(ksm, key, slot);
329 if (err) {
330 wake_up(&ksm->idle_slots_wait_queue);
331 keyslot_manager_hw_exit(ksm);
332 return err;
333 }
334
335 /* Move this slot to the hash list for the new key. */
336 if (idle_slot->key.crypto_mode != BLK_ENCRYPTION_MODE_INVALID)
337 hlist_del(&idle_slot->hash_node);
338 hlist_add_head(&idle_slot->hash_node, hash_bucket_for_key(ksm, key));
339
340 atomic_set(&idle_slot->slot_refs, 1);
341 idle_slot->key = *key;
342
343 remove_slot_from_lru_list(ksm, slot);
344
345 keyslot_manager_hw_exit(ksm);
346 return slot;
347 }
348
349 /**
350 * keyslot_manager_get_slot() - Increment the refcount on the specified slot.
351 * @ksm: The keyslot manager that we want to modify.
352 * @slot: The slot to increment the refcount of.
353 *
354 * This function assumes that there is already an active reference to that slot
355 * and simply increments the refcount. This is useful when cloning a bio that
356 * already has a reference to a keyslot, and we want the cloned bio to also have
357 * its own reference.
358 *
359 * Context: Any context.
360 */
keyslot_manager_get_slot(struct keyslot_manager * ksm,unsigned int slot)361 void keyslot_manager_get_slot(struct keyslot_manager *ksm, unsigned int slot)
362 {
363 if (keyslot_manager_is_passthrough(ksm))
364 return;
365
366 if (WARN_ON(slot >= ksm->num_slots))
367 return;
368
369 WARN_ON(atomic_inc_return(&ksm->slots[slot].slot_refs) < 2);
370 }
371
372 /**
373 * keyslot_manager_put_slot() - Release a reference to a slot
374 * @ksm: The keyslot manager to release the reference from.
375 * @slot: The slot to release the reference from.
376 *
377 * Context: Any context.
378 */
keyslot_manager_put_slot(struct keyslot_manager * ksm,unsigned int slot)379 void keyslot_manager_put_slot(struct keyslot_manager *ksm, unsigned int slot)
380 {
381 unsigned long flags;
382
383 if (keyslot_manager_is_passthrough(ksm))
384 return;
385
386 if (WARN_ON(slot >= ksm->num_slots))
387 return;
388
389 if (atomic_dec_and_lock_irqsave(&ksm->slots[slot].slot_refs,
390 &ksm->idle_slots_lock, flags)) {
391 list_add_tail(&ksm->slots[slot].idle_slot_node,
392 &ksm->idle_slots);
393 spin_unlock_irqrestore(&ksm->idle_slots_lock, flags);
394 wake_up(&ksm->idle_slots_wait_queue);
395 }
396 }
397
398 /**
399 * keyslot_manager_crypto_mode_supported() - Find out if a crypto_mode /
400 * data unit size / is_hw_wrapped_key
401 * combination is supported by a ksm.
402 * @ksm: The keyslot manager to check
403 * @crypto_mode: The crypto mode to check for.
404 * @dun_bytes: The number of bytes that will be used to specify the DUN
405 * @data_unit_size: The data_unit_size for the mode.
406 * @is_hw_wrapped_key: Whether a hardware-wrapped key will be used.
407 *
408 * Calls and returns the result of the crypto_mode_supported function specified
409 * by the ksm.
410 *
411 * Context: Process context.
412 * Return: Whether or not this ksm supports the specified crypto settings.
413 */
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)414 bool keyslot_manager_crypto_mode_supported(struct keyslot_manager *ksm,
415 enum blk_crypto_mode_num crypto_mode,
416 unsigned int dun_bytes,
417 unsigned int data_unit_size,
418 bool is_hw_wrapped_key)
419 {
420 if (!ksm)
421 return false;
422 if (WARN_ON(crypto_mode >= BLK_ENCRYPTION_MODE_MAX))
423 return false;
424 if (WARN_ON(!is_power_of_2(data_unit_size)))
425 return false;
426 if (is_hw_wrapped_key) {
427 if (!(ksm->features & BLK_CRYPTO_FEATURE_WRAPPED_KEYS))
428 return false;
429 } else {
430 if (!(ksm->features & BLK_CRYPTO_FEATURE_STANDARD_KEYS))
431 return false;
432 }
433 if (!(ksm->crypto_mode_supported[crypto_mode] & data_unit_size))
434 return false;
435
436 return ksm->max_dun_bytes_supported >= dun_bytes;
437 }
438
439 /**
440 * keyslot_manager_evict_key() - Evict a key from the lower layer device.
441 * @ksm: The keyslot manager to evict from
442 * @key: The key to evict
443 *
444 * Find the keyslot that the specified key was programmed into, and evict that
445 * slot from the lower layer device if that slot is not currently in use.
446 *
447 * Context: Process context. Takes and releases ksm->lock.
448 * Return: 0 on success, -EBUSY if the key is still in use, or another
449 * -errno value on other error.
450 */
keyslot_manager_evict_key(struct keyslot_manager * ksm,const struct blk_crypto_key * key)451 int keyslot_manager_evict_key(struct keyslot_manager *ksm,
452 const struct blk_crypto_key *key)
453 {
454 int slot;
455 int err;
456 struct keyslot *slotp;
457
458 if (keyslot_manager_is_passthrough(ksm)) {
459 if (ksm->ksm_ll_ops.keyslot_evict) {
460 keyslot_manager_hw_enter(ksm);
461 err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, -1);
462 keyslot_manager_hw_exit(ksm);
463 return err;
464 }
465 return 0;
466 }
467
468 keyslot_manager_hw_enter(ksm);
469
470 slot = find_keyslot(ksm, key);
471 if (slot < 0) {
472 err = slot;
473 goto out_unlock;
474 }
475 slotp = &ksm->slots[slot];
476
477 if (atomic_read(&slotp->slot_refs) != 0) {
478 err = -EBUSY;
479 goto out_unlock;
480 }
481 err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, slot);
482 if (err)
483 goto out_unlock;
484
485 hlist_del(&slotp->hash_node);
486 memzero_explicit(&slotp->key, sizeof(slotp->key));
487 err = 0;
488 out_unlock:
489 keyslot_manager_hw_exit(ksm);
490 return err;
491 }
492
493 /**
494 * keyslot_manager_reprogram_all_keys() - Re-program all keyslots.
495 * @ksm: The keyslot manager
496 *
497 * Re-program all keyslots that are supposed to have a key programmed. This is
498 * intended only for use by drivers for hardware that loses its keys on reset.
499 *
500 * Context: Process context. Takes and releases ksm->lock.
501 */
keyslot_manager_reprogram_all_keys(struct keyslot_manager * ksm)502 void keyslot_manager_reprogram_all_keys(struct keyslot_manager *ksm)
503 {
504 unsigned int slot;
505
506 if (WARN_ON(keyslot_manager_is_passthrough(ksm)))
507 return;
508
509 /* This is for device initialization, so don't resume the device */
510 down_write(&ksm->lock);
511 for (slot = 0; slot < ksm->num_slots; slot++) {
512 const struct keyslot *slotp = &ksm->slots[slot];
513 int err;
514
515 if (slotp->key.crypto_mode == BLK_ENCRYPTION_MODE_INVALID)
516 continue;
517
518 err = ksm->ksm_ll_ops.keyslot_program(ksm, &slotp->key, slot);
519 WARN_ON(err);
520 }
521 up_write(&ksm->lock);
522 }
523 EXPORT_SYMBOL_GPL(keyslot_manager_reprogram_all_keys);
524
525 /**
526 * keyslot_manager_private() - return the private data stored with ksm
527 * @ksm: The keyslot manager
528 *
529 * Returns the private data passed to the ksm when it was created.
530 */
keyslot_manager_private(struct keyslot_manager * ksm)531 void *keyslot_manager_private(struct keyslot_manager *ksm)
532 {
533 return ksm->ll_priv_data;
534 }
535 EXPORT_SYMBOL_GPL(keyslot_manager_private);
536
keyslot_manager_destroy(struct keyslot_manager * ksm)537 void keyslot_manager_destroy(struct keyslot_manager *ksm)
538 {
539 if (ksm) {
540 kvfree(ksm->slot_hashtable);
541 memzero_explicit(ksm, struct_size(ksm, slots, ksm->num_slots));
542 kvfree(ksm);
543 }
544 }
545 EXPORT_SYMBOL_GPL(keyslot_manager_destroy);
546
547 /**
548 * keyslot_manager_create_passthrough() - Create a passthrough keyslot manager
549 * @dev: Device for runtime power management (NULL if none)
550 * @ksm_ll_ops: The struct keyslot_mgmt_ll_ops
551 * @features: Bitmask of BLK_CRYPTO_FEATURE_* flags
552 * @crypto_mode_supported: Bitmasks for supported encryption modes
553 * @ll_priv_data: Private data passed as is to the functions in ksm_ll_ops.
554 *
555 * Allocate memory for and initialize a passthrough keyslot manager.
556 * Called by e.g. storage drivers to set up a keyslot manager in their
557 * request_queue, when the storage driver wants to manage its keys by itself.
558 * This is useful for inline encryption hardware that don't have a small fixed
559 * number of keyslots, and for layered devices.
560 *
561 * See keyslot_manager_create() for more details about the parameters.
562 *
563 * Context: This function may sleep
564 * Return: Pointer to constructed keyslot manager or NULL on error.
565 */
keyslot_manager_create_passthrough(struct device * dev,const struct keyslot_mgmt_ll_ops * ksm_ll_ops,unsigned int features,const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],void * ll_priv_data)566 struct keyslot_manager *keyslot_manager_create_passthrough(
567 struct device *dev,
568 const struct keyslot_mgmt_ll_ops *ksm_ll_ops,
569 unsigned int features,
570 const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
571 void *ll_priv_data)
572 {
573 struct keyslot_manager *ksm;
574
575 ksm = kzalloc(sizeof(*ksm), GFP_KERNEL);
576 if (!ksm)
577 return NULL;
578
579 ksm->ksm_ll_ops = *ksm_ll_ops;
580 ksm->features = features;
581 memcpy(ksm->crypto_mode_supported, crypto_mode_supported,
582 sizeof(ksm->crypto_mode_supported));
583 ksm->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE;
584 ksm->ll_priv_data = ll_priv_data;
585 keyslot_manager_set_dev(ksm, dev);
586
587 init_rwsem(&ksm->lock);
588
589 return ksm;
590 }
591 EXPORT_SYMBOL_GPL(keyslot_manager_create_passthrough);
592
593 /**
594 * keyslot_manager_intersect_modes() - restrict supported modes by child device
595 * @parent: The keyslot manager for parent device
596 * @child: The keyslot manager for child device, or NULL
597 *
598 * Clear any crypto mode support bits in @parent that aren't set in @child.
599 * If @child is NULL, then all parent bits are cleared.
600 *
601 * Only use this when setting up the keyslot manager for a layered device,
602 * before it's been exposed yet.
603 */
keyslot_manager_intersect_modes(struct keyslot_manager * parent,const struct keyslot_manager * child)604 void keyslot_manager_intersect_modes(struct keyslot_manager *parent,
605 const struct keyslot_manager *child)
606 {
607 if (child) {
608 unsigned int i;
609
610 parent->features &= child->features;
611 parent->max_dun_bytes_supported =
612 min(parent->max_dun_bytes_supported,
613 child->max_dun_bytes_supported);
614 for (i = 0; i < ARRAY_SIZE(child->crypto_mode_supported); i++) {
615 parent->crypto_mode_supported[i] &=
616 child->crypto_mode_supported[i];
617 }
618 } else {
619 parent->features = 0;
620 parent->max_dun_bytes_supported = 0;
621 memset(parent->crypto_mode_supported, 0,
622 sizeof(parent->crypto_mode_supported));
623 }
624 }
625 EXPORT_SYMBOL_GPL(keyslot_manager_intersect_modes);
626
627 /**
628 * keyslot_manager_derive_raw_secret() - Derive software secret from wrapped key
629 * @ksm: The keyslot manager
630 * @wrapped_key: The wrapped key
631 * @wrapped_key_size: Size of the wrapped key in bytes
632 * @secret: (output) the software secret
633 * @secret_size: (output) the number of secret bytes to derive
634 *
635 * Given a hardware-wrapped key, ask the hardware to derive a secret which
636 * software can use for cryptographic tasks other than inline encryption. The
637 * derived secret is guaranteed to be cryptographically isolated from the key
638 * with which any inline encryption with this wrapped key would actually be
639 * done. I.e., both will be derived from the unwrapped key.
640 *
641 * Return: 0 on success, -EOPNOTSUPP if hardware-wrapped keys are unsupported,
642 * or another -errno code.
643 */
keyslot_manager_derive_raw_secret(struct keyslot_manager * ksm,const u8 * wrapped_key,unsigned int wrapped_key_size,u8 * secret,unsigned int secret_size)644 int keyslot_manager_derive_raw_secret(struct keyslot_manager *ksm,
645 const u8 *wrapped_key,
646 unsigned int wrapped_key_size,
647 u8 *secret, unsigned int secret_size)
648 {
649 int err;
650
651 if (ksm->ksm_ll_ops.derive_raw_secret) {
652 keyslot_manager_hw_enter(ksm);
653 err = ksm->ksm_ll_ops.derive_raw_secret(ksm, wrapped_key,
654 wrapped_key_size,
655 secret, secret_size);
656 keyslot_manager_hw_exit(ksm);
657 } else {
658 err = -EOPNOTSUPP;
659 }
660
661 return err;
662 }
663 EXPORT_SYMBOL_GPL(keyslot_manager_derive_raw_secret);
664