• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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