static int crypto_rfc4543_copy_src_to_dst(struct aead_request *req, bool enc) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead); unsigned int authsize = crypto_aead_authsize(aead); unsigned int nbytes = req->cryptlen - (enc ? 0 : authsize); struct blkcipher_desc desc = { .tfm = ctx->null, }; return crypto_blkcipher_encrypt(&desc, req->dst, req->src, nbytes); } static int crypto_rfc4543_encrypt(struct aead_request *req) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req); struct aead_request *subreq; int err; if (req->src != req->dst) { err = crypto_rfc4543_copy_src_to_dst(req, true); if (err) return err; } subreq = crypto_rfc4543_crypt(req, true); err = crypto_aead_encrypt(subreq); if (err) return err; scatterwalk_map_and_copy(rctx->auth_tag, req->dst, req->cryptlen, crypto_aead_authsize(aead), 1); return 0; } static int crypto_rfc4543_decrypt(struct aead_request *req) { int err; if (req->src != req->dst) { err = crypto_rfc4543_copy_src_to_dst(req, false); if (err) return err; } req = crypto_rfc4543_crypt(req, false); return crypto_aead_decrypt(req); }
static int crypto_rfc4543_encrypt(struct aead_request *req) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req); struct aead_request *subreq; int err; subreq = crypto_rfc4543_crypt(req, 1); err = crypto_aead_encrypt(subreq); if (err) return err; scatterwalk_map_and_copy(rctx->auth_tag, req->dst, req->cryptlen, crypto_aead_authsize(aead), 1); return 0; }
static int crypto_rfc4543_decrypt(struct aead_request *req) { req = crypto_rfc4543_crypt(req, 0); return crypto_aead_decrypt(req); }