};
struct chacha_req {
- /* the key we generate for Poly1305 using Chacha20 */
- u8 key[POLY1305_KEY_SIZE];
u8 iv[CHACHA20_IV_SIZE];
struct scatterlist src[1];
struct ablkcipher_request req; /* must be last member */
};
struct chachapoly_req_ctx {
+ /* the key we generate for Poly1305 using Chacha20 */
+ u8 key[POLY1305_KEY_SIZE];
/* calculated Poly1305 tag */
u8 tag[POLY1305_DIGEST_SIZE];
/* length of data to en/decrypt, without ICV */
return poly_adpad(req);
}
-static void poly_init_done(struct crypto_async_request *areq, int err)
+static void poly_setkey_done(struct crypto_async_request *areq, int err)
{
async_done_continue(areq->data, err, poly_ad);
}
-static int poly_init(struct aead_request *req)
+static int poly_setkey(struct aead_request *req)
{
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
struct poly_req *preq = &rctx->u.poly;
int err;
+ sg_init_table(preq->src, 1);
+ sg_set_buf(preq->src, rctx->key, sizeof(rctx->key));
+
ahash_request_set_callback(&preq->req, aead_request_flags(req),
- poly_init_done, req);
+ poly_setkey_done, req);
ahash_request_set_tfm(&preq->req, ctx->poly);
+ ahash_request_set_crypt(&preq->req, preq->src, NULL, sizeof(rctx->key));
- err = crypto_ahash_init(&preq->req);
+ err = crypto_ahash_update(&preq->req);
if (err)
return err;
return poly_ad(req);
}
-static int poly_genkey_continue(struct aead_request *req)
+static void poly_init_done(struct crypto_async_request *areq, int err)
{
- struct crypto_aead *aead = crypto_aead_reqtfm(req);
- struct chachapoly_ctx *ctx = crypto_aead_ctx(aead);
+ async_done_continue(areq->data, err, poly_setkey);
+}
+
+static int poly_init(struct aead_request *req)
+{
+ struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
- struct chacha_req *creq = &rctx->u.chacha;
+ struct poly_req *preq = &rctx->u.poly;
int err;
- crypto_ahash_clear_flags(ctx->poly, CRYPTO_TFM_REQ_MASK);
- crypto_ahash_set_flags(ctx->poly, crypto_aead_get_flags(aead) &
- CRYPTO_TFM_REQ_MASK);
+ ahash_request_set_callback(&preq->req, aead_request_flags(req),
+ poly_init_done, req);
+ ahash_request_set_tfm(&preq->req, ctx->poly);
- err = crypto_ahash_setkey(ctx->poly, creq->key, sizeof(creq->key));
- crypto_aead_set_flags(aead, crypto_ahash_get_flags(ctx->poly) &
- CRYPTO_TFM_RES_MASK);
+ err = crypto_ahash_init(&preq->req);
if (err)
return err;
- return poly_init(req);
+ return poly_setkey(req);
}
static void poly_genkey_done(struct crypto_async_request *areq, int err)
{
- async_done_continue(areq->data, err, poly_genkey_continue);
+ async_done_continue(areq->data, err, poly_init);
}
static int poly_genkey(struct aead_request *req)
int err;
sg_init_table(creq->src, 1);
- memset(creq->key, 0, sizeof(creq->key));
- sg_set_buf(creq->src, creq->key, sizeof(creq->key));
+ memset(rctx->key, 0, sizeof(rctx->key));
+ sg_set_buf(creq->src, rctx->key, sizeof(rctx->key));
chacha_iv(creq->iv, req, 0);
if (err)
return err;
- return poly_genkey_continue(req);
+ return poly_init(req);
}
static void chacha_encrypt_done(struct crypto_async_request *areq, int err)
/* encrypt call chain:
* - chacha_encrypt/done()
- * - poly_genkey/done/continue()
+ * - poly_genkey/done()
* - poly_init/done()
+ * - poly_setkey/done()
* - poly_ad/done()
* - poly_adpad/done()
* - poly_cipher/done()
rctx->cryptlen = req->cryptlen - POLY1305_DIGEST_SIZE;
/* decrypt call chain:
- * - poly_genkey/done/continue()
+ * - poly_genkey/done()
* - poly_init/done()
+ * - poly_setkey/done()
* - poly_ad/done()
* - poly_adpad/done()
* - poly_cipher/done()
return chachapoly_alloc(tb, "rfc7539", 12);
}
+static struct crypto_instance *rfc7539esp_alloc(struct rtattr **tb)
+{
+ return chachapoly_alloc(tb, "rfc7539esp", 8);
+}
+
static void chachapoly_free(struct crypto_instance *inst)
{
struct chachapoly_instance_ctx *ctx = crypto_instance_ctx(inst);
.module = THIS_MODULE,
};
+static struct crypto_template rfc7539esp_tmpl = {
+ .name = "rfc7539esp",
+ .alloc = rfc7539esp_alloc,
+ .free = chachapoly_free,
+ .module = THIS_MODULE,
+};
+
static int __init chacha20poly1305_module_init(void)
{
- return crypto_register_template(&rfc7539_tmpl);
+ int err;
+
+ err = crypto_register_template(&rfc7539_tmpl);
+ if (err)
+ return err;
+
+ err = crypto_register_template(&rfc7539esp_tmpl);
+ if (err)
+ crypto_unregister_template(&rfc7539_tmpl);
+
+ return err;
}
static void __exit chacha20poly1305_module_exit(void)
{
+ crypto_unregister_template(&rfc7539esp_tmpl);
crypto_unregister_template(&rfc7539_tmpl);
}
MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD");
MODULE_ALIAS_CRYPTO("chacha20poly1305");
MODULE_ALIAS_CRYPTO("rfc7539");
+MODULE_ALIAS_CRYPTO("rfc7539esp");