Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: aead - Add support for on-stack AEAD req allocation

This patch introduces infrastructure for allocating req objects on the
stack for AEADs. The additions mirror the existing sync skcipher APIs.
This can be used in cases where simple sync AEAD operations are being
done. So allocating the request on stack avoides possible out-of-memory
errors.

The struct crypto_sync_aead is a wrapper around crypto_aead and should
be used in its place when sync only requests will be done on the stack.
Correspondingly, the request should be allocated with
SYNC_AEAD_REQUEST_ON_STACK().

Similar to sync_skcipher APIs, the new sync_aead APIs are wrappers
around the regular aead APIs to facilitate sync only operations. The
following crypto APIs are added:
- struct crypto_sync_aead
- crypto_alloc_sync_aead()
- crypto_free_sync_aead()
- crypto_aync_aead_tfm()
- crypto_sync_aead_setkey()
- crypto_sync_aead_setauthsize()
- crypto_sync_aead_authsize()
- crypto_sync_aead_maxauthsize()
- crypto_sync_aead_ivsize()
- crypto_sync_aead_blocksize()
- crypto_sync_aead_get_flags()
- crypto_sync_aead_set_flags()
- crypto_sync_aead_clear_flags()
- crypto_sync_aead_reqtfm()
- aead_request_set_sync_tfm()
- SYNC_AEAD_REQUEST_ON_STACK()

Signed-off-by: T Pratham <t-pratham@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

T Pratham and committed by
Herbert Xu
85e1a7ec 275a9a3f

+106
+19
crypto/aead.c
··· 205 205 } 206 206 EXPORT_SYMBOL_GPL(crypto_alloc_aead); 207 207 208 + struct crypto_sync_aead *crypto_alloc_sync_aead(const char *alg_name, u32 type, u32 mask) 209 + { 210 + struct crypto_aead *tfm; 211 + 212 + /* Only sync algorithms are allowed. */ 213 + mask |= CRYPTO_ALG_ASYNC; 214 + type &= ~(CRYPTO_ALG_ASYNC); 215 + 216 + tfm = crypto_alloc_tfm(alg_name, &crypto_aead_type, type, mask); 217 + 218 + if (!IS_ERR(tfm) && WARN_ON(crypto_aead_reqsize(tfm) > MAX_SYNC_AEAD_REQSIZE)) { 219 + crypto_free_aead(tfm); 220 + return ERR_PTR(-EINVAL); 221 + } 222 + 223 + return (struct crypto_sync_aead *)tfm; 224 + } 225 + EXPORT_SYMBOL_GPL(crypto_alloc_sync_aead); 226 + 208 227 int crypto_has_aead(const char *alg_name, u32 type, u32 mask) 209 228 { 210 229 return crypto_type_has_alg(alg_name, &crypto_aead_type, type, mask);
+87
include/crypto/aead.h
··· 159 159 struct crypto_tfm base; 160 160 }; 161 161 162 + struct crypto_sync_aead { 163 + struct crypto_aead base; 164 + }; 165 + 166 + #define MAX_SYNC_AEAD_REQSIZE 384 167 + 168 + #define SYNC_AEAD_REQUEST_ON_STACK(name, _tfm) \ 169 + char __##name##_desc[sizeof(struct aead_request) + \ 170 + MAX_SYNC_AEAD_REQSIZE \ 171 + ] CRYPTO_MINALIGN_ATTR; \ 172 + struct aead_request *name = \ 173 + (((struct aead_request *)__##name##_desc)->base.tfm = \ 174 + crypto_sync_aead_tfm((_tfm)), \ 175 + (void *)__##name##_desc) 176 + 162 177 static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm) 163 178 { 164 179 return container_of(tfm, struct crypto_aead, base); ··· 195 180 */ 196 181 struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask); 197 182 183 + struct crypto_sync_aead *crypto_alloc_sync_aead(const char *alg_name, u32 type, u32 mask); 184 + 198 185 static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) 199 186 { 200 187 return &tfm->base; 188 + } 189 + 190 + static inline struct crypto_tfm *crypto_sync_aead_tfm(struct crypto_sync_aead *tfm) 191 + { 192 + return crypto_aead_tfm(&tfm->base); 201 193 } 202 194 203 195 /** ··· 216 194 static inline void crypto_free_aead(struct crypto_aead *tfm) 217 195 { 218 196 crypto_destroy_tfm(tfm, crypto_aead_tfm(tfm)); 197 + } 198 + 199 + static inline void crypto_free_sync_aead(struct crypto_sync_aead *tfm) 200 + { 201 + crypto_free_aead(&tfm->base); 219 202 } 220 203 221 204 /** ··· 265 238 return crypto_aead_alg_ivsize(crypto_aead_alg(tfm)); 266 239 } 267 240 241 + static inline unsigned int crypto_sync_aead_ivsize(struct crypto_sync_aead *tfm) 242 + { 243 + return crypto_aead_ivsize(&tfm->base); 244 + } 245 + 268 246 /** 269 247 * crypto_aead_authsize() - obtain maximum authentication data size 270 248 * @tfm: cipher handle ··· 287 255 return tfm->authsize; 288 256 } 289 257 258 + static inline unsigned int crypto_sync_aead_authsize(struct crypto_sync_aead *tfm) 259 + { 260 + return crypto_aead_authsize(&tfm->base); 261 + } 262 + 290 263 static inline unsigned int crypto_aead_alg_maxauthsize(struct aead_alg *alg) 291 264 { 292 265 return alg->maxauthsize; ··· 300 263 static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead) 301 264 { 302 265 return crypto_aead_alg_maxauthsize(crypto_aead_alg(aead)); 266 + } 267 + 268 + static inline unsigned int crypto_sync_aead_maxauthsize(struct crypto_sync_aead *tfm) 269 + { 270 + return crypto_aead_maxauthsize(&tfm->base); 303 271 } 304 272 305 273 /** ··· 320 278 static inline unsigned int crypto_aead_blocksize(struct crypto_aead *tfm) 321 279 { 322 280 return crypto_tfm_alg_blocksize(crypto_aead_tfm(tfm)); 281 + } 282 + 283 + static inline unsigned int crypto_sync_aead_blocksize(struct crypto_sync_aead *tfm) 284 + { 285 + return crypto_aead_blocksize(&tfm->base); 323 286 } 324 287 325 288 static inline unsigned int crypto_aead_alignmask(struct crypto_aead *tfm) ··· 347 300 crypto_tfm_clear_flags(crypto_aead_tfm(tfm), flags); 348 301 } 349 302 303 + static inline u32 crypto_sync_aead_get_flags(struct crypto_sync_aead *tfm) 304 + { 305 + return crypto_aead_get_flags(&tfm->base); 306 + } 307 + 308 + static inline void crypto_sync_aead_set_flags(struct crypto_sync_aead *tfm, u32 flags) 309 + { 310 + crypto_aead_set_flags(&tfm->base, flags); 311 + } 312 + 313 + static inline void crypto_sync_aead_clear_flags(struct crypto_sync_aead *tfm, u32 flags) 314 + { 315 + crypto_aead_clear_flags(&tfm->base, flags); 316 + } 317 + 350 318 /** 351 319 * crypto_aead_setkey() - set key for cipher 352 320 * @tfm: cipher handle ··· 381 319 int crypto_aead_setkey(struct crypto_aead *tfm, 382 320 const u8 *key, unsigned int keylen); 383 321 322 + static inline int crypto_sync_aead_setkey(struct crypto_sync_aead *tfm, 323 + const u8 *key, unsigned int keylen) 324 + { 325 + return crypto_aead_setkey(&tfm->base, key, keylen); 326 + } 327 + 384 328 /** 385 329 * crypto_aead_setauthsize() - set authentication data size 386 330 * @tfm: cipher handle ··· 399 331 */ 400 332 int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize); 401 333 334 + static inline int crypto_sync_aead_setauthsize(struct crypto_sync_aead *tfm, 335 + unsigned int authsize) 336 + { 337 + return crypto_aead_setauthsize(&tfm->base, authsize); 338 + } 339 + 402 340 static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) 403 341 { 404 342 return __crypto_aead_cast(req->base.tfm); 343 + } 344 + 345 + static inline struct crypto_sync_aead *crypto_sync_aead_reqtfm(struct aead_request *req) 346 + { 347 + struct crypto_aead *tfm = crypto_aead_reqtfm(req); 348 + 349 + return container_of(tfm, struct crypto_sync_aead, base); 405 350 } 406 351 407 352 /** ··· 496 415 struct crypto_aead *tfm) 497 416 { 498 417 req->base.tfm = crypto_aead_tfm(tfm); 418 + } 419 + 420 + static inline void aead_request_set_sync_tfm(struct aead_request *req, 421 + struct crypto_sync_aead *tfm) 422 + { 423 + aead_request_set_tfm(req, &tfm->base); 499 424 } 500 425 501 426 /**