Commit af05b300 authored by Herbert Xu's avatar Herbert Xu

crypto: aesni - Convert top-level rfc4106 algorithm to new interface

This patch converts rfc4106-gcm-aesni to the new AEAD interface.
The low-level interface remains as is for now because we can't
touch it until cryptd itself is upgraded.

In the conversion I've also removed the duplicate copy of the
context in the top-level algorithm.  Now all processing is carried
out in the low-level __driver-gcm-aes-aesni algorithm.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 92b9876b
...@@ -52,7 +52,6 @@ struct aesni_rfc4106_gcm_ctx { ...@@ -52,7 +52,6 @@ struct aesni_rfc4106_gcm_ctx {
u8 hash_subkey[16]; u8 hash_subkey[16];
struct crypto_aes_ctx aes_key_expanded; struct crypto_aes_ctx aes_key_expanded;
u8 nonce[4]; u8 nonce[4];
struct cryptd_aead *cryptd_tfm;
}; };
struct aesni_gcm_set_hash_subkey_result { struct aesni_gcm_set_hash_subkey_result {
...@@ -790,37 +789,30 @@ static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, ...@@ -790,37 +789,30 @@ static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
#endif #endif
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
static int rfc4106_init(struct crypto_tfm *tfm) static int rfc4106_init(struct crypto_aead *aead)
{ {
struct cryptd_aead *cryptd_tfm; struct cryptd_aead *cryptd_tfm;
struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *) struct cryptd_aead **ctx = crypto_aead_ctx(aead);
PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN);
struct crypto_aead *cryptd_child;
struct aesni_rfc4106_gcm_ctx *child_ctx;
cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni",
CRYPTO_ALG_INTERNAL, CRYPTO_ALG_INTERNAL,
CRYPTO_ALG_INTERNAL); CRYPTO_ALG_INTERNAL);
if (IS_ERR(cryptd_tfm)) if (IS_ERR(cryptd_tfm))
return PTR_ERR(cryptd_tfm); return PTR_ERR(cryptd_tfm);
cryptd_child = cryptd_aead_child(cryptd_tfm); *ctx = cryptd_tfm;
child_ctx = aesni_rfc4106_gcm_ctx_get(cryptd_child); crypto_aead_set_reqsize(
memcpy(child_ctx, ctx, sizeof(*ctx)); aead,
ctx->cryptd_tfm = cryptd_tfm;
crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
sizeof(struct aead_request) + sizeof(struct aead_request) +
crypto_aead_reqsize(&cryptd_tfm->base)); crypto_aead_reqsize(&cryptd_tfm->base));
return 0; return 0;
} }
static void rfc4106_exit(struct crypto_tfm *tfm) static void rfc4106_exit(struct crypto_aead *aead)
{ {
struct aesni_rfc4106_gcm_ctx *ctx = struct cryptd_aead **ctx = crypto_aead_ctx(aead);
(struct aesni_rfc4106_gcm_ctx *)
PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); cryptd_free_aead(*ctx);
if (!IS_ERR(ctx->cryptd_tfm))
cryptd_free_aead(ctx->cryptd_tfm);
return;
} }
static void static void
...@@ -951,18 +943,10 @@ static int common_rfc4106_set_key(struct crypto_aead *aead, const u8 *key, ...@@ -951,18 +943,10 @@ static int common_rfc4106_set_key(struct crypto_aead *aead, const u8 *key,
static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
unsigned int key_len) unsigned int key_len)
{ {
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); struct cryptd_aead **ctx = crypto_aead_ctx(parent);
struct crypto_aead *child = cryptd_aead_child(ctx->cryptd_tfm); struct cryptd_aead *cryptd_tfm = *ctx;
struct aesni_rfc4106_gcm_ctx *c_ctx = aesni_rfc4106_gcm_ctx_get(child);
struct cryptd_aead *cryptd_tfm = ctx->cryptd_tfm;
int ret;
ret = crypto_aead_setkey(child, key, key_len); return crypto_aead_setkey(&cryptd_tfm->base, key, key_len);
if (!ret) {
memcpy(ctx, c_ctx, sizeof(*ctx));
ctx->cryptd_tfm = cryptd_tfm;
}
return ret;
} }
static int common_rfc4106_set_authsize(struct crypto_aead *aead, static int common_rfc4106_set_authsize(struct crypto_aead *aead,
...@@ -985,14 +969,10 @@ static int common_rfc4106_set_authsize(struct crypto_aead *aead, ...@@ -985,14 +969,10 @@ static int common_rfc4106_set_authsize(struct crypto_aead *aead,
static int rfc4106_set_authsize(struct crypto_aead *parent, static int rfc4106_set_authsize(struct crypto_aead *parent,
unsigned int authsize) unsigned int authsize)
{ {
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); struct cryptd_aead **ctx = crypto_aead_ctx(parent);
struct crypto_aead *child = cryptd_aead_child(ctx->cryptd_tfm); struct cryptd_aead *cryptd_tfm = *ctx;
int ret;
ret = crypto_aead_setauthsize(child, authsize); return crypto_aead_setauthsize(&cryptd_tfm->base, authsize);
if (!ret)
crypto_aead_crt(parent)->authsize = authsize;
return ret;
} }
static int __driver_rfc4106_encrypt(struct aead_request *req) static int __driver_rfc4106_encrypt(struct aead_request *req)
...@@ -1171,44 +1151,42 @@ static int __driver_rfc4106_decrypt(struct aead_request *req) ...@@ -1171,44 +1151,42 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
static int rfc4106_encrypt(struct aead_request *req) static int rfc4106_encrypt(struct aead_request *req)
{ {
int ret;
struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); struct cryptd_aead **ctx = crypto_aead_ctx(tfm);
struct cryptd_aead *cryptd_tfm = *ctx;
struct aead_request *subreq = aead_request_ctx(req);
if (!irq_fpu_usable()) { aead_request_set_tfm(subreq, irq_fpu_usable() ?
struct aead_request *cryptd_req = cryptd_aead_child(cryptd_tfm) :
(struct aead_request *) aead_request_ctx(req); &cryptd_tfm->base);
memcpy(cryptd_req, req, sizeof(*req)); aead_request_set_callback(subreq, req->base.flags,
aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); req->base.complete, req->base.data);
ret = crypto_aead_encrypt(cryptd_req); aead_request_set_crypt(subreq, req->src, req->dst,
} else { req->cryptlen, req->iv);
kernel_fpu_begin(); aead_request_set_ad(subreq, req->assoclen);
ret = __driver_rfc4106_encrypt(req);
kernel_fpu_end(); return crypto_aead_encrypt(subreq);
}
return ret;
} }
static int rfc4106_decrypt(struct aead_request *req) static int rfc4106_decrypt(struct aead_request *req)
{ {
int ret;
struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); struct cryptd_aead **ctx = crypto_aead_ctx(tfm);
struct cryptd_aead *cryptd_tfm = *ctx;
struct aead_request *subreq = aead_request_ctx(req);
if (!irq_fpu_usable()) { aead_request_set_tfm(subreq, irq_fpu_usable() ?
struct aead_request *cryptd_req = cryptd_aead_child(cryptd_tfm) :
(struct aead_request *) aead_request_ctx(req); &cryptd_tfm->base);
memcpy(cryptd_req, req, sizeof(*req)); aead_request_set_callback(subreq, req->base.flags,
aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); req->base.complete, req->base.data);
ret = crypto_aead_decrypt(cryptd_req); aead_request_set_crypt(subreq, req->src, req->dst,
} else { req->cryptlen, req->iv);
kernel_fpu_begin(); aead_request_set_ad(subreq, req->assoclen);
ret = __driver_rfc4106_decrypt(req);
kernel_fpu_end(); return crypto_aead_decrypt(subreq);
}
return ret;
} }
static int helper_rfc4106_encrypt(struct aead_request *req) static int helper_rfc4106_encrypt(struct aead_request *req)
...@@ -1432,30 +1410,6 @@ static struct crypto_alg aesni_algs[] = { { ...@@ -1432,30 +1410,6 @@ static struct crypto_alg aesni_algs[] = { {
.maxauthsize = 16, .maxauthsize = 16,
}, },
}, },
}, {
.cra_name = "rfc4106(gcm(aes))",
.cra_driver_name = "rfc4106-gcm-aesni",
.cra_priority = 400,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
.cra_blocksize = 1,
.cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) +
AESNI_ALIGN,
.cra_alignmask = 0,
.cra_type = &crypto_nivaead_type,
.cra_module = THIS_MODULE,
.cra_init = rfc4106_init,
.cra_exit = rfc4106_exit,
.cra_u = {
.aead = {
.setkey = rfc4106_set_key,
.setauthsize = rfc4106_set_authsize,
.encrypt = rfc4106_encrypt,
.decrypt = rfc4106_decrypt,
.geniv = "seqiv",
.ivsize = 8,
.maxauthsize = 16,
},
},
#endif #endif
#if IS_ENABLED(CONFIG_CRYPTO_PCBC) #if IS_ENABLED(CONFIG_CRYPTO_PCBC)
}, { }, {
...@@ -1570,6 +1524,30 @@ static struct crypto_alg aesni_algs[] = { { ...@@ -1570,6 +1524,30 @@ static struct crypto_alg aesni_algs[] = { {
}, },
} }; } };
#ifdef CONFIG_X86_64
static struct aead_alg aesni_aead_algs[] = { {
.init = rfc4106_init,
.exit = rfc4106_exit,
.setkey = rfc4106_set_key,
.setauthsize = rfc4106_set_authsize,
.encrypt = rfc4106_encrypt,
.decrypt = rfc4106_decrypt,
.ivsize = 8,
.maxauthsize = 16,
.base = {
.cra_name = "rfc4106(gcm(aes))",
.cra_driver_name = "rfc4106-gcm-aesni",
.cra_priority = 400,
.cra_flags = CRYPTO_ALG_ASYNC,
.cra_blocksize = 1,
.cra_ctxsize = sizeof(struct cryptd_aead *),
.cra_module = THIS_MODULE,
},
} };
#else
static struct aead_alg aesni_aead_algs[0];
#endif
static const struct x86_cpu_id aesni_cpu_id[] = { static const struct x86_cpu_id aesni_cpu_id[] = {
X86_FEATURE_MATCH(X86_FEATURE_AES), X86_FEATURE_MATCH(X86_FEATURE_AES),
...@@ -1617,11 +1595,27 @@ static int __init aesni_init(void) ...@@ -1617,11 +1595,27 @@ static int __init aesni_init(void)
if (err) if (err)
return err; return err;
return crypto_register_algs(aesni_algs, ARRAY_SIZE(aesni_algs)); err = crypto_register_algs(aesni_algs, ARRAY_SIZE(aesni_algs));
if (err)
goto fpu_exit;
err = crypto_register_aeads(aesni_aead_algs,
ARRAY_SIZE(aesni_aead_algs));
if (err)
goto unregister_algs;
return err;
unregister_algs:
crypto_unregister_algs(aesni_algs, ARRAY_SIZE(aesni_algs));
fpu_exit:
crypto_fpu_exit();
return err;
} }
static void __exit aesni_exit(void) static void __exit aesni_exit(void)
{ {
crypto_unregister_aeads(aesni_aead_algs, ARRAY_SIZE(aesni_aead_algs));
crypto_unregister_algs(aesni_algs, ARRAY_SIZE(aesni_algs)); crypto_unregister_algs(aesni_algs, ARRAY_SIZE(aesni_algs));
crypto_fpu_exit(); crypto_fpu_exit();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment