Source
x
static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* seqiv: Sequence Number IV Generator
*
* This generator generates an IV based on a sequence number by xoring it
* with a salt. This algorithm is mainly useful for CTR and similar modes.
*
* Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
*/
static void seqiv_free(struct crypto_instance *inst);
static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err)
{
struct aead_request *subreq = aead_request_ctx(req);
struct crypto_aead *geniv;
if (err == -EINPROGRESS)
return;
if (err)
goto out;
geniv = crypto_aead_reqtfm(req);
memcpy(req->iv, subreq->iv, crypto_aead_ivsize(geniv));
out:
kzfree(subreq->iv);
}
static void seqiv_aead_encrypt_complete(struct crypto_async_request *base,
int err)
{
struct aead_request *req = base->data;
seqiv_aead_encrypt_complete2(req, err);
aead_request_complete(req, err);
}
static int seqiv_aead_encrypt(struct aead_request *req)
{
struct crypto_aead *geniv = crypto_aead_reqtfm(req);
struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
struct aead_request *subreq = aead_request_ctx(req);
crypto_completion_t compl;
void *data;
u8 *info;
unsigned int ivsize = 8;
int err;
if (req->cryptlen < ivsize)
return -EINVAL;
aead_request_set_tfm(subreq, ctx->child);
compl = req->base.complete;
data = req->base.data;
info = req->iv;
if (req->src != req->dst) {
SYNC_SKCIPHER_REQUEST_ON_STACK(nreq, ctx->sknull);
skcipher_request_set_sync_tfm(nreq, ctx->sknull);
skcipher_request_set_callback(nreq, req->base.flags,
NULL, NULL);
skcipher_request_set_crypt(nreq, req->src, req->dst,
req->assoclen + req->cryptlen,
NULL);
err = crypto_skcipher_encrypt(nreq);
if (err)
return err;
}
if (unlikely(!IS_ALIGNED((unsigned long)info,
crypto_aead_alignmask(geniv) + 1))) {
info = kmemdup(req->iv, ivsize, req->base.flags &
CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
GFP_ATOMIC);
if (!info)
return -ENOMEM;