162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2019 Google LLC 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __LINUX_BLK_CRYPTO_INTERNAL_H 762306a36Sopenharmony_ci#define __LINUX_BLK_CRYPTO_INTERNAL_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/bio.h> 1062306a36Sopenharmony_ci#include <linux/blk-mq.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* Represents a crypto mode supported by blk-crypto */ 1362306a36Sopenharmony_cistruct blk_crypto_mode { 1462306a36Sopenharmony_ci const char *name; /* name of this mode, shown in sysfs */ 1562306a36Sopenharmony_ci const char *cipher_str; /* crypto API name (for fallback case) */ 1662306a36Sopenharmony_ci unsigned int keysize; /* key size in bytes */ 1762306a36Sopenharmony_ci unsigned int ivsize; /* iv size in bytes */ 1862306a36Sopenharmony_ci}; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciextern const struct blk_crypto_mode blk_crypto_modes[]; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#ifdef CONFIG_BLK_INLINE_ENCRYPTION 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciint blk_crypto_sysfs_register(struct gendisk *disk); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_civoid blk_crypto_sysfs_unregister(struct gendisk *disk); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_civoid bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], 2962306a36Sopenharmony_ci unsigned int inc); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cibool bio_crypt_rq_ctx_compatible(struct request *rq, struct bio *bio); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cibool bio_crypt_ctx_mergeable(struct bio_crypt_ctx *bc1, unsigned int bc1_bytes, 3462306a36Sopenharmony_ci struct bio_crypt_ctx *bc2); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic inline bool bio_crypt_ctx_back_mergeable(struct request *req, 3762306a36Sopenharmony_ci struct bio *bio) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci return bio_crypt_ctx_mergeable(req->crypt_ctx, blk_rq_bytes(req), 4062306a36Sopenharmony_ci bio->bi_crypt_context); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic inline bool bio_crypt_ctx_front_mergeable(struct request *req, 4462306a36Sopenharmony_ci struct bio *bio) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci return bio_crypt_ctx_mergeable(bio->bi_crypt_context, 4762306a36Sopenharmony_ci bio->bi_iter.bi_size, req->crypt_ctx); 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic inline bool bio_crypt_ctx_merge_rq(struct request *req, 5162306a36Sopenharmony_ci struct request *next) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci return bio_crypt_ctx_mergeable(req->crypt_ctx, blk_rq_bytes(req), 5462306a36Sopenharmony_ci next->crypt_ctx); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic inline void blk_crypto_rq_set_defaults(struct request *rq) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci rq->crypt_ctx = NULL; 6062306a36Sopenharmony_ci rq->crypt_keyslot = NULL; 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic inline bool blk_crypto_rq_is_encrypted(struct request *rq) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci return rq->crypt_ctx; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic inline bool blk_crypto_rq_has_keyslot(struct request *rq) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci return rq->crypt_keyslot; 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciblk_status_t blk_crypto_get_keyslot(struct blk_crypto_profile *profile, 7462306a36Sopenharmony_ci const struct blk_crypto_key *key, 7562306a36Sopenharmony_ci struct blk_crypto_keyslot **slot_ptr); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_civoid blk_crypto_put_keyslot(struct blk_crypto_keyslot *slot); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ciint __blk_crypto_evict_key(struct blk_crypto_profile *profile, 8062306a36Sopenharmony_ci const struct blk_crypto_key *key); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cibool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile, 8362306a36Sopenharmony_ci const struct blk_crypto_config *cfg); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#else /* CONFIG_BLK_INLINE_ENCRYPTION */ 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic inline int blk_crypto_sysfs_register(struct gendisk *disk) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci return 0; 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic inline void blk_crypto_sysfs_unregister(struct gendisk *disk) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic inline bool bio_crypt_rq_ctx_compatible(struct request *rq, 9762306a36Sopenharmony_ci struct bio *bio) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci return true; 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic inline bool bio_crypt_ctx_front_mergeable(struct request *req, 10362306a36Sopenharmony_ci struct bio *bio) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci return true; 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic inline bool bio_crypt_ctx_back_mergeable(struct request *req, 10962306a36Sopenharmony_ci struct bio *bio) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci return true; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic inline bool bio_crypt_ctx_merge_rq(struct request *req, 11562306a36Sopenharmony_ci struct request *next) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci return true; 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistatic inline void blk_crypto_rq_set_defaults(struct request *rq) { } 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic inline bool blk_crypto_rq_is_encrypted(struct request *rq) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci return false; 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic inline bool blk_crypto_rq_has_keyslot(struct request *rq) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci return false; 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#endif /* CONFIG_BLK_INLINE_ENCRYPTION */ 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_civoid __bio_crypt_advance(struct bio *bio, unsigned int bytes); 13562306a36Sopenharmony_cistatic inline void bio_crypt_advance(struct bio *bio, unsigned int bytes) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci if (bio_has_crypt_ctx(bio)) 13862306a36Sopenharmony_ci __bio_crypt_advance(bio, bytes); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_civoid __bio_crypt_free_ctx(struct bio *bio); 14262306a36Sopenharmony_cistatic inline void bio_crypt_free_ctx(struct bio *bio) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci if (bio_has_crypt_ctx(bio)) 14562306a36Sopenharmony_ci __bio_crypt_free_ctx(bio); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic inline void bio_crypt_do_front_merge(struct request *rq, 14962306a36Sopenharmony_ci struct bio *bio) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci#ifdef CONFIG_BLK_INLINE_ENCRYPTION 15262306a36Sopenharmony_ci if (bio_has_crypt_ctx(bio)) 15362306a36Sopenharmony_ci memcpy(rq->crypt_ctx->bc_dun, bio->bi_crypt_context->bc_dun, 15462306a36Sopenharmony_ci sizeof(rq->crypt_ctx->bc_dun)); 15562306a36Sopenharmony_ci#endif 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cibool __blk_crypto_bio_prep(struct bio **bio_ptr); 15962306a36Sopenharmony_cistatic inline bool blk_crypto_bio_prep(struct bio **bio_ptr) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci if (bio_has_crypt_ctx(*bio_ptr)) 16262306a36Sopenharmony_ci return __blk_crypto_bio_prep(bio_ptr); 16362306a36Sopenharmony_ci return true; 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ciblk_status_t __blk_crypto_rq_get_keyslot(struct request *rq); 16762306a36Sopenharmony_cistatic inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci if (blk_crypto_rq_is_encrypted(rq)) 17062306a36Sopenharmony_ci return __blk_crypto_rq_get_keyslot(rq); 17162306a36Sopenharmony_ci return BLK_STS_OK; 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_civoid __blk_crypto_rq_put_keyslot(struct request *rq); 17562306a36Sopenharmony_cistatic inline void blk_crypto_rq_put_keyslot(struct request *rq) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci if (blk_crypto_rq_has_keyslot(rq)) 17862306a36Sopenharmony_ci __blk_crypto_rq_put_keyslot(rq); 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_civoid __blk_crypto_free_request(struct request *rq); 18262306a36Sopenharmony_cistatic inline void blk_crypto_free_request(struct request *rq) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci if (blk_crypto_rq_is_encrypted(rq)) 18562306a36Sopenharmony_ci __blk_crypto_free_request(rq); 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciint __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, 18962306a36Sopenharmony_ci gfp_t gfp_mask); 19062306a36Sopenharmony_ci/** 19162306a36Sopenharmony_ci * blk_crypto_rq_bio_prep - Prepare a request's crypt_ctx when its first bio 19262306a36Sopenharmony_ci * is inserted 19362306a36Sopenharmony_ci * @rq: The request to prepare 19462306a36Sopenharmony_ci * @bio: The first bio being inserted into the request 19562306a36Sopenharmony_ci * @gfp_mask: Memory allocation flags 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * Return: 0 on success, -ENOMEM if out of memory. -ENOMEM is only possible if 19862306a36Sopenharmony_ci * @gfp_mask doesn't include %__GFP_DIRECT_RECLAIM. 19962306a36Sopenharmony_ci */ 20062306a36Sopenharmony_cistatic inline int blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, 20162306a36Sopenharmony_ci gfp_t gfp_mask) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci if (bio_has_crypt_ctx(bio)) 20462306a36Sopenharmony_ci return __blk_crypto_rq_bio_prep(rq, bio, gfp_mask); 20562306a36Sopenharmony_ci return 0; 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci#ifdef CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciint blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cibool blk_crypto_fallback_bio_prep(struct bio **bio_ptr); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ciint blk_crypto_fallback_evict_key(const struct blk_crypto_key *key); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci#else /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */ 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cistatic inline int 21962306a36Sopenharmony_ciblk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci pr_warn_once("crypto API fallback is disabled\n"); 22262306a36Sopenharmony_ci return -ENOPKG; 22362306a36Sopenharmony_ci} 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistatic inline bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci pr_warn_once("crypto API fallback disabled; failing request.\n"); 22862306a36Sopenharmony_ci (*bio_ptr)->bi_status = BLK_STS_NOTSUPP; 22962306a36Sopenharmony_ci return false; 23062306a36Sopenharmony_ci} 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_cistatic inline int 23362306a36Sopenharmony_ciblk_crypto_fallback_evict_key(const struct blk_crypto_key *key) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci return 0; 23662306a36Sopenharmony_ci} 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci#endif /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */ 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci#endif /* __LINUX_BLK_CRYPTO_INTERNAL_H */ 241