162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2019 Google LLC 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* 762306a36Sopenharmony_ci * Refer to Documentation/block/inline-encryption.rst for detailed explanation. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define pr_fmt(fmt) "blk-crypto-fallback: " fmt 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <crypto/skcipher.h> 1362306a36Sopenharmony_ci#include <linux/blk-crypto.h> 1462306a36Sopenharmony_ci#include <linux/blk-crypto-profile.h> 1562306a36Sopenharmony_ci#include <linux/blkdev.h> 1662306a36Sopenharmony_ci#include <linux/crypto.h> 1762306a36Sopenharmony_ci#include <linux/mempool.h> 1862306a36Sopenharmony_ci#include <linux/module.h> 1962306a36Sopenharmony_ci#include <linux/random.h> 2062306a36Sopenharmony_ci#include <linux/scatterlist.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include "blk-cgroup.h" 2362306a36Sopenharmony_ci#include "blk-crypto-internal.h" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic unsigned int num_prealloc_bounce_pg = 32; 2662306a36Sopenharmony_cimodule_param(num_prealloc_bounce_pg, uint, 0); 2762306a36Sopenharmony_ciMODULE_PARM_DESC(num_prealloc_bounce_pg, 2862306a36Sopenharmony_ci "Number of preallocated bounce pages for the blk-crypto crypto API fallback"); 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic unsigned int blk_crypto_num_keyslots = 100; 3162306a36Sopenharmony_cimodule_param_named(num_keyslots, blk_crypto_num_keyslots, uint, 0); 3262306a36Sopenharmony_ciMODULE_PARM_DESC(num_keyslots, 3362306a36Sopenharmony_ci "Number of keyslots for the blk-crypto crypto API fallback"); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic unsigned int num_prealloc_fallback_crypt_ctxs = 128; 3662306a36Sopenharmony_cimodule_param(num_prealloc_fallback_crypt_ctxs, uint, 0); 3762306a36Sopenharmony_ciMODULE_PARM_DESC(num_prealloc_crypt_fallback_ctxs, 3862306a36Sopenharmony_ci "Number of preallocated bio fallback crypto contexts for blk-crypto to use during crypto API fallback"); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistruct bio_fallback_crypt_ctx { 4162306a36Sopenharmony_ci struct bio_crypt_ctx crypt_ctx; 4262306a36Sopenharmony_ci /* 4362306a36Sopenharmony_ci * Copy of the bvec_iter when this bio was submitted. 4462306a36Sopenharmony_ci * We only want to en/decrypt the part of the bio as described by the 4562306a36Sopenharmony_ci * bvec_iter upon submission because bio might be split before being 4662306a36Sopenharmony_ci * resubmitted 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci struct bvec_iter crypt_iter; 4962306a36Sopenharmony_ci union { 5062306a36Sopenharmony_ci struct { 5162306a36Sopenharmony_ci struct work_struct work; 5262306a36Sopenharmony_ci struct bio *bio; 5362306a36Sopenharmony_ci }; 5462306a36Sopenharmony_ci struct { 5562306a36Sopenharmony_ci void *bi_private_orig; 5662306a36Sopenharmony_ci bio_end_io_t *bi_end_io_orig; 5762306a36Sopenharmony_ci }; 5862306a36Sopenharmony_ci }; 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic struct kmem_cache *bio_fallback_crypt_ctx_cache; 6262306a36Sopenharmony_cistatic mempool_t *bio_fallback_crypt_ctx_pool; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* 6562306a36Sopenharmony_ci * Allocating a crypto tfm during I/O can deadlock, so we have to preallocate 6662306a36Sopenharmony_ci * all of a mode's tfms when that mode starts being used. Since each mode may 6762306a36Sopenharmony_ci * need all the keyslots at some point, each mode needs its own tfm for each 6862306a36Sopenharmony_ci * keyslot; thus, a keyslot may contain tfms for multiple modes. However, to 6962306a36Sopenharmony_ci * match the behavior of real inline encryption hardware (which only supports a 7062306a36Sopenharmony_ci * single encryption context per keyslot), we only allow one tfm per keyslot to 7162306a36Sopenharmony_ci * be used at a time - the rest of the unused tfms have their keys cleared. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_cistatic DEFINE_MUTEX(tfms_init_lock); 7462306a36Sopenharmony_cistatic bool tfms_inited[BLK_ENCRYPTION_MODE_MAX]; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic struct blk_crypto_fallback_keyslot { 7762306a36Sopenharmony_ci enum blk_crypto_mode_num crypto_mode; 7862306a36Sopenharmony_ci struct crypto_skcipher *tfms[BLK_ENCRYPTION_MODE_MAX]; 7962306a36Sopenharmony_ci} *blk_crypto_keyslots; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic struct blk_crypto_profile *blk_crypto_fallback_profile; 8262306a36Sopenharmony_cistatic struct workqueue_struct *blk_crypto_wq; 8362306a36Sopenharmony_cistatic mempool_t *blk_crypto_bounce_page_pool; 8462306a36Sopenharmony_cistatic struct bio_set crypto_bio_split; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* 8762306a36Sopenharmony_ci * This is the key we set when evicting a keyslot. This *should* be the all 0's 8862306a36Sopenharmony_ci * key, but AES-XTS rejects that key, so we use some random bytes instead. 8962306a36Sopenharmony_ci */ 9062306a36Sopenharmony_cistatic u8 blank_key[BLK_CRYPTO_MAX_KEY_SIZE]; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic void blk_crypto_fallback_evict_keyslot(unsigned int slot) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci struct blk_crypto_fallback_keyslot *slotp = &blk_crypto_keyslots[slot]; 9562306a36Sopenharmony_ci enum blk_crypto_mode_num crypto_mode = slotp->crypto_mode; 9662306a36Sopenharmony_ci int err; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci WARN_ON(slotp->crypto_mode == BLK_ENCRYPTION_MODE_INVALID); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* Clear the key in the skcipher */ 10162306a36Sopenharmony_ci err = crypto_skcipher_setkey(slotp->tfms[crypto_mode], blank_key, 10262306a36Sopenharmony_ci blk_crypto_modes[crypto_mode].keysize); 10362306a36Sopenharmony_ci WARN_ON(err); 10462306a36Sopenharmony_ci slotp->crypto_mode = BLK_ENCRYPTION_MODE_INVALID; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic int 10862306a36Sopenharmony_ciblk_crypto_fallback_keyslot_program(struct blk_crypto_profile *profile, 10962306a36Sopenharmony_ci const struct blk_crypto_key *key, 11062306a36Sopenharmony_ci unsigned int slot) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci struct blk_crypto_fallback_keyslot *slotp = &blk_crypto_keyslots[slot]; 11362306a36Sopenharmony_ci const enum blk_crypto_mode_num crypto_mode = 11462306a36Sopenharmony_ci key->crypto_cfg.crypto_mode; 11562306a36Sopenharmony_ci int err; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if (crypto_mode != slotp->crypto_mode && 11862306a36Sopenharmony_ci slotp->crypto_mode != BLK_ENCRYPTION_MODE_INVALID) 11962306a36Sopenharmony_ci blk_crypto_fallback_evict_keyslot(slot); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci slotp->crypto_mode = crypto_mode; 12262306a36Sopenharmony_ci err = crypto_skcipher_setkey(slotp->tfms[crypto_mode], key->raw, 12362306a36Sopenharmony_ci key->size); 12462306a36Sopenharmony_ci if (err) { 12562306a36Sopenharmony_ci blk_crypto_fallback_evict_keyslot(slot); 12662306a36Sopenharmony_ci return err; 12762306a36Sopenharmony_ci } 12862306a36Sopenharmony_ci return 0; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic int blk_crypto_fallback_keyslot_evict(struct blk_crypto_profile *profile, 13262306a36Sopenharmony_ci const struct blk_crypto_key *key, 13362306a36Sopenharmony_ci unsigned int slot) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci blk_crypto_fallback_evict_keyslot(slot); 13662306a36Sopenharmony_ci return 0; 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistatic const struct blk_crypto_ll_ops blk_crypto_fallback_ll_ops = { 14062306a36Sopenharmony_ci .keyslot_program = blk_crypto_fallback_keyslot_program, 14162306a36Sopenharmony_ci .keyslot_evict = blk_crypto_fallback_keyslot_evict, 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic void blk_crypto_fallback_encrypt_endio(struct bio *enc_bio) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci struct bio *src_bio = enc_bio->bi_private; 14762306a36Sopenharmony_ci int i; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci for (i = 0; i < enc_bio->bi_vcnt; i++) 15062306a36Sopenharmony_ci mempool_free(enc_bio->bi_io_vec[i].bv_page, 15162306a36Sopenharmony_ci blk_crypto_bounce_page_pool); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci src_bio->bi_status = enc_bio->bi_status; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci bio_uninit(enc_bio); 15662306a36Sopenharmony_ci kfree(enc_bio); 15762306a36Sopenharmony_ci bio_endio(src_bio); 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic struct bio *blk_crypto_fallback_clone_bio(struct bio *bio_src) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci unsigned int nr_segs = bio_segments(bio_src); 16362306a36Sopenharmony_ci struct bvec_iter iter; 16462306a36Sopenharmony_ci struct bio_vec bv; 16562306a36Sopenharmony_ci struct bio *bio; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci bio = bio_kmalloc(nr_segs, GFP_NOIO); 16862306a36Sopenharmony_ci if (!bio) 16962306a36Sopenharmony_ci return NULL; 17062306a36Sopenharmony_ci bio_init(bio, bio_src->bi_bdev, bio->bi_inline_vecs, nr_segs, 17162306a36Sopenharmony_ci bio_src->bi_opf); 17262306a36Sopenharmony_ci if (bio_flagged(bio_src, BIO_REMAPPED)) 17362306a36Sopenharmony_ci bio_set_flag(bio, BIO_REMAPPED); 17462306a36Sopenharmony_ci bio->bi_ioprio = bio_src->bi_ioprio; 17562306a36Sopenharmony_ci bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; 17662306a36Sopenharmony_ci bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci bio_for_each_segment(bv, bio_src, iter) 17962306a36Sopenharmony_ci bio->bi_io_vec[bio->bi_vcnt++] = bv; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci bio_clone_blkg_association(bio, bio_src); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci return bio; 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistatic bool 18762306a36Sopenharmony_ciblk_crypto_fallback_alloc_cipher_req(struct blk_crypto_keyslot *slot, 18862306a36Sopenharmony_ci struct skcipher_request **ciph_req_ret, 18962306a36Sopenharmony_ci struct crypto_wait *wait) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci struct skcipher_request *ciph_req; 19262306a36Sopenharmony_ci const struct blk_crypto_fallback_keyslot *slotp; 19362306a36Sopenharmony_ci int keyslot_idx = blk_crypto_keyslot_index(slot); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci slotp = &blk_crypto_keyslots[keyslot_idx]; 19662306a36Sopenharmony_ci ciph_req = skcipher_request_alloc(slotp->tfms[slotp->crypto_mode], 19762306a36Sopenharmony_ci GFP_NOIO); 19862306a36Sopenharmony_ci if (!ciph_req) 19962306a36Sopenharmony_ci return false; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci skcipher_request_set_callback(ciph_req, 20262306a36Sopenharmony_ci CRYPTO_TFM_REQ_MAY_BACKLOG | 20362306a36Sopenharmony_ci CRYPTO_TFM_REQ_MAY_SLEEP, 20462306a36Sopenharmony_ci crypto_req_done, wait); 20562306a36Sopenharmony_ci *ciph_req_ret = ciph_req; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci return true; 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic bool blk_crypto_fallback_split_bio_if_needed(struct bio **bio_ptr) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci struct bio *bio = *bio_ptr; 21362306a36Sopenharmony_ci unsigned int i = 0; 21462306a36Sopenharmony_ci unsigned int num_sectors = 0; 21562306a36Sopenharmony_ci struct bio_vec bv; 21662306a36Sopenharmony_ci struct bvec_iter iter; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci bio_for_each_segment(bv, bio, iter) { 21962306a36Sopenharmony_ci num_sectors += bv.bv_len >> SECTOR_SHIFT; 22062306a36Sopenharmony_ci if (++i == BIO_MAX_VECS) 22162306a36Sopenharmony_ci break; 22262306a36Sopenharmony_ci } 22362306a36Sopenharmony_ci if (num_sectors < bio_sectors(bio)) { 22462306a36Sopenharmony_ci struct bio *split_bio; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci split_bio = bio_split(bio, num_sectors, GFP_NOIO, 22762306a36Sopenharmony_ci &crypto_bio_split); 22862306a36Sopenharmony_ci if (!split_bio) { 22962306a36Sopenharmony_ci bio->bi_status = BLK_STS_RESOURCE; 23062306a36Sopenharmony_ci return false; 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci bio_chain(split_bio, bio); 23362306a36Sopenharmony_ci submit_bio_noacct(bio); 23462306a36Sopenharmony_ci *bio_ptr = split_bio; 23562306a36Sopenharmony_ci } 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci return true; 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ciunion blk_crypto_iv { 24162306a36Sopenharmony_ci __le64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; 24262306a36Sopenharmony_ci u8 bytes[BLK_CRYPTO_MAX_IV_SIZE]; 24362306a36Sopenharmony_ci}; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic void blk_crypto_dun_to_iv(const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], 24662306a36Sopenharmony_ci union blk_crypto_iv *iv) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci int i; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci for (i = 0; i < BLK_CRYPTO_DUN_ARRAY_SIZE; i++) 25162306a36Sopenharmony_ci iv->dun[i] = cpu_to_le64(dun[i]); 25262306a36Sopenharmony_ci} 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci/* 25562306a36Sopenharmony_ci * The crypto API fallback's encryption routine. 25662306a36Sopenharmony_ci * Allocate a bounce bio for encryption, encrypt the input bio using crypto API, 25762306a36Sopenharmony_ci * and replace *bio_ptr with the bounce bio. May split input bio if it's too 25862306a36Sopenharmony_ci * large. Returns true on success. Returns false and sets bio->bi_status on 25962306a36Sopenharmony_ci * error. 26062306a36Sopenharmony_ci */ 26162306a36Sopenharmony_cistatic bool blk_crypto_fallback_encrypt_bio(struct bio **bio_ptr) 26262306a36Sopenharmony_ci{ 26362306a36Sopenharmony_ci struct bio *src_bio, *enc_bio; 26462306a36Sopenharmony_ci struct bio_crypt_ctx *bc; 26562306a36Sopenharmony_ci struct blk_crypto_keyslot *slot; 26662306a36Sopenharmony_ci int data_unit_size; 26762306a36Sopenharmony_ci struct skcipher_request *ciph_req = NULL; 26862306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 26962306a36Sopenharmony_ci u64 curr_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; 27062306a36Sopenharmony_ci struct scatterlist src, dst; 27162306a36Sopenharmony_ci union blk_crypto_iv iv; 27262306a36Sopenharmony_ci unsigned int i, j; 27362306a36Sopenharmony_ci bool ret = false; 27462306a36Sopenharmony_ci blk_status_t blk_st; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci /* Split the bio if it's too big for single page bvec */ 27762306a36Sopenharmony_ci if (!blk_crypto_fallback_split_bio_if_needed(bio_ptr)) 27862306a36Sopenharmony_ci return false; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci src_bio = *bio_ptr; 28162306a36Sopenharmony_ci bc = src_bio->bi_crypt_context; 28262306a36Sopenharmony_ci data_unit_size = bc->bc_key->crypto_cfg.data_unit_size; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* Allocate bounce bio for encryption */ 28562306a36Sopenharmony_ci enc_bio = blk_crypto_fallback_clone_bio(src_bio); 28662306a36Sopenharmony_ci if (!enc_bio) { 28762306a36Sopenharmony_ci src_bio->bi_status = BLK_STS_RESOURCE; 28862306a36Sopenharmony_ci return false; 28962306a36Sopenharmony_ci } 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci /* 29262306a36Sopenharmony_ci * Get a blk-crypto-fallback keyslot that contains a crypto_skcipher for 29362306a36Sopenharmony_ci * this bio's algorithm and key. 29462306a36Sopenharmony_ci */ 29562306a36Sopenharmony_ci blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile, 29662306a36Sopenharmony_ci bc->bc_key, &slot); 29762306a36Sopenharmony_ci if (blk_st != BLK_STS_OK) { 29862306a36Sopenharmony_ci src_bio->bi_status = blk_st; 29962306a36Sopenharmony_ci goto out_put_enc_bio; 30062306a36Sopenharmony_ci } 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci /* and then allocate an skcipher_request for it */ 30362306a36Sopenharmony_ci if (!blk_crypto_fallback_alloc_cipher_req(slot, &ciph_req, &wait)) { 30462306a36Sopenharmony_ci src_bio->bi_status = BLK_STS_RESOURCE; 30562306a36Sopenharmony_ci goto out_release_keyslot; 30662306a36Sopenharmony_ci } 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci memcpy(curr_dun, bc->bc_dun, sizeof(curr_dun)); 30962306a36Sopenharmony_ci sg_init_table(&src, 1); 31062306a36Sopenharmony_ci sg_init_table(&dst, 1); 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci skcipher_request_set_crypt(ciph_req, &src, &dst, data_unit_size, 31362306a36Sopenharmony_ci iv.bytes); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* Encrypt each page in the bounce bio */ 31662306a36Sopenharmony_ci for (i = 0; i < enc_bio->bi_vcnt; i++) { 31762306a36Sopenharmony_ci struct bio_vec *enc_bvec = &enc_bio->bi_io_vec[i]; 31862306a36Sopenharmony_ci struct page *plaintext_page = enc_bvec->bv_page; 31962306a36Sopenharmony_ci struct page *ciphertext_page = 32062306a36Sopenharmony_ci mempool_alloc(blk_crypto_bounce_page_pool, GFP_NOIO); 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci enc_bvec->bv_page = ciphertext_page; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci if (!ciphertext_page) { 32562306a36Sopenharmony_ci src_bio->bi_status = BLK_STS_RESOURCE; 32662306a36Sopenharmony_ci goto out_free_bounce_pages; 32762306a36Sopenharmony_ci } 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci sg_set_page(&src, plaintext_page, data_unit_size, 33062306a36Sopenharmony_ci enc_bvec->bv_offset); 33162306a36Sopenharmony_ci sg_set_page(&dst, ciphertext_page, data_unit_size, 33262306a36Sopenharmony_ci enc_bvec->bv_offset); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci /* Encrypt each data unit in this page */ 33562306a36Sopenharmony_ci for (j = 0; j < enc_bvec->bv_len; j += data_unit_size) { 33662306a36Sopenharmony_ci blk_crypto_dun_to_iv(curr_dun, &iv); 33762306a36Sopenharmony_ci if (crypto_wait_req(crypto_skcipher_encrypt(ciph_req), 33862306a36Sopenharmony_ci &wait)) { 33962306a36Sopenharmony_ci i++; 34062306a36Sopenharmony_ci src_bio->bi_status = BLK_STS_IOERR; 34162306a36Sopenharmony_ci goto out_free_bounce_pages; 34262306a36Sopenharmony_ci } 34362306a36Sopenharmony_ci bio_crypt_dun_increment(curr_dun, 1); 34462306a36Sopenharmony_ci src.offset += data_unit_size; 34562306a36Sopenharmony_ci dst.offset += data_unit_size; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci } 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci enc_bio->bi_private = src_bio; 35062306a36Sopenharmony_ci enc_bio->bi_end_io = blk_crypto_fallback_encrypt_endio; 35162306a36Sopenharmony_ci *bio_ptr = enc_bio; 35262306a36Sopenharmony_ci ret = true; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci enc_bio = NULL; 35562306a36Sopenharmony_ci goto out_free_ciph_req; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ciout_free_bounce_pages: 35862306a36Sopenharmony_ci while (i > 0) 35962306a36Sopenharmony_ci mempool_free(enc_bio->bi_io_vec[--i].bv_page, 36062306a36Sopenharmony_ci blk_crypto_bounce_page_pool); 36162306a36Sopenharmony_ciout_free_ciph_req: 36262306a36Sopenharmony_ci skcipher_request_free(ciph_req); 36362306a36Sopenharmony_ciout_release_keyslot: 36462306a36Sopenharmony_ci blk_crypto_put_keyslot(slot); 36562306a36Sopenharmony_ciout_put_enc_bio: 36662306a36Sopenharmony_ci if (enc_bio) 36762306a36Sopenharmony_ci bio_uninit(enc_bio); 36862306a36Sopenharmony_ci kfree(enc_bio); 36962306a36Sopenharmony_ci return ret; 37062306a36Sopenharmony_ci} 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci/* 37362306a36Sopenharmony_ci * The crypto API fallback's main decryption routine. 37462306a36Sopenharmony_ci * Decrypts input bio in place, and calls bio_endio on the bio. 37562306a36Sopenharmony_ci */ 37662306a36Sopenharmony_cistatic void blk_crypto_fallback_decrypt_bio(struct work_struct *work) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci struct bio_fallback_crypt_ctx *f_ctx = 37962306a36Sopenharmony_ci container_of(work, struct bio_fallback_crypt_ctx, work); 38062306a36Sopenharmony_ci struct bio *bio = f_ctx->bio; 38162306a36Sopenharmony_ci struct bio_crypt_ctx *bc = &f_ctx->crypt_ctx; 38262306a36Sopenharmony_ci struct blk_crypto_keyslot *slot; 38362306a36Sopenharmony_ci struct skcipher_request *ciph_req = NULL; 38462306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 38562306a36Sopenharmony_ci u64 curr_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; 38662306a36Sopenharmony_ci union blk_crypto_iv iv; 38762306a36Sopenharmony_ci struct scatterlist sg; 38862306a36Sopenharmony_ci struct bio_vec bv; 38962306a36Sopenharmony_ci struct bvec_iter iter; 39062306a36Sopenharmony_ci const int data_unit_size = bc->bc_key->crypto_cfg.data_unit_size; 39162306a36Sopenharmony_ci unsigned int i; 39262306a36Sopenharmony_ci blk_status_t blk_st; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci /* 39562306a36Sopenharmony_ci * Get a blk-crypto-fallback keyslot that contains a crypto_skcipher for 39662306a36Sopenharmony_ci * this bio's algorithm and key. 39762306a36Sopenharmony_ci */ 39862306a36Sopenharmony_ci blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile, 39962306a36Sopenharmony_ci bc->bc_key, &slot); 40062306a36Sopenharmony_ci if (blk_st != BLK_STS_OK) { 40162306a36Sopenharmony_ci bio->bi_status = blk_st; 40262306a36Sopenharmony_ci goto out_no_keyslot; 40362306a36Sopenharmony_ci } 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci /* and then allocate an skcipher_request for it */ 40662306a36Sopenharmony_ci if (!blk_crypto_fallback_alloc_cipher_req(slot, &ciph_req, &wait)) { 40762306a36Sopenharmony_ci bio->bi_status = BLK_STS_RESOURCE; 40862306a36Sopenharmony_ci goto out; 40962306a36Sopenharmony_ci } 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci memcpy(curr_dun, bc->bc_dun, sizeof(curr_dun)); 41262306a36Sopenharmony_ci sg_init_table(&sg, 1); 41362306a36Sopenharmony_ci skcipher_request_set_crypt(ciph_req, &sg, &sg, data_unit_size, 41462306a36Sopenharmony_ci iv.bytes); 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci /* Decrypt each segment in the bio */ 41762306a36Sopenharmony_ci __bio_for_each_segment(bv, bio, iter, f_ctx->crypt_iter) { 41862306a36Sopenharmony_ci struct page *page = bv.bv_page; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci sg_set_page(&sg, page, data_unit_size, bv.bv_offset); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci /* Decrypt each data unit in the segment */ 42362306a36Sopenharmony_ci for (i = 0; i < bv.bv_len; i += data_unit_size) { 42462306a36Sopenharmony_ci blk_crypto_dun_to_iv(curr_dun, &iv); 42562306a36Sopenharmony_ci if (crypto_wait_req(crypto_skcipher_decrypt(ciph_req), 42662306a36Sopenharmony_ci &wait)) { 42762306a36Sopenharmony_ci bio->bi_status = BLK_STS_IOERR; 42862306a36Sopenharmony_ci goto out; 42962306a36Sopenharmony_ci } 43062306a36Sopenharmony_ci bio_crypt_dun_increment(curr_dun, 1); 43162306a36Sopenharmony_ci sg.offset += data_unit_size; 43262306a36Sopenharmony_ci } 43362306a36Sopenharmony_ci } 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ciout: 43662306a36Sopenharmony_ci skcipher_request_free(ciph_req); 43762306a36Sopenharmony_ci blk_crypto_put_keyslot(slot); 43862306a36Sopenharmony_ciout_no_keyslot: 43962306a36Sopenharmony_ci mempool_free(f_ctx, bio_fallback_crypt_ctx_pool); 44062306a36Sopenharmony_ci bio_endio(bio); 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci/** 44462306a36Sopenharmony_ci * blk_crypto_fallback_decrypt_endio - queue bio for fallback decryption 44562306a36Sopenharmony_ci * 44662306a36Sopenharmony_ci * @bio: the bio to queue 44762306a36Sopenharmony_ci * 44862306a36Sopenharmony_ci * Restore bi_private and bi_end_io, and queue the bio for decryption into a 44962306a36Sopenharmony_ci * workqueue, since this function will be called from an atomic context. 45062306a36Sopenharmony_ci */ 45162306a36Sopenharmony_cistatic void blk_crypto_fallback_decrypt_endio(struct bio *bio) 45262306a36Sopenharmony_ci{ 45362306a36Sopenharmony_ci struct bio_fallback_crypt_ctx *f_ctx = bio->bi_private; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci bio->bi_private = f_ctx->bi_private_orig; 45662306a36Sopenharmony_ci bio->bi_end_io = f_ctx->bi_end_io_orig; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci /* If there was an IO error, don't queue for decrypt. */ 45962306a36Sopenharmony_ci if (bio->bi_status) { 46062306a36Sopenharmony_ci mempool_free(f_ctx, bio_fallback_crypt_ctx_pool); 46162306a36Sopenharmony_ci bio_endio(bio); 46262306a36Sopenharmony_ci return; 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci INIT_WORK(&f_ctx->work, blk_crypto_fallback_decrypt_bio); 46662306a36Sopenharmony_ci f_ctx->bio = bio; 46762306a36Sopenharmony_ci queue_work(blk_crypto_wq, &f_ctx->work); 46862306a36Sopenharmony_ci} 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci/** 47162306a36Sopenharmony_ci * blk_crypto_fallback_bio_prep - Prepare a bio to use fallback en/decryption 47262306a36Sopenharmony_ci * 47362306a36Sopenharmony_ci * @bio_ptr: pointer to the bio to prepare 47462306a36Sopenharmony_ci * 47562306a36Sopenharmony_ci * If bio is doing a WRITE operation, this splits the bio into two parts if it's 47662306a36Sopenharmony_ci * too big (see blk_crypto_fallback_split_bio_if_needed()). It then allocates a 47762306a36Sopenharmony_ci * bounce bio for the first part, encrypts it, and updates bio_ptr to point to 47862306a36Sopenharmony_ci * the bounce bio. 47962306a36Sopenharmony_ci * 48062306a36Sopenharmony_ci * For a READ operation, we mark the bio for decryption by using bi_private and 48162306a36Sopenharmony_ci * bi_end_io. 48262306a36Sopenharmony_ci * 48362306a36Sopenharmony_ci * In either case, this function will make the bio look like a regular bio (i.e. 48462306a36Sopenharmony_ci * as if no encryption context was ever specified) for the purposes of the rest 48562306a36Sopenharmony_ci * of the stack except for blk-integrity (blk-integrity and blk-crypto are not 48662306a36Sopenharmony_ci * currently supported together). 48762306a36Sopenharmony_ci * 48862306a36Sopenharmony_ci * Return: true on success. Sets bio->bi_status and returns false on error. 48962306a36Sopenharmony_ci */ 49062306a36Sopenharmony_cibool blk_crypto_fallback_bio_prep(struct bio **bio_ptr) 49162306a36Sopenharmony_ci{ 49262306a36Sopenharmony_ci struct bio *bio = *bio_ptr; 49362306a36Sopenharmony_ci struct bio_crypt_ctx *bc = bio->bi_crypt_context; 49462306a36Sopenharmony_ci struct bio_fallback_crypt_ctx *f_ctx; 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci if (WARN_ON_ONCE(!tfms_inited[bc->bc_key->crypto_cfg.crypto_mode])) { 49762306a36Sopenharmony_ci /* User didn't call blk_crypto_start_using_key() first */ 49862306a36Sopenharmony_ci bio->bi_status = BLK_STS_IOERR; 49962306a36Sopenharmony_ci return false; 50062306a36Sopenharmony_ci } 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci if (!__blk_crypto_cfg_supported(blk_crypto_fallback_profile, 50362306a36Sopenharmony_ci &bc->bc_key->crypto_cfg)) { 50462306a36Sopenharmony_ci bio->bi_status = BLK_STS_NOTSUPP; 50562306a36Sopenharmony_ci return false; 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci if (bio_data_dir(bio) == WRITE) 50962306a36Sopenharmony_ci return blk_crypto_fallback_encrypt_bio(bio_ptr); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci /* 51262306a36Sopenharmony_ci * bio READ case: Set up a f_ctx in the bio's bi_private and set the 51362306a36Sopenharmony_ci * bi_end_io appropriately to trigger decryption when the bio is ended. 51462306a36Sopenharmony_ci */ 51562306a36Sopenharmony_ci f_ctx = mempool_alloc(bio_fallback_crypt_ctx_pool, GFP_NOIO); 51662306a36Sopenharmony_ci f_ctx->crypt_ctx = *bc; 51762306a36Sopenharmony_ci f_ctx->crypt_iter = bio->bi_iter; 51862306a36Sopenharmony_ci f_ctx->bi_private_orig = bio->bi_private; 51962306a36Sopenharmony_ci f_ctx->bi_end_io_orig = bio->bi_end_io; 52062306a36Sopenharmony_ci bio->bi_private = (void *)f_ctx; 52162306a36Sopenharmony_ci bio->bi_end_io = blk_crypto_fallback_decrypt_endio; 52262306a36Sopenharmony_ci bio_crypt_free_ctx(bio); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci return true; 52562306a36Sopenharmony_ci} 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ciint blk_crypto_fallback_evict_key(const struct blk_crypto_key *key) 52862306a36Sopenharmony_ci{ 52962306a36Sopenharmony_ci return __blk_crypto_evict_key(blk_crypto_fallback_profile, key); 53062306a36Sopenharmony_ci} 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_cistatic bool blk_crypto_fallback_inited; 53362306a36Sopenharmony_cistatic int blk_crypto_fallback_init(void) 53462306a36Sopenharmony_ci{ 53562306a36Sopenharmony_ci int i; 53662306a36Sopenharmony_ci int err; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci if (blk_crypto_fallback_inited) 53962306a36Sopenharmony_ci return 0; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci get_random_bytes(blank_key, BLK_CRYPTO_MAX_KEY_SIZE); 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci err = bioset_init(&crypto_bio_split, 64, 0, 0); 54462306a36Sopenharmony_ci if (err) 54562306a36Sopenharmony_ci goto out; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci /* Dynamic allocation is needed because of lockdep_register_key(). */ 54862306a36Sopenharmony_ci blk_crypto_fallback_profile = 54962306a36Sopenharmony_ci kzalloc(sizeof(*blk_crypto_fallback_profile), GFP_KERNEL); 55062306a36Sopenharmony_ci if (!blk_crypto_fallback_profile) { 55162306a36Sopenharmony_ci err = -ENOMEM; 55262306a36Sopenharmony_ci goto fail_free_bioset; 55362306a36Sopenharmony_ci } 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci err = blk_crypto_profile_init(blk_crypto_fallback_profile, 55662306a36Sopenharmony_ci blk_crypto_num_keyslots); 55762306a36Sopenharmony_ci if (err) 55862306a36Sopenharmony_ci goto fail_free_profile; 55962306a36Sopenharmony_ci err = -ENOMEM; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci blk_crypto_fallback_profile->ll_ops = blk_crypto_fallback_ll_ops; 56262306a36Sopenharmony_ci blk_crypto_fallback_profile->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE; 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci /* All blk-crypto modes have a crypto API fallback. */ 56562306a36Sopenharmony_ci for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++) 56662306a36Sopenharmony_ci blk_crypto_fallback_profile->modes_supported[i] = 0xFFFFFFFF; 56762306a36Sopenharmony_ci blk_crypto_fallback_profile->modes_supported[BLK_ENCRYPTION_MODE_INVALID] = 0; 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci blk_crypto_wq = alloc_workqueue("blk_crypto_wq", 57062306a36Sopenharmony_ci WQ_UNBOUND | WQ_HIGHPRI | 57162306a36Sopenharmony_ci WQ_MEM_RECLAIM, num_online_cpus()); 57262306a36Sopenharmony_ci if (!blk_crypto_wq) 57362306a36Sopenharmony_ci goto fail_destroy_profile; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci blk_crypto_keyslots = kcalloc(blk_crypto_num_keyslots, 57662306a36Sopenharmony_ci sizeof(blk_crypto_keyslots[0]), 57762306a36Sopenharmony_ci GFP_KERNEL); 57862306a36Sopenharmony_ci if (!blk_crypto_keyslots) 57962306a36Sopenharmony_ci goto fail_free_wq; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci blk_crypto_bounce_page_pool = 58262306a36Sopenharmony_ci mempool_create_page_pool(num_prealloc_bounce_pg, 0); 58362306a36Sopenharmony_ci if (!blk_crypto_bounce_page_pool) 58462306a36Sopenharmony_ci goto fail_free_keyslots; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci bio_fallback_crypt_ctx_cache = KMEM_CACHE(bio_fallback_crypt_ctx, 0); 58762306a36Sopenharmony_ci if (!bio_fallback_crypt_ctx_cache) 58862306a36Sopenharmony_ci goto fail_free_bounce_page_pool; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci bio_fallback_crypt_ctx_pool = 59162306a36Sopenharmony_ci mempool_create_slab_pool(num_prealloc_fallback_crypt_ctxs, 59262306a36Sopenharmony_ci bio_fallback_crypt_ctx_cache); 59362306a36Sopenharmony_ci if (!bio_fallback_crypt_ctx_pool) 59462306a36Sopenharmony_ci goto fail_free_crypt_ctx_cache; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci blk_crypto_fallback_inited = true; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci return 0; 59962306a36Sopenharmony_cifail_free_crypt_ctx_cache: 60062306a36Sopenharmony_ci kmem_cache_destroy(bio_fallback_crypt_ctx_cache); 60162306a36Sopenharmony_cifail_free_bounce_page_pool: 60262306a36Sopenharmony_ci mempool_destroy(blk_crypto_bounce_page_pool); 60362306a36Sopenharmony_cifail_free_keyslots: 60462306a36Sopenharmony_ci kfree(blk_crypto_keyslots); 60562306a36Sopenharmony_cifail_free_wq: 60662306a36Sopenharmony_ci destroy_workqueue(blk_crypto_wq); 60762306a36Sopenharmony_cifail_destroy_profile: 60862306a36Sopenharmony_ci blk_crypto_profile_destroy(blk_crypto_fallback_profile); 60962306a36Sopenharmony_cifail_free_profile: 61062306a36Sopenharmony_ci kfree(blk_crypto_fallback_profile); 61162306a36Sopenharmony_cifail_free_bioset: 61262306a36Sopenharmony_ci bioset_exit(&crypto_bio_split); 61362306a36Sopenharmony_ciout: 61462306a36Sopenharmony_ci return err; 61562306a36Sopenharmony_ci} 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci/* 61862306a36Sopenharmony_ci * Prepare blk-crypto-fallback for the specified crypto mode. 61962306a36Sopenharmony_ci * Returns -ENOPKG if the needed crypto API support is missing. 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_ciint blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num) 62262306a36Sopenharmony_ci{ 62362306a36Sopenharmony_ci const char *cipher_str = blk_crypto_modes[mode_num].cipher_str; 62462306a36Sopenharmony_ci struct blk_crypto_fallback_keyslot *slotp; 62562306a36Sopenharmony_ci unsigned int i; 62662306a36Sopenharmony_ci int err = 0; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci /* 62962306a36Sopenharmony_ci * Fast path 63062306a36Sopenharmony_ci * Ensure that updates to blk_crypto_keyslots[i].tfms[mode_num] 63162306a36Sopenharmony_ci * for each i are visible before we try to access them. 63262306a36Sopenharmony_ci */ 63362306a36Sopenharmony_ci if (likely(smp_load_acquire(&tfms_inited[mode_num]))) 63462306a36Sopenharmony_ci return 0; 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci mutex_lock(&tfms_init_lock); 63762306a36Sopenharmony_ci if (tfms_inited[mode_num]) 63862306a36Sopenharmony_ci goto out; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci err = blk_crypto_fallback_init(); 64162306a36Sopenharmony_ci if (err) 64262306a36Sopenharmony_ci goto out; 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci for (i = 0; i < blk_crypto_num_keyslots; i++) { 64562306a36Sopenharmony_ci slotp = &blk_crypto_keyslots[i]; 64662306a36Sopenharmony_ci slotp->tfms[mode_num] = crypto_alloc_skcipher(cipher_str, 0, 0); 64762306a36Sopenharmony_ci if (IS_ERR(slotp->tfms[mode_num])) { 64862306a36Sopenharmony_ci err = PTR_ERR(slotp->tfms[mode_num]); 64962306a36Sopenharmony_ci if (err == -ENOENT) { 65062306a36Sopenharmony_ci pr_warn_once("Missing crypto API support for \"%s\"\n", 65162306a36Sopenharmony_ci cipher_str); 65262306a36Sopenharmony_ci err = -ENOPKG; 65362306a36Sopenharmony_ci } 65462306a36Sopenharmony_ci slotp->tfms[mode_num] = NULL; 65562306a36Sopenharmony_ci goto out_free_tfms; 65662306a36Sopenharmony_ci } 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci crypto_skcipher_set_flags(slotp->tfms[mode_num], 65962306a36Sopenharmony_ci CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); 66062306a36Sopenharmony_ci } 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci /* 66362306a36Sopenharmony_ci * Ensure that updates to blk_crypto_keyslots[i].tfms[mode_num] 66462306a36Sopenharmony_ci * for each i are visible before we set tfms_inited[mode_num]. 66562306a36Sopenharmony_ci */ 66662306a36Sopenharmony_ci smp_store_release(&tfms_inited[mode_num], true); 66762306a36Sopenharmony_ci goto out; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ciout_free_tfms: 67062306a36Sopenharmony_ci for (i = 0; i < blk_crypto_num_keyslots; i++) { 67162306a36Sopenharmony_ci slotp = &blk_crypto_keyslots[i]; 67262306a36Sopenharmony_ci crypto_free_skcipher(slotp->tfms[mode_num]); 67362306a36Sopenharmony_ci slotp->tfms[mode_num] = NULL; 67462306a36Sopenharmony_ci } 67562306a36Sopenharmony_ciout: 67662306a36Sopenharmony_ci mutex_unlock(&tfms_init_lock); 67762306a36Sopenharmony_ci return err; 67862306a36Sopenharmony_ci} 679