summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorWilliam Qiu <william.qiu@starfivetech.com>2023-06-15 14:19:31 +0300
committerWilliam Qiu <william.qiu@starfivetech.com>2023-06-15 14:44:10 +0300
commiteb1b2d41aa11ed69b7274c1d02112d1a09e5702a (patch)
treeb0f77ba58b5bd54cd39479bebb4356f28cb42225 /crypto
parent01333ad19257c883c8288277260d94b173cd6502 (diff)
downloadlinux-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.c9
-rw-r--r--crypto/algif_aead.c30
-rw-r--r--crypto/algif_skcipher.c24
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;