1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright 2019 Google LLC 4 */ 5 6#ifndef __LINUX_BLK_CRYPTO_INTERNAL_H 7#define __LINUX_BLK_CRYPTO_INTERNAL_H 8 9#include <linux/bio.h> 10#include <linux/blkdev.h> 11 12/* Represents a crypto mode supported by blk-crypto */ 13struct blk_crypto_mode { 14 const char *cipher_str; /* crypto API name (for fallback case) */ 15 unsigned int keysize; /* key size in bytes */ 16 unsigned int ivsize; /* iv size in bytes */ 17}; 18 19extern const struct blk_crypto_mode blk_crypto_modes[]; 20 21#ifdef CONFIG_BLK_INLINE_ENCRYPTION 22 23void bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], 24 unsigned int inc); 25 26bool bio_crypt_rq_ctx_compatible(struct request *rq, struct bio *bio); 27 28bool bio_crypt_ctx_mergeable(struct bio_crypt_ctx *bc1, unsigned int bc1_bytes, 29 struct bio_crypt_ctx *bc2); 30 31static inline bool bio_crypt_ctx_back_mergeable(struct request *req, 32 struct bio *bio) 33{ 34 return bio_crypt_ctx_mergeable(req->crypt_ctx, blk_rq_bytes(req), 35 bio->bi_crypt_context); 36} 37 38static inline bool bio_crypt_ctx_front_mergeable(struct request *req, 39 struct bio *bio) 40{ 41 return bio_crypt_ctx_mergeable(bio->bi_crypt_context, 42 bio->bi_iter.bi_size, req->crypt_ctx); 43} 44 45static inline bool bio_crypt_ctx_merge_rq(struct request *req, 46 struct request *next) 47{ 48 return bio_crypt_ctx_mergeable(req->crypt_ctx, blk_rq_bytes(req), 49 next->crypt_ctx); 50} 51 52static inline void blk_crypto_rq_set_defaults(struct request *rq) 53{ 54 rq->crypt_ctx = NULL; 55 rq->crypt_keyslot = NULL; 56} 57 58static inline bool blk_crypto_rq_is_encrypted(struct request *rq) 59{ 60 return rq->crypt_ctx; 61} 62 63static inline bool blk_crypto_rq_has_keyslot(struct request *rq) 64{ 65 return rq->crypt_keyslot; 66} 67 68#else /* CONFIG_BLK_INLINE_ENCRYPTION */ 69 70static inline bool bio_crypt_rq_ctx_compatible(struct request *rq, 71 struct bio *bio) 72{ 73 return true; 74} 75 76static inline bool bio_crypt_ctx_front_mergeable(struct request *req, 77 struct bio *bio) 78{ 79 return true; 80} 81 82static inline bool bio_crypt_ctx_back_mergeable(struct request *req, 83 struct bio *bio) 84{ 85 return true; 86} 87 88static inline bool bio_crypt_ctx_merge_rq(struct request *req, 89 struct request *next) 90{ 91 return true; 92} 93 94static inline void blk_crypto_rq_set_defaults(struct request *rq) { } 95 96static inline bool blk_crypto_rq_is_encrypted(struct request *rq) 97{ 98 return false; 99} 100 101static inline bool blk_crypto_rq_has_keyslot(struct request *rq) 102{ 103 return false; 104} 105 106#endif /* CONFIG_BLK_INLINE_ENCRYPTION */ 107 108void __bio_crypt_advance(struct bio *bio, unsigned int bytes); 109static inline void bio_crypt_advance(struct bio *bio, unsigned int bytes) 110{ 111 if (bio_has_crypt_ctx(bio)) 112 __bio_crypt_advance(bio, bytes); 113} 114 115void __bio_crypt_free_ctx(struct bio *bio); 116static inline void bio_crypt_free_ctx(struct bio *bio) 117{ 118 if (bio_has_crypt_ctx(bio)) 119 __bio_crypt_free_ctx(bio); 120} 121 122static inline void bio_crypt_do_front_merge(struct request *rq, 123 struct bio *bio) 124{ 125#ifdef CONFIG_BLK_INLINE_ENCRYPTION 126 if (bio_has_crypt_ctx(bio)) 127 memcpy(rq->crypt_ctx->bc_dun, bio->bi_crypt_context->bc_dun, 128 sizeof(rq->crypt_ctx->bc_dun)); 129#endif 130} 131 132bool __blk_crypto_bio_prep(struct bio **bio_ptr); 133static inline bool blk_crypto_bio_prep(struct bio **bio_ptr) 134{ 135 if (bio_has_crypt_ctx(*bio_ptr)) 136 return __blk_crypto_bio_prep(bio_ptr); 137 return true; 138} 139 140blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq); 141static inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq) 142{ 143 if (blk_crypto_rq_is_encrypted(rq)) 144 return __blk_crypto_rq_get_keyslot(rq); 145 return BLK_STS_OK; 146} 147 148void __blk_crypto_rq_put_keyslot(struct request *rq); 149static inline void blk_crypto_rq_put_keyslot(struct request *rq) 150{ 151 if (blk_crypto_rq_has_keyslot(rq)) 152 __blk_crypto_rq_put_keyslot(rq); 153} 154 155void __blk_crypto_free_request(struct request *rq); 156static inline void blk_crypto_free_request(struct request *rq) 157{ 158 if (blk_crypto_rq_is_encrypted(rq)) 159 __blk_crypto_free_request(rq); 160} 161 162int __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, 163 gfp_t gfp_mask); 164/** 165 * blk_crypto_rq_bio_prep - Prepare a request's crypt_ctx when its first bio 166 * is inserted 167 * @rq: The request to prepare 168 * @bio: The first bio being inserted into the request 169 * @gfp_mask: Memory allocation flags 170 * 171 * Return: 0 on success, -ENOMEM if out of memory. -ENOMEM is only possible if 172 * @gfp_mask doesn't include %__GFP_DIRECT_RECLAIM. 173 */ 174static inline int blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, 175 gfp_t gfp_mask) 176{ 177 if (bio_has_crypt_ctx(bio)) 178 return __blk_crypto_rq_bio_prep(rq, bio, gfp_mask); 179 return 0; 180} 181 182/** 183 * blk_crypto_insert_cloned_request - Prepare a cloned request to be inserted 184 * into a request queue. 185 * @rq: the request being queued 186 * 187 * Return: BLK_STS_OK on success, nonzero on error. 188 */ 189static inline blk_status_t blk_crypto_insert_cloned_request(struct request *rq) 190{ 191 192 if (blk_crypto_rq_is_encrypted(rq)) 193 return blk_crypto_rq_get_keyslot(rq); 194 return BLK_STS_OK; 195} 196 197#ifdef CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK 198 199int blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num); 200 201bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr); 202 203int blk_crypto_fallback_evict_key(const struct blk_crypto_key *key); 204 205#else /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */ 206 207static inline int 208blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num) 209{ 210 pr_warn_once("crypto API fallback is disabled\n"); 211 return -ENOPKG; 212} 213 214static inline bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr) 215{ 216 pr_warn_once("crypto API fallback disabled; failing request.\n"); 217 (*bio_ptr)->bi_status = BLK_STS_NOTSUPP; 218 return false; 219} 220 221static inline int 222blk_crypto_fallback_evict_key(const struct blk_crypto_key *key) 223{ 224 return 0; 225} 226 227#endif /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */ 228 229#endif /* __LINUX_BLK_CRYPTO_INTERNAL_H */ 230