diff options
author | William Qiu <william.qiu@starfivetech.com> | 2023-06-15 14:19:31 +0300 |
---|---|---|
committer | William Qiu <william.qiu@starfivetech.com> | 2023-06-15 14:44:10 +0300 |
commit | eb1b2d41aa11ed69b7274c1d02112d1a09e5702a (patch) | |
tree | b0f77ba58b5bd54cd39479bebb4356f28cb42225 /crypto | |
parent | 01333ad19257c883c8288277260d94b173cd6502 (diff) | |
download | linux-eb1b2d41aa11ed69b7274c1d02112d1a09e5702a.tar.xz |
crypto: AF_ALG -- add sign/verify API
Add the flags for handling signature generation and signature
verification.
The af_alg helper code as well as the algif_skcipher and algif_aead code
must be changed from a boolean indicating the cipher operation to an
integer because there are now 4 different cipher operations that are
defined. Yet, the algif_aead and algif_skcipher code still only allows
encryption and decryption cipher operations.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/af_alg.c | 9 | ||||
-rw-r--r-- | crypto/algif_aead.c | 30 | ||||
-rw-r--r-- | crypto/algif_skcipher.c | 24 |
3 files changed, 42 insertions, 21 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index e893c0f6c879..a5c01cd02b5c 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -834,6 +834,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, struct af_alg_control con = {}; long copied = 0; bool enc = false; + int op = 0; bool init = false; int err = 0; @@ -844,11 +845,11 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, init = true; switch (con.op) { + case ALG_OP_VERIFY: + case ALG_OP_SIGN: case ALG_OP_ENCRYPT: - enc = true; - break; case ALG_OP_DECRYPT: - enc = false; + op = con.op; break; default: return -EINVAL; @@ -872,7 +873,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, ctx->init = true; if (init) { - ctx->enc = enc; + ctx->op = op; if (con.iv) memcpy(ctx->iv, con.iv->iv, ivsize); diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 42493b4d8ce4..403486b70ce3 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -55,7 +55,7 @@ static inline bool aead_sufficient_data(struct sock *sk) * The minimum amount of memory needed for an AEAD cipher is * the AAD and in case of decryption the tag. */ - return ctx->used >= ctx->aead_assoclen + (ctx->enc ? 0 : as); + return ctx->used >= ctx->aead_assoclen + (ctx->op ? 0 : as); } static int aead_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) @@ -71,6 +71,19 @@ static int aead_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) return af_alg_sendmsg(sock, msg, size, ivsize); } +static inline int aead_cipher_op(struct af_alg_ctx *ctx, + struct af_alg_async_req *areq) +{ + switch (ctx->op) { + case ALG_OP_ENCRYPT: + return crypto_aead_encrypt(&areq->cra_u.aead_req); + case ALG_OP_DECRYPT: + return crypto_aead_decrypt(&areq->cra_u.aead_req); + default: + return -EOPNOTSUPP; + } +} + static int crypto_aead_copy_sgl(struct crypto_sync_skcipher *null_tfm, struct scatterlist *src, struct scatterlist *dst, unsigned int len) @@ -138,7 +151,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, * buffer provides the tag which is consumed resulting in only the * plaintext without a buffer for the tag returned to the caller. */ - if (ctx->enc) + if (ctx->op) outlen = used + as; else outlen = used - as; @@ -212,7 +225,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, /* Use the RX SGL as source (and destination) for crypto op. */ rsgl_src = areq->first_rsgl.sgl.sg; - if (ctx->enc) { + if (ctx->op == ALG_OP_ENCRYPT) { /* * Encryption operation - The in-place cipher operation is * achieved by the following operation: @@ -228,7 +241,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, if (err) goto free; af_alg_pull_tsgl(sk, processed, NULL, 0); - } else { + } else if (ctx->op == ALG_OP_DECRYPT) { /* * Decryption operation - To achieve an in-place cipher * operation, the following SGL structure is used: @@ -293,8 +306,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, aead_request_set_callback(&areq->cra_u.aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, af_alg_async_cb, areq); - err = ctx->enc ? crypto_aead_encrypt(&areq->cra_u.aead_req) : - crypto_aead_decrypt(&areq->cra_u.aead_req); + err = aead_cipher_op(ctx, areq); /* AIO operation in progress */ if (err == -EINPROGRESS) @@ -307,10 +319,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, CRYPTO_TFM_REQ_MAY_SLEEP | CRYPTO_TFM_REQ_MAY_BACKLOG, crypto_req_done, &ctx->wait); - err = crypto_wait_req(ctx->enc ? - crypto_aead_encrypt(&areq->cra_u.aead_req) : - crypto_aead_decrypt(&areq->cra_u.aead_req), - &ctx->wait); + err = crypto_wait_req(aead_cipher_op(ctx, areq), &ctx->wait); } @@ -555,6 +564,7 @@ static int aead_accept_parent_nokey(void *private, struct sock *sk) INIT_LIST_HEAD(&ctx->tsgl_list); ctx->len = len; + ctx->op = 0; crypto_init_wait(&ctx->wait); ask->private = ctx; diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index ee8890ee8f33..eed6277825c1 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -47,6 +47,19 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, return af_alg_sendmsg(sock, msg, size, ivsize); } +static inline int skcipher_cipher_op(struct af_alg_ctx *ctx, + struct af_alg_async_req *areq) +{ + switch (ctx->op) { + case ALG_OP_ENCRYPT: + return crypto_skcipher_encrypt(&areq->cra_u.skcipher_req); + case ALG_OP_DECRYPT: + return crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); + default: + return -EOPNOTSUPP; + } +} + static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, int flags) { @@ -118,9 +131,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, skcipher_request_set_callback(&areq->cra_u.skcipher_req, CRYPTO_TFM_REQ_MAY_SLEEP, af_alg_async_cb, areq); - err = ctx->enc ? - crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) : - crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); + err = skcipher_cipher_op(ctx, areq); /* AIO operation in progress */ if (err == -EINPROGRESS) @@ -133,10 +144,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, CRYPTO_TFM_REQ_MAY_SLEEP | CRYPTO_TFM_REQ_MAY_BACKLOG, crypto_req_done, &ctx->wait); - err = crypto_wait_req(ctx->enc ? - crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) : - crypto_skcipher_decrypt(&areq->cra_u.skcipher_req), - &ctx->wait); + err = crypto_wait_req(skcipher_cipher_op(ctx, areq), + &ctx->wait); } @@ -341,6 +350,7 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk) INIT_LIST_HEAD(&ctx->tsgl_list); ctx->len = len; + ctx->op = 0; crypto_init_wait(&ctx->wait); ask->private = ctx; |