* [PATCH v2 01/18] X.509: Parse RSASSA-PSS style certificates
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
@ 2021-04-08 14:14 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad Varad Gautam
` (18 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:14 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
An X.509 wrapper for a RSASSA-PSS signature contains additional
signature parameters over the PKCSv.15 encoding scheme. Extend the
x509 parser to allow parsing RSASSA-PSS encoded certificates, with
the defaults taken from RFC8017.
References: https://tools.ietf.org/html/rfc8017#appendix-C
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
v2: Remove check to reject certificates with differing mgf hash and digest
hash algorithms from x509_note_pkey_algo.
crypto/asymmetric_keys/Makefile | 5 +-
crypto/asymmetric_keys/x509_cert_parser.c | 148 ++++++++++++++++++++++
crypto/asymmetric_keys/x509_rsassa.asn1 | 17 +++
include/crypto/public_key.h | 4 +
include/linux/oid_registry.h | 3 +
5 files changed, 176 insertions(+), 1 deletion(-)
create mode 100644 crypto/asymmetric_keys/x509_rsassa.asn1
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 28b91adba2aed..f79ed8e8ef8e2 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -20,15 +20,18 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
x509_key_parser-y := \
x509.asn1.o \
x509_akid.asn1.o \
+ x509_rsassa.asn1.o \
x509_cert_parser.o \
x509_public_key.o
$(obj)/x509_cert_parser.o: \
$(obj)/x509.asn1.h \
- $(obj)/x509_akid.asn1.h
+ $(obj)/x509_akid.asn1.h \
+ $(obj)/x509_rsassa.asn1.h
$(obj)/x509.asn1.o: $(obj)/x509.asn1.c $(obj)/x509.asn1.h
$(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h
+$(obj)/x509_rsassa.asn1.o: $(obj)/x509_rsassa.asn1.c $(obj)/x509_rsassa.asn1.h
#
# PKCS#8 private key handling
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 52c9b455fc7df..19cd162acdb06 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -15,6 +15,7 @@
#include "x509_parser.h"
#include "x509.asn1.h"
#include "x509_akid.asn1.h"
+#include "x509_rsassa.asn1.h"
struct x509_parse_context {
struct x509_certificate *cert; /* Certificate being constructed */
@@ -38,6 +39,8 @@ struct x509_parse_context {
const void *raw_akid; /* Raw authorityKeyId in ASN.1 */
const void *akid_raw_issuer; /* Raw directoryName in authorityKeyId */
unsigned akid_raw_issuer_size;
+ const void *raw_sig_params; /* Signature AlgorithmIdentifier.parameters */
+ unsigned raw_sig_params_size;
};
/*
@@ -101,6 +104,15 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
}
}
+ if (strcmp(ctx->cert->sig->encoding, "pss") == 0) {
+ pr_devel("rsa enc=pss hash=%s mgf=%s mgf_hash=%s salt=0x%x tf=0x%x\n",
+ ctx->cert->sig->hash_algo,
+ ctx->cert->sig->mgf,
+ ctx->cert->sig->mgf_hash_algo,
+ ctx->cert->sig->salt_length,
+ ctx->cert->sig->trailer_field);
+ }
+
ret = -ENOMEM;
cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
if (!cert->pub->key)
@@ -194,6 +206,7 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
const void *value, size_t vlen)
{
struct x509_parse_context *ctx = context;
+ int ret = 0;
pr_debug("PubKey Algo: %u\n", ctx->last_oid);
@@ -238,6 +251,35 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
case OID_SM2_with_SM3:
ctx->cert->sig->hash_algo = "sm3";
goto sm2;
+
+ case OID_rsassaPSS:
+ /* For rsassaPSS, the hash algorithm is packed as a mandatory
+ * parameter in AlgorithmIdentifier.parameters.
+ */
+ if (ctx->raw_sig_params == NULL && ctx->raw_sig_params_size != 1)
+ return -EBADMSG;
+
+ ctx->cert->sig->pkey_algo = "rsa";
+ ctx->cert->sig->encoding = "pss";
+ ctx->algo_oid = ctx->last_oid;
+ if (ctx->raw_sig_params) {
+ ret = asn1_ber_decoder(&x509_rsassa_decoder, ctx,
+ ctx->raw_sig_params,
+ ctx->raw_sig_params_size);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Fill in RSASSA-PSS-params defaults if left out. */
+ if (!ctx->cert->sig->hash_algo)
+ ctx->cert->sig->hash_algo = "sha1";
+ if (!ctx->cert->sig->mgf)
+ ctx->cert->sig->mgf = "mgf1";
+ if (!ctx->cert->sig->mgf_hash_algo)
+ ctx->cert->sig->mgf_hash_algo = "sha1";
+ ctx->cert->sig->trailer_field = 0xbc;
+
+ return 0;
}
rsa_pkcs1:
@@ -439,6 +481,18 @@ int x509_note_params(void *context, size_t hdrlen,
{
struct x509_parse_context *ctx = context;
+ if (ctx->last_oid == OID_rsassaPSS && !ctx->raw_sig_params) {
+ /* Stash AlgorithmIdentifier.parameters for RSASSA-PSS. */
+ ctx->raw_sig_params_size = vlen + hdrlen;
+ if (ctx->raw_sig_params_size) {
+ ctx->raw_sig_params = value - hdrlen;
+ } else {
+ ctx->raw_sig_params = NULL;
+ ctx->raw_sig_params_size = 1;
+ }
+ return 0;
+ }
+
/*
* AlgorithmIdentifier is used three times in the x509, we should skip
* first and ignore third, using second one which is after subject and
@@ -705,3 +759,97 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
ctx->cert->sig->auth_ids[0] = kid;
return 0;
}
+
+int x509_note_hash_algo(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+ const char **ptr = NULL;
+
+ if (ctx->last_oid != OID_rsassaPSS)
+ return -EBADMSG;
+
+ if (ctx->cert->sig->mgf)
+ ptr = &ctx->cert->sig->mgf_hash_algo;
+ else
+ ptr = &ctx->cert->sig->hash_algo;
+
+ switch (look_up_OID(value, vlen)) {
+ case OID_sha224:
+ *ptr = "sha224";
+ break;
+ case OID_sha256:
+ *ptr = "sha256";
+ break;
+ case OID_sha384:
+ *ptr = "sha384";
+ break;
+ case OID_sha512:
+ *ptr = "sha512";
+ break;
+ case OID_sha1:
+ default:
+ *ptr = "sha1";
+ break;
+ }
+
+ return 0;
+}
+
+int x509_note_hash_algo_params(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ return -EOPNOTSUPP;
+}
+
+int x509_note_mgf(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ if (ctx->last_oid != OID_rsassaPSS)
+ return -EBADMSG;
+
+ /* RFC8017 PKCS1MGFAlgorithms */
+ if (look_up_OID(value, vlen) != OID_mgf1)
+ return -EINVAL;
+
+ ctx->cert->sig->mgf = "mgf1";
+
+ return 0;
+}
+
+int x509_note_salt_length(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ if (ctx->last_oid != OID_rsassaPSS)
+ return -EBADMSG;
+
+ if (!value || !vlen || vlen > sizeof(ctx->cert->sig->salt_length))
+ return -EINVAL;
+
+ ctx->cert->sig->salt_length = (vlen == 2) ?
+ be16_to_cpu(*((__force __be16 *) value)) : *((u8 *) value);
+
+ return 0;
+}
+
+int x509_note_trailer_field(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ if (ctx->last_oid != OID_rsassaPSS)
+ return -EBADMSG;
+
+ /* trailerField 0xbc per RFC8017 A.2.3 regardless of if
+ * specified. */
+ return 0;
+}
diff --git a/crypto/asymmetric_keys/x509_rsassa.asn1 b/crypto/asymmetric_keys/x509_rsassa.asn1
new file mode 100644
index 0000000000000..e524b978856d2
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_rsassa.asn1
@@ -0,0 +1,17 @@
+-- RFC8017
+RSASSA-PSS-params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm DEFAULT,
+ maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT,
+ saltLength [2] INTEGER DEFAULT ({ x509_note_salt_length }),
+ trailerField [3] INTEGER DEFAULT ({ x509_note_trailer_field })
+}
+
+HashAlgorithm ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER ({ x509_note_hash_algo }),
+ parameters ANY OPTIONAL ({ x509_note_hash_algo_params })
+}
+
+MaskGenAlgorithm ::= SEQUENCE {
+ mgf OBJECT IDENTIFIER ({ x509_note_mgf }),
+ parameters HashAlgorithm
+}
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 47accec68cb0f..f36834c8bb139 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -46,6 +46,10 @@ struct public_key_signature {
const char *encoding;
const void *data;
unsigned int data_size;
+ const char *mgf;
+ const char *mgf_hash_algo;
+ u16 salt_length;
+ u16 trailer_field;
};
extern void public_key_signature_free(struct public_key_signature *sig);
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index 4462ed2c18cdd..c247adc8a41e4 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -113,6 +113,9 @@ enum OID {
OID_SM2_with_SM3, /* 1.2.156.10197.1.501 */
OID_sm3WithRSAEncryption, /* 1.2.156.10197.1.504 */
+ OID_mgf1, /* 1.2.840.113549.1.1.8 */
+ OID_rsassaPSS, /* 1.2.840.113549.1.1.10 */
+
OID__NR
};
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
2021-04-08 14:14 ` [PATCH v2 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper Varad Gautam
` (17 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
The existing RSA implementation supports PKCSv1.5 style signature
paddings via rsa-pkcs1pad. A lot of the functionality implemented
for rsa-pkcs1pad can be reused across other RSA padding schemes.
Rename such functions as rsapad_* before moving them out of
rsa-pkcs1pad.c.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-pkcs1pad.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 8ac3e73e8ea65..83ba7540a53ac 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -104,7 +104,7 @@ struct pkcs1pad_request {
struct akcipher_request child_req;
};
-static int pkcs1pad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
{
struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
@@ -125,7 +125,7 @@ static int pkcs1pad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
return 0;
}
-static int pkcs1pad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
{
struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
@@ -146,7 +146,7 @@ static int pkcs1pad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
return 0;
}
-static unsigned int pkcs1pad_get_max_size(struct crypto_akcipher *tfm)
+static unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
{
struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
@@ -159,8 +159,8 @@ static unsigned int pkcs1pad_get_max_size(struct crypto_akcipher *tfm)
return ctx->key_size;
}
-static void pkcs1pad_sg_set_buf(struct scatterlist *sg, void *buf, size_t len,
- struct scatterlist *next)
+static void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
+ size_t len, struct scatterlist *next)
{
int nsegs = next ? 2 : 1;
@@ -256,7 +256,7 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
req_ctx->in_buf[i] = 1 + prandom_u32_max(255);
req_ctx->in_buf[ps_end] = 0x00;
- pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
+ rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
ctx->key_size - 1 - req->src_len, req->src);
akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -357,7 +357,7 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
if (!req_ctx->out_buf)
return -ENOMEM;
- pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
+ rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
ctx->key_size, NULL);
akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -415,7 +415,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data,
digest_info->size);
- pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
+ rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
ctx->key_size - 1 - req->src_len, req->src);
akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -545,7 +545,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
if (!req_ctx->out_buf)
return -ENOMEM;
- pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
+ rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
ctx->key_size, NULL);
akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
@@ -564,7 +564,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
return err;
}
-static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm)
+static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
{
struct akcipher_instance *inst = akcipher_alg_instance(tfm);
struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
@@ -579,14 +579,14 @@ static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm)
return 0;
}
-static void pkcs1pad_exit_tfm(struct crypto_akcipher *tfm)
+static void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
{
struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
crypto_free_akcipher(ctx->child);
}
-static void pkcs1pad_free(struct akcipher_instance *inst)
+static void rsapad_akcipher_free(struct akcipher_instance *inst)
{
struct pkcs1pad_inst_ctx *ctx = akcipher_instance_ctx(inst);
struct crypto_akcipher_spawn *spawn = &ctx->spawn;
@@ -656,24 +656,24 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
- inst->alg.init = pkcs1pad_init_tfm;
- inst->alg.exit = pkcs1pad_exit_tfm;
+ inst->alg.init = rsapad_akcipher_init_tfm;
+ inst->alg.exit = rsapad_akcipher_exit_tfm;
inst->alg.encrypt = pkcs1pad_encrypt;
inst->alg.decrypt = pkcs1pad_decrypt;
inst->alg.sign = pkcs1pad_sign;
inst->alg.verify = pkcs1pad_verify;
- inst->alg.set_pub_key = pkcs1pad_set_pub_key;
- inst->alg.set_priv_key = pkcs1pad_set_priv_key;
- inst->alg.max_size = pkcs1pad_get_max_size;
+ inst->alg.set_pub_key = rsapad_set_pub_key;
+ inst->alg.set_priv_key = rsapad_set_priv_key;
+ inst->alg.max_size = rsapad_get_max_size;
inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize;
- inst->free = pkcs1pad_free;
+ inst->free = rsapad_akcipher_free;
err = akcipher_register_instance(tmpl, inst);
if (err) {
err_free_inst:
- pkcs1pad_free(inst);
+ rsapad_akcipher_free(inst);
}
return err;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
2021-04-08 14:14 ` [PATCH v2 01/18] X.509: Parse RSASSA-PSS style certificates Varad Gautam
2021-04-08 14:15 ` [PATCH v2 02/18] crypto: rsa-pkcs1pad: Rename pkcs1pad-specific functions to rsapad Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers Varad Gautam
` (16 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
which can be reused by other signature padding schemes as
rsapad_akcipher_create. This will be moved out of rsa-pkcs1pad.c to
be used across rsa-*pad implementations.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-pkcs1pad.c | 48 ++++++++++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 14 deletions(-)
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 83ba7540a53ac..849573f6b44b3 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -595,7 +595,21 @@ static void rsapad_akcipher_free(struct akcipher_instance *inst)
kfree(inst);
}
-static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
+static struct akcipher_alg pkcs1pad_alg = {
+ .init = rsapad_akcipher_init_tfm,
+ .exit = rsapad_akcipher_exit_tfm,
+
+ .encrypt = pkcs1pad_encrypt,
+ .decrypt = pkcs1pad_decrypt,
+ .sign = pkcs1pad_sign,
+ .verify = pkcs1pad_verify,
+ .set_pub_key = rsapad_set_pub_key,
+ .set_priv_key = rsapad_set_priv_key,
+ .max_size = rsapad_get_max_size
+};
+
+static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
+ struct akcipher_alg *alg)
{
u32 mask;
struct akcipher_instance *inst;
@@ -625,12 +639,12 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
hash_name = crypto_attr_alg_name(tb[2]);
if (IS_ERR(hash_name)) {
if (snprintf(inst->alg.base.cra_name,
- CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
+ CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
if (snprintf(inst->alg.base.cra_driver_name,
- CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
+ CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
rsa_alg->base.cra_driver_name) >=
CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
@@ -642,12 +656,13 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
}
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s,%s)", rsa_alg->base.cra_name,
+ "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name,
hash_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
if (snprintf(inst->alg.base.cra_driver_name,
- CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)",
+ CRYPTO_MAX_ALG_NAME, "%s(%s,%s)",
+ tmpl->name,
rsa_alg->base.cra_driver_name,
hash_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
@@ -656,16 +671,16 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
- inst->alg.init = rsapad_akcipher_init_tfm;
- inst->alg.exit = rsapad_akcipher_exit_tfm;
+ inst->alg.init = alg->init;
+ inst->alg.exit = alg->exit;
- inst->alg.encrypt = pkcs1pad_encrypt;
- inst->alg.decrypt = pkcs1pad_decrypt;
- inst->alg.sign = pkcs1pad_sign;
- inst->alg.verify = pkcs1pad_verify;
- inst->alg.set_pub_key = rsapad_set_pub_key;
- inst->alg.set_priv_key = rsapad_set_priv_key;
- inst->alg.max_size = rsapad_get_max_size;
+ inst->alg.encrypt = alg->encrypt;
+ inst->alg.decrypt = alg->decrypt;
+ inst->alg.sign = alg->sign;
+ inst->alg.verify = alg->verify;
+ inst->alg.set_pub_key = alg->set_pub_key;
+ inst->alg.set_priv_key = alg->set_priv_key;
+ inst->alg.max_size = alg->max_size;
inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize;
inst->free = rsapad_akcipher_free;
@@ -678,6 +693,11 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
return err;
}
+static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+ return rsapad_akcipher_create(tmpl, tb, &pkcs1pad_alg);
+}
+
struct crypto_template rsa_pkcs1pad_tmpl = {
.name = "pkcs1pad",
.create = pkcs1pad_create,
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (2 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 03/18] crypto: rsa-pkcs1pad: Extract pkcs1pad_create into a generic helper Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_* Varad Gautam
` (15 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
rsa-pkcs1pad operations that require using RSA primitives rely on
creating an akcipher child RSA transform and processing the results
in the operation-specific callback. Add helpers
rsapad_akcipher_setup_child and rsapad_akcipher_req_complete for req
setup and callback handling, and switch pkcs1pad operations to use
these.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-pkcs1pad.c | 106 +++++++++++++++++++-----------------------
1 file changed, 49 insertions(+), 57 deletions(-)
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 849573f6b44b3..6329c79316d24 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -171,6 +171,38 @@ static void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
sg_chain(sg, nsegs, next);
}
+typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
+static void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
+ int err, rsa_akcipher_complete_cb cb)
+{
+ struct akcipher_request *req = child_async_req->data;
+ struct crypto_async_request async_req;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ async_req.data = req->base.data;
+ async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
+ async_req.flags = child_async_req->flags;
+ req->base.complete(&async_req, cb(req, err));
+}
+
+static void rsapad_akcipher_setup_child(struct akcipher_request *req,
+ struct scatterlist *src_sg,
+ struct scatterlist *dst_sg,
+ unsigned int src_len,
+ unsigned int dst_len,
+ crypto_completion_t cb)
+{
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+
+ akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
+ akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
+ akcipher_request_set_crypt(&req_ctx->child_req, src_sg, dst_sg, src_len, dst_len);
+}
+
static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
@@ -213,17 +245,8 @@ static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
static void pkcs1pad_encrypt_sign_complete_cb(
struct crypto_async_request *child_async_req, int err)
{
- struct akcipher_request *req = child_async_req->data;
- struct crypto_async_request async_req;
-
- if (err == -EINPROGRESS)
- return;
-
- async_req.data = req->base.data;
- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
- async_req.flags = child_async_req->flags;
- req->base.complete(&async_req,
- pkcs1pad_encrypt_sign_complete(req, err));
+ rsapad_akcipher_req_complete(child_async_req, err,
+ pkcs1pad_encrypt_sign_complete);
}
static int pkcs1pad_encrypt(struct akcipher_request *req)
@@ -259,13 +282,10 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
ctx->key_size - 1 - req->src_len, req->src);
- akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
- akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
- pkcs1pad_encrypt_sign_complete_cb, req);
-
/* Reuse output buffer */
- akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
- req->dst, ctx->key_size - 1, req->dst_len);
+ rsapad_akcipher_setup_child(req, req_ctx->in_sg, req->dst,
+ ctx->key_size - 1, req->dst_len,
+ pkcs1pad_encrypt_sign_complete_cb);
err = crypto_akcipher_encrypt(&req_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
@@ -331,16 +351,7 @@ static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err)
static void pkcs1pad_decrypt_complete_cb(
struct crypto_async_request *child_async_req, int err)
{
- struct akcipher_request *req = child_async_req->data;
- struct crypto_async_request async_req;
-
- if (err == -EINPROGRESS)
- return;
-
- async_req.data = req->base.data;
- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
- async_req.flags = child_async_req->flags;
- req->base.complete(&async_req, pkcs1pad_decrypt_complete(req, err));
+ rsapad_akcipher_req_complete(child_async_req, err, pkcs1pad_decrypt_complete);
}
static int pkcs1pad_decrypt(struct akcipher_request *req)
@@ -360,14 +371,10 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
ctx->key_size, NULL);
- akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
- akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
- pkcs1pad_decrypt_complete_cb, req);
-
/* Reuse input buffer, output to a new buffer */
- akcipher_request_set_crypt(&req_ctx->child_req, req->src,
- req_ctx->out_sg, req->src_len,
- ctx->key_size);
+ rsapad_akcipher_setup_child(req, req->src, req_ctx->out_sg,
+ req->src_len, ctx->key_size,
+ pkcs1pad_decrypt_complete_cb);
err = crypto_akcipher_decrypt(&req_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
@@ -418,13 +425,10 @@ static int pkcs1pad_sign(struct akcipher_request *req)
rsapad_akcipher_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
ctx->key_size - 1 - req->src_len, req->src);
- akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
- akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
- pkcs1pad_encrypt_sign_complete_cb, req);
-
/* Reuse output buffer */
- akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
- req->dst, ctx->key_size - 1, req->dst_len);
+ rsapad_akcipher_setup_child(req, req_ctx->in_sg, req->dst,
+ ctx->key_size - 1, req->dst_len,
+ pkcs1pad_encrypt_sign_complete_cb);
err = crypto_akcipher_decrypt(&req_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
@@ -509,16 +513,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
static void pkcs1pad_verify_complete_cb(
struct crypto_async_request *child_async_req, int err)
{
- struct akcipher_request *req = child_async_req->data;
- struct crypto_async_request async_req;
-
- if (err == -EINPROGRESS)
- return;
-
- async_req.data = req->base.data;
- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
- async_req.flags = child_async_req->flags;
- req->base.complete(&async_req, pkcs1pad_verify_complete(req, err));
+ rsapad_akcipher_req_complete(child_async_req, err,
+ pkcs1pad_verify_complete);
}
/*
@@ -548,14 +544,10 @@ static int pkcs1pad_verify(struct akcipher_request *req)
rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
ctx->key_size, NULL);
- akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
- akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
- pkcs1pad_verify_complete_cb, req);
-
/* Reuse input buffer, output to a new buffer */
- akcipher_request_set_crypt(&req_ctx->child_req, req->src,
- req_ctx->out_sg, req->src_len,
- ctx->key_size);
+ rsapad_akcipher_setup_child(req, req->src, req_ctx->out_sg,
+ req->src_len, ctx->key_size,
+ pkcs1pad_verify_complete_cb);
err = crypto_akcipher_encrypt(&req_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_*
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (3 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 04/18] crypto: rsa-pkcs1pad: Pull out child req processing code into helpers Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 06/18] crypto: rsa: Start moving RSA common code to rsa-common Varad Gautam
` (14 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Use generic naming to share with other padding scheme implementations.
These will be moved out of rsa-pkcs1pad.c.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-pkcs1pad.c | 62 +++++++++++++++++++++----------------------
1 file changed, 31 insertions(+), 31 deletions(-)
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 6329c79316d24..e76fc98a537a4 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -88,17 +88,17 @@ static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
return NULL;
}
-struct pkcs1pad_ctx {
+struct rsapad_tfm_ctx {
struct crypto_akcipher *child;
unsigned int key_size;
};
-struct pkcs1pad_inst_ctx {
+struct rsapad_inst_ctx {
struct crypto_akcipher_spawn spawn;
const struct rsa_asn1_template *digest_info;
};
-struct pkcs1pad_request {
+struct rsapad_akciper_req_ctx {
struct scatterlist in_sg[2], out_sg[1];
uint8_t *in_buf, *out_buf;
struct akcipher_request child_req;
@@ -107,7 +107,7 @@ struct pkcs1pad_request {
static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
{
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
int err;
ctx->key_size = 0;
@@ -128,7 +128,7 @@ static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
{
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
int err;
ctx->key_size = 0;
@@ -148,7 +148,7 @@ static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
static unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
{
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
/*
* The maximum destination buffer size for the encrypt/sign operations
@@ -195,8 +195,8 @@ static void rsapad_akcipher_setup_child(struct akcipher_request *req,
crypto_completion_t cb)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
@@ -206,8 +206,8 @@ static void rsapad_akcipher_setup_child(struct akcipher_request *req,
static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
unsigned int pad_len;
unsigned int len;
u8 *out_buf;
@@ -252,8 +252,8 @@ static void pkcs1pad_encrypt_sign_complete_cb(
static int pkcs1pad_encrypt(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
int err;
unsigned int i, ps_end;
@@ -297,8 +297,8 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
unsigned int dst_len;
unsigned int pos;
u8 *out_buf;
@@ -357,8 +357,8 @@ static void pkcs1pad_decrypt_complete_cb(
static int pkcs1pad_decrypt(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
int err;
if (!ctx->key_size || req->src_len != ctx->key_size)
@@ -386,10 +386,10 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
static int pkcs1pad_sign(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
struct akcipher_instance *inst = akcipher_alg_instance(tfm);
- struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+ struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
const struct rsa_asn1_template *digest_info = ictx->digest_info;
int err;
unsigned int ps_end, digest_size = 0;
@@ -440,10 +440,10 @@ static int pkcs1pad_sign(struct akcipher_request *req)
static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
struct akcipher_instance *inst = akcipher_alg_instance(tfm);
- struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+ struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
const struct rsa_asn1_template *digest_info = ictx->digest_info;
unsigned int dst_len;
unsigned int pos;
@@ -528,8 +528,8 @@ static void pkcs1pad_verify_complete_cb(
static int pkcs1pad_verify(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
int err;
if (WARN_ON(req->dst) ||
@@ -559,8 +559,8 @@ static int pkcs1pad_verify(struct akcipher_request *req)
static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
{
struct akcipher_instance *inst = akcipher_alg_instance(tfm);
- struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
struct crypto_akcipher *child_tfm;
child_tfm = crypto_spawn_akcipher(&ictx->spawn);
@@ -573,14 +573,14 @@ static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
static void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
{
- struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
crypto_free_akcipher(ctx->child);
}
static void rsapad_akcipher_free(struct akcipher_instance *inst)
{
- struct pkcs1pad_inst_ctx *ctx = akcipher_instance_ctx(inst);
+ struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst);
struct crypto_akcipher_spawn *spawn = &ctx->spawn;
crypto_drop_akcipher(spawn);
@@ -605,7 +605,7 @@ static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **
{
u32 mask;
struct akcipher_instance *inst;
- struct pkcs1pad_inst_ctx *ctx;
+ struct rsapad_inst_ctx *ctx;
struct akcipher_alg *rsa_alg;
const char *hash_name;
int err;
@@ -661,7 +661,7 @@ static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **
}
inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
- inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
+ inst->alg.base.cra_ctxsize = sizeof(struct rsapad_tfm_ctx);
inst->alg.init = alg->init;
inst->alg.exit = alg->exit;
@@ -673,7 +673,7 @@ static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **
inst->alg.set_pub_key = alg->set_pub_key;
inst->alg.set_priv_key = alg->set_priv_key;
inst->alg.max_size = alg->max_size;
- inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize;
+ inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
inst->free = rsapad_akcipher_free;
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 06/18] crypto: rsa: Start moving RSA common code to rsa-common
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (4 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 05/18] crypto: rsa-pkcs1pad: Rename pkcs1pad_* structs to rsapad_* Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 07/18] crypto: rsa: Move more " Varad Gautam
` (13 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Move out helpers from rsa-pkcs1pad.c which will be shared across
rsa-*pad implementations.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/Makefile | 1 +
crypto/rsa-common.c | 76 ++++++++++++++++++++++
crypto/rsa-pkcs1pad.c | 97 +---------------------------
include/crypto/internal/rsa-common.h | 37 +++++++++++
4 files changed, 115 insertions(+), 96 deletions(-)
create mode 100644 crypto/rsa-common.c
create mode 100644 include/crypto/internal/rsa-common.h
diff --git a/crypto/Makefile b/crypto/Makefile
index cf23affb16780..57a85b2b3429b 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -39,6 +39,7 @@ rsa_generic-y := rsapubkey.asn1.o
rsa_generic-y += rsaprivkey.asn1.o
rsa_generic-y += rsa.o
rsa_generic-y += rsa_helper.o
+rsa_generic-y += rsa-common.o
rsa_generic-y += rsa-pkcs1pad.o
obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
new file mode 100644
index 0000000000000..60073c56e3748
--- /dev/null
+++ b/crypto/rsa-common.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2015 Intel Corporation
+ * Copyright (C) 2021 SUSE
+ *
+ */
+
+#include <crypto/internal/rsa-common.h>
+
+/*
+ * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
+ */
+static const u8 rsa_digest_info_md5[] = {
+ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
+ 0x05, 0x00, 0x04, 0x10
+};
+
+static const u8 rsa_digest_info_sha1[] = {
+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+ 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+ 0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 rsa_digest_info_rmd160[] = {
+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+ 0x2b, 0x24, 0x03, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 rsa_digest_info_sha224[] = {
+ 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
+ 0x05, 0x00, 0x04, 0x1c
+};
+
+static const u8 rsa_digest_info_sha256[] = {
+ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x20
+};
+
+static const u8 rsa_digest_info_sha384[] = {
+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
+ 0x05, 0x00, 0x04, 0x30
+};
+
+static const u8 rsa_digest_info_sha512[] = {
+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+ 0x05, 0x00, 0x04, 0x40
+};
+
+static const struct rsa_asn1_template rsa_asn1_templates[] = {
+#define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) }
+ _(md5),
+ _(sha1),
+ _(rmd160),
+ _(sha256),
+ _(sha384),
+ _(sha512),
+ _(sha224),
+ { NULL }
+#undef _
+};
+
+const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
+{
+ const struct rsa_asn1_template *p;
+
+ for (p = rsa_asn1_templates; p->name; p++)
+ if (strcmp(name, p->name) == 0)
+ return p;
+ return NULL;
+}
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index e76fc98a537a4..ffb7220b3d10a 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -5,104 +5,9 @@
* Copyright (c) 2015 Intel Corporation
*/
-#include <crypto/algapi.h>
-#include <crypto/akcipher.h>
-#include <crypto/internal/akcipher.h>
-#include <crypto/internal/rsa.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
+#include <crypto/internal/rsa-common.h>
#include <linux/module.h>
#include <linux/random.h>
-#include <linux/scatterlist.h>
-
-/*
- * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
- */
-static const u8 rsa_digest_info_md5[] = {
- 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
- 0x05, 0x00, 0x04, 0x10
-};
-
-static const u8 rsa_digest_info_sha1[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2b, 0x0e, 0x03, 0x02, 0x1a,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 rsa_digest_info_rmd160[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2b, 0x24, 0x03, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 rsa_digest_info_sha224[] = {
- 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
- 0x05, 0x00, 0x04, 0x1c
-};
-
-static const u8 rsa_digest_info_sha256[] = {
- 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x20
-};
-
-static const u8 rsa_digest_info_sha384[] = {
- 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
- 0x05, 0x00, 0x04, 0x30
-};
-
-static const u8 rsa_digest_info_sha512[] = {
- 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
- 0x05, 0x00, 0x04, 0x40
-};
-
-static const struct rsa_asn1_template {
- const char *name;
- const u8 *data;
- size_t size;
-} rsa_asn1_templates[] = {
-#define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) }
- _(md5),
- _(sha1),
- _(rmd160),
- _(sha256),
- _(sha384),
- _(sha512),
- _(sha224),
- { NULL }
-#undef _
-};
-
-static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
-{
- const struct rsa_asn1_template *p;
-
- for (p = rsa_asn1_templates; p->name; p++)
- if (strcmp(name, p->name) == 0)
- return p;
- return NULL;
-}
-
-struct rsapad_tfm_ctx {
- struct crypto_akcipher *child;
- unsigned int key_size;
-};
-
-struct rsapad_inst_ctx {
- struct crypto_akcipher_spawn spawn;
- const struct rsa_asn1_template *digest_info;
-};
-
-struct rsapad_akciper_req_ctx {
- struct scatterlist in_sg[2], out_sg[1];
- uint8_t *in_buf, *out_buf;
- struct akcipher_request child_req;
-};
static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
new file mode 100644
index 0000000000000..ecdce0cdafaa3
--- /dev/null
+++ b/include/crypto/internal/rsa-common.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2015 Intel Corporation
+ * Copyright (C) 2021 SUSE
+ *
+ */
+#ifndef _RSA_COMMON_
+#define _RSA_COMMON_
+
+#include <crypto/algapi.h>
+#include <crypto/internal/akcipher.h>
+#include <linux/scatterlist.h>
+
+struct rsa_asn1_template {
+ const char *name;
+ const u8 *data;
+ size_t size;
+};
+const struct rsa_asn1_template *rsa_lookup_asn1(const char *name);
+
+struct rsapad_tfm_ctx {
+ struct crypto_akcipher *child;
+ unsigned int key_size;
+};
+
+struct rsapad_inst_ctx {
+ struct crypto_akcipher_spawn spawn;
+ const struct rsa_asn1_template *digest_info;
+};
+
+struct rsapad_akciper_req_ctx {
+ struct scatterlist in_sg[2], out_sg[1];
+ uint8_t *in_buf, *out_buf;
+ struct akcipher_request child_req;
+};
+
+#endif
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 07/18] crypto: rsa: Move more common code to rsa-common
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (5 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 06/18] crypto: rsa: Start moving RSA common code to rsa-common Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback " Varad Gautam
` (12 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Move helpers for setting public/private keys, RSA akcipher
instance setup, keysize querying etc. to rsa-common.c.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-common.c | 183 +++++++++++++++++++++++++++
crypto/rsa-pkcs1pad.c | 183 ---------------------------
include/crypto/internal/rsa-common.h | 13 ++
3 files changed, 196 insertions(+), 183 deletions(-)
diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
index 60073c56e3748..d70d7d405165f 100644
--- a/crypto/rsa-common.c
+++ b/crypto/rsa-common.c
@@ -74,3 +74,186 @@ const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
return p;
return NULL;
}
+
+int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+ unsigned int keylen)
+{
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ int err;
+
+ ctx->key_size = 0;
+
+ err = crypto_akcipher_set_pub_key(ctx->child, key, keylen);
+ if (err)
+ return err;
+
+ /* Find out new modulus size from rsa implementation */
+ err = crypto_akcipher_maxsize(ctx->child);
+ if (err > PAGE_SIZE)
+ return -EOPNOTSUPP;
+
+ ctx->key_size = err;
+ return 0;
+}
+
+int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+ unsigned int keylen)
+{
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ int err;
+
+ ctx->key_size = 0;
+
+ err = crypto_akcipher_set_priv_key(ctx->child, key, keylen);
+ if (err)
+ return err;
+
+ /* Find out new modulus size from rsa implementation */
+ err = crypto_akcipher_maxsize(ctx->child);
+ if (err > PAGE_SIZE)
+ return -EOPNOTSUPP;
+
+ ctx->key_size = err;
+ return 0;
+}
+
+unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
+{
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ /*
+ * The maximum destination buffer size for the encrypt/sign operations
+ * will be the same as for RSA, even though it's smaller for
+ * decrypt/verify.
+ */
+
+ return ctx->key_size;
+}
+
+void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
+ size_t len, struct scatterlist *next)
+{
+ int nsegs = next ? 2 : 1;
+
+ sg_init_table(sg, nsegs);
+ sg_set_buf(sg, buf, len);
+
+ if (next)
+ sg_chain(sg, nsegs, next);
+}
+
+int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
+{
+ struct akcipher_instance *inst = akcipher_alg_instance(tfm);
+ struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct crypto_akcipher *child_tfm;
+
+ child_tfm = crypto_spawn_akcipher(&ictx->spawn);
+ if (IS_ERR(child_tfm))
+ return PTR_ERR(child_tfm);
+
+ ctx->child = child_tfm;
+ return 0;
+}
+
+void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
+{
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ crypto_free_akcipher(ctx->child);
+}
+
+void rsapad_akcipher_free(struct akcipher_instance *inst)
+{
+ struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst);
+ struct crypto_akcipher_spawn *spawn = &ctx->spawn;
+
+ crypto_drop_akcipher(spawn);
+ kfree(inst);
+}
+
+int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
+ struct akcipher_alg *alg)
+{
+ u32 mask;
+ struct akcipher_instance *inst;
+ struct rsapad_inst_ctx *ctx;
+ struct akcipher_alg *rsa_alg;
+ const char *hash_name;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask);
+ if (err)
+ return err;
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ ctx = akcipher_instance_ctx(inst);
+
+ err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst),
+ crypto_attr_alg_name(tb[1]), 0, mask);
+ if (err)
+ goto err_free_inst;
+
+ rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
+
+ err = -ENAMETOOLONG;
+ hash_name = crypto_attr_alg_name(tb[2]);
+ if (IS_ERR(hash_name)) {
+ if (snprintf(inst->alg.base.cra_name,
+ CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
+ rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_free_inst;
+
+ if (snprintf(inst->alg.base.cra_driver_name,
+ CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
+ rsa_alg->base.cra_driver_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto err_free_inst;
+ } else {
+ ctx->digest_info = rsa_lookup_asn1(hash_name);
+ if (!ctx->digest_info) {
+ err = -EINVAL;
+ goto err_free_inst;
+ }
+
+ if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
+ "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name,
+ hash_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_free_inst;
+
+ if (snprintf(inst->alg.base.cra_driver_name,
+ CRYPTO_MAX_ALG_NAME, "%s(%s,%s)",
+ tmpl->name,
+ rsa_alg->base.cra_driver_name,
+ hash_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_free_inst;
+ }
+
+ inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
+ inst->alg.base.cra_ctxsize = sizeof(struct rsapad_tfm_ctx);
+
+ inst->alg.init = alg->init;
+ inst->alg.exit = alg->exit;
+
+ inst->alg.encrypt = alg->encrypt;
+ inst->alg.decrypt = alg->decrypt;
+ inst->alg.sign = alg->sign;
+ inst->alg.verify = alg->verify;
+ inst->alg.set_pub_key = alg->set_pub_key;
+ inst->alg.set_priv_key = alg->set_priv_key;
+ inst->alg.max_size = alg->max_size;
+ inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
+
+ inst->free = rsapad_akcipher_free;
+
+ err = akcipher_register_instance(tmpl, inst);
+ if (err) {
+err_free_inst:
+ rsapad_akcipher_free(inst);
+ }
+ return err;
+}
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index ffb7220b3d10a..30b0193b7352a 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -9,73 +9,6 @@
#include <linux/module.h>
#include <linux/random.h>
-static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
- unsigned int keylen)
-{
- struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
- int err;
-
- ctx->key_size = 0;
-
- err = crypto_akcipher_set_pub_key(ctx->child, key, keylen);
- if (err)
- return err;
-
- /* Find out new modulus size from rsa implementation */
- err = crypto_akcipher_maxsize(ctx->child);
- if (err > PAGE_SIZE)
- return -ENOTSUPP;
-
- ctx->key_size = err;
- return 0;
-}
-
-static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
- unsigned int keylen)
-{
- struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
- int err;
-
- ctx->key_size = 0;
-
- err = crypto_akcipher_set_priv_key(ctx->child, key, keylen);
- if (err)
- return err;
-
- /* Find out new modulus size from rsa implementation */
- err = crypto_akcipher_maxsize(ctx->child);
- if (err > PAGE_SIZE)
- return -ENOTSUPP;
-
- ctx->key_size = err;
- return 0;
-}
-
-static unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm)
-{
- struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
-
- /*
- * The maximum destination buffer size for the encrypt/sign operations
- * will be the same as for RSA, even though it's smaller for
- * decrypt/verify.
- */
-
- return ctx->key_size;
-}
-
-static void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
- size_t len, struct scatterlist *next)
-{
- int nsegs = next ? 2 : 1;
-
- sg_init_table(sg, nsegs);
- sg_set_buf(sg, buf, len);
-
- if (next)
- sg_chain(sg, nsegs, next);
-}
-
typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
static void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
int err, rsa_akcipher_complete_cb cb)
@@ -461,37 +394,6 @@ static int pkcs1pad_verify(struct akcipher_request *req)
return err;
}
-static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm)
-{
- struct akcipher_instance *inst = akcipher_alg_instance(tfm);
- struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
- struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct crypto_akcipher *child_tfm;
-
- child_tfm = crypto_spawn_akcipher(&ictx->spawn);
- if (IS_ERR(child_tfm))
- return PTR_ERR(child_tfm);
-
- ctx->child = child_tfm;
- return 0;
-}
-
-static void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm)
-{
- struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
-
- crypto_free_akcipher(ctx->child);
-}
-
-static void rsapad_akcipher_free(struct akcipher_instance *inst)
-{
- struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst);
- struct crypto_akcipher_spawn *spawn = &ctx->spawn;
-
- crypto_drop_akcipher(spawn);
- kfree(inst);
-}
-
static struct akcipher_alg pkcs1pad_alg = {
.init = rsapad_akcipher_init_tfm,
.exit = rsapad_akcipher_exit_tfm,
@@ -505,91 +407,6 @@ static struct akcipher_alg pkcs1pad_alg = {
.max_size = rsapad_get_max_size
};
-static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
- struct akcipher_alg *alg)
-{
- u32 mask;
- struct akcipher_instance *inst;
- struct rsapad_inst_ctx *ctx;
- struct akcipher_alg *rsa_alg;
- const char *hash_name;
- int err;
-
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask);
- if (err)
- return err;
-
- inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
- if (!inst)
- return -ENOMEM;
-
- ctx = akcipher_instance_ctx(inst);
-
- err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst),
- crypto_attr_alg_name(tb[1]), 0, mask);
- if (err)
- goto err_free_inst;
-
- rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
-
- err = -ENAMETOOLONG;
- hash_name = crypto_attr_alg_name(tb[2]);
- if (IS_ERR(hash_name)) {
- if (snprintf(inst->alg.base.cra_name,
- CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
- rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
- goto err_free_inst;
-
- if (snprintf(inst->alg.base.cra_driver_name,
- CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name,
- rsa_alg->base.cra_driver_name) >=
- CRYPTO_MAX_ALG_NAME)
- goto err_free_inst;
- } else {
- ctx->digest_info = rsa_lookup_asn1(hash_name);
- if (!ctx->digest_info) {
- err = -EINVAL;
- goto err_free_inst;
- }
-
- if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
- "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name,
- hash_name) >= CRYPTO_MAX_ALG_NAME)
- goto err_free_inst;
-
- if (snprintf(inst->alg.base.cra_driver_name,
- CRYPTO_MAX_ALG_NAME, "%s(%s,%s)",
- tmpl->name,
- rsa_alg->base.cra_driver_name,
- hash_name) >= CRYPTO_MAX_ALG_NAME)
- goto err_free_inst;
- }
-
- inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
- inst->alg.base.cra_ctxsize = sizeof(struct rsapad_tfm_ctx);
-
- inst->alg.init = alg->init;
- inst->alg.exit = alg->exit;
-
- inst->alg.encrypt = alg->encrypt;
- inst->alg.decrypt = alg->decrypt;
- inst->alg.sign = alg->sign;
- inst->alg.verify = alg->verify;
- inst->alg.set_pub_key = alg->set_pub_key;
- inst->alg.set_priv_key = alg->set_priv_key;
- inst->alg.max_size = alg->max_size;
- inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
-
- inst->free = rsapad_akcipher_free;
-
- err = akcipher_register_instance(tmpl, inst);
- if (err) {
-err_free_inst:
- rsapad_akcipher_free(inst);
- }
- return err;
-}
-
static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
{
return rsapad_akcipher_create(tmpl, tb, &pkcs1pad_alg);
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
index ecdce0cdafaa3..a6f20cce610ab 100644
--- a/include/crypto/internal/rsa-common.h
+++ b/include/crypto/internal/rsa-common.h
@@ -34,4 +34,17 @@ struct rsapad_akciper_req_ctx {
struct akcipher_request child_req;
};
+int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+ unsigned int keylen);
+int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+ unsigned int keylen);
+unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm);
+void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf,
+ size_t len, struct scatterlist *next);
+int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm);
+void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm);
+void rsapad_akcipher_free(struct akcipher_instance *inst);
+int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
+ struct akcipher_alg *alg);
+
#endif
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback to rsa-common
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (6 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 07/18] crypto: rsa: Move more " Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 09/18] crypto: Extend akcipher API to pass signature parameters Varad Gautam
` (11 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Pull out more common code from rsa-pkcs1pad into rsa-common.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-common.c | 31 +++++++++++++++++++++++++++
crypto/rsa-pkcs1pad.c | 32 ----------------------------
include/crypto/internal/rsa-common.h | 9 ++++++++
3 files changed, 40 insertions(+), 32 deletions(-)
diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
index d70d7d405165f..6ed258a782875 100644
--- a/crypto/rsa-common.c
+++ b/crypto/rsa-common.c
@@ -75,6 +75,37 @@ const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
return NULL;
}
+void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
+ int err, rsa_akcipher_complete_cb cb)
+{
+ struct akcipher_request *req = child_async_req->data;
+ struct crypto_async_request async_req;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ async_req.data = req->base.data;
+ async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
+ async_req.flags = child_async_req->flags;
+ req->base.complete(&async_req, cb(req, err));
+}
+
+void rsapad_akcipher_setup_child(struct akcipher_request *req,
+ struct scatterlist *src_sg,
+ struct scatterlist *dst_sg,
+ unsigned int src_len,
+ unsigned int dst_len,
+ crypto_completion_t cb)
+{
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
+
+ akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
+ akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
+ akcipher_request_set_crypt(&req_ctx->child_req, src_sg, dst_sg, src_len, dst_len);
+}
+
int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
{
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 30b0193b7352a..6fa207732fcbe 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -9,38 +9,6 @@
#include <linux/module.h>
#include <linux/random.h>
-typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
-static void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
- int err, rsa_akcipher_complete_cb cb)
-{
- struct akcipher_request *req = child_async_req->data;
- struct crypto_async_request async_req;
-
- if (err == -EINPROGRESS)
- return;
-
- async_req.data = req->base.data;
- async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
- async_req.flags = child_async_req->flags;
- req->base.complete(&async_req, cb(req, err));
-}
-
-static void rsapad_akcipher_setup_child(struct akcipher_request *req,
- struct scatterlist *src_sg,
- struct scatterlist *dst_sg,
- unsigned int src_len,
- unsigned int dst_len,
- crypto_completion_t cb)
-{
- struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
- struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
-
- akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
- akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, cb, req);
- akcipher_request_set_crypt(&req_ctx->child_req, src_sg, dst_sg, src_len, dst_len);
-}
-
static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
index a6f20cce610ab..4fa3cf5a989cc 100644
--- a/include/crypto/internal/rsa-common.h
+++ b/include/crypto/internal/rsa-common.h
@@ -34,6 +34,15 @@ struct rsapad_akciper_req_ctx {
struct akcipher_request child_req;
};
+typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int);
+void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req,
+ int err, rsa_akcipher_complete_cb cb);
+void rsapad_akcipher_setup_child(struct akcipher_request *req,
+ struct scatterlist *src_sg,
+ struct scatterlist *dst_sg,
+ unsigned int src_len,
+ unsigned int dst_len,
+ crypto_completion_t cb);
int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen);
int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 09/18] crypto: Extend akcipher API to pass signature parameters
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (7 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 08/18] crypto: rsa: Move rsapad_akcipher_setup_child and callback " Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h Varad Gautam
` (10 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
For certain signature encoding schemes (eg. RSASSA-PSS), the
verify/sign operation behavior depends on information contained in
the signature blob. Allow passing this down to the crypto_template by
introducing a crypto_akcipher_set_sig_params() call.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-common.c | 1 +
include/crypto/akcipher.h | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c
index 6ed258a782875..f80cdfcc1f9ee 100644
--- a/crypto/rsa-common.c
+++ b/crypto/rsa-common.c
@@ -277,6 +277,7 @@ int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb,
inst->alg.set_pub_key = alg->set_pub_key;
inst->alg.set_priv_key = alg->set_priv_key;
inst->alg.max_size = alg->max_size;
+ inst->alg.set_sig_params = alg->set_sig_params;
inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize;
inst->free = rsapad_akcipher_free;
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index 1d3aa252cabaf..a0e8720294293 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -101,6 +101,8 @@ struct akcipher_alg {
unsigned int (*max_size)(struct crypto_akcipher *tfm);
int (*init)(struct crypto_akcipher *tfm);
void (*exit)(struct crypto_akcipher *tfm);
+ int (*set_sig_params)(struct crypto_akcipher *tfm, const void *sig,
+ unsigned int sig_len);
unsigned int reqsize;
struct crypto_alg base;
@@ -413,4 +415,28 @@ static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,
return alg->set_priv_key(tfm, key, keylen);
}
+
+/**
+ * crypto_akcipher_set_sig_params() - Invoke set sig params operation
+ *
+ * Use this if the verification/signing operation behavior depends on
+ * parameters contained in the signature.
+ *
+ * @tfm: tfm handle
+ * @sig: ptr to a struct public_key_signature to extract info from
+ * @siglen: Length of sig - should be unnecessary if you pass the struct.
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_set_sig_params(struct crypto_akcipher *tfm,
+ const void *sig,
+ unsigned int siglen)
+{
+ struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+ if (alg->set_sig_params)
+ return alg->set_sig_params(tfm, sig, siglen);
+ else
+ return -EOPNOTSUPP;
+}
#endif
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (8 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 09/18] crypto: Extend akcipher API to pass signature parameters Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 11/18] crypto: Scaffolding for RSA-PSS signature style Varad Gautam
` (9 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
The RSASSA-PSS signature scheme requires knowing the RSA modulus size
in bits. The rsa akcipher_alg max_size call is insufficient for this,
as the returned keysize is rounded up to the next byte.
Since the RSA modulus is stored as an MPI accessible via
struct rsa_mpi_key, move the struct definition to rsa.h to help RSA
sub-implementations query the MPI values.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa.c | 6 ------
include/crypto/internal/rsa.h | 7 +++++++
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 4cdbec95d0779..5c4eece5b8028 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -12,12 +12,6 @@
#include <crypto/akcipher.h>
#include <crypto/algapi.h>
-struct rsa_mpi_key {
- MPI n;
- MPI e;
- MPI d;
-};
-
/*
* RSAEP function [RFC3447 sec 5.1.1]
* c = m^e mod n;
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index e870133f4b775..e73c61f788e68 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -7,6 +7,7 @@
*/
#ifndef _RSA_HELPER_
#define _RSA_HELPER_
+#include <linux/mpi.h>
#include <linux/types.h>
/**
@@ -53,5 +54,11 @@ int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len);
+struct rsa_mpi_key {
+ MPI n;
+ MPI e;
+ MPI d;
+};
+
extern struct crypto_template rsa_pkcs1pad_tmpl;
#endif
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 11/18] crypto: Scaffolding for RSA-PSS signature style
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (9 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 10/18] crypto: rsa: Move struct rsa_mpi_key definition to rsa.h Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers Varad Gautam
` (8 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Add a crypto_template for rsa-psspad, hidden behind
CONFIG_CRYPTO_RSASSA_PSS. Set the sign/verify/encrypt/decrypt
operations to return -EOPNOTSUPP, to be implemented in the future
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/Kconfig | 6 ++++++
crypto/Makefile | 1 +
crypto/rsa-psspad.c | 39 +++++++++++++++++++++++++++++++++++
crypto/rsa.c | 20 +++++++++++++++---
include/crypto/internal/rsa.h | 3 +++
5 files changed, 66 insertions(+), 3 deletions(-)
create mode 100644 crypto/rsa-psspad.c
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 5809cc198fa7c..3aedb40aa08f1 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -224,6 +224,12 @@ config CRYPTO_RSA
help
Generic implementation of the RSA public key algorithm.
+config CRYPTO_RSASSA_PSS
+ bool "RSASSA-PSS algorithm"
+ select CRYPTO_RSA
+ help
+ RSASSA-PSS signature verification scheme.
+
config CRYPTO_DH
tristate "Diffie-Hellman algorithm"
select CRYPTO_KPP
diff --git a/crypto/Makefile b/crypto/Makefile
index 57a85b2b3429b..88be24b9bcb24 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -42,6 +42,7 @@ rsa_generic-y += rsa_helper.o
rsa_generic-y += rsa-common.o
rsa_generic-y += rsa-pkcs1pad.o
obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+obj-$(CONFIG_CRYPTO_RSASSA_PSS) += rsa-psspad.o
$(obj)/sm2signature.asn1.o: $(obj)/sm2signature.asn1.c $(obj)/sm2signature.asn1.h
$(obj)/sm2.o: $(obj)/sm2signature.asn1.h
diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
new file mode 100644
index 0000000000000..0e5422b05c081
--- /dev/null
+++ b/crypto/rsa-psspad.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RSASSA-PSS signature scheme.
+ *
+ * Copyright (C) 2021, SUSE
+ * Authors: Varad Gautam <varad.gautam@suse.com>
+ */
+
+#include <crypto/internal/akcipher.h>
+#include <crypto/internal/rsa-common.h>
+
+static int psspad_s_v_e_d(struct akcipher_request *req)
+{
+ return -EOPNOTSUPP;
+}
+
+static struct akcipher_alg psspad_alg = {
+ .init = rsapad_akcipher_init_tfm,
+ .exit = rsapad_akcipher_exit_tfm,
+
+ .encrypt = psspad_s_v_e_d,
+ .decrypt = psspad_s_v_e_d,
+ .sign = psspad_s_v_e_d,
+ .verify = psspad_s_v_e_d,
+ .set_pub_key = rsapad_set_pub_key,
+ .set_priv_key = rsapad_set_priv_key,
+ .max_size = rsapad_get_max_size
+};
+
+static int psspad_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+ return rsapad_akcipher_create(tmpl, tb, &psspad_alg);
+}
+
+struct crypto_template rsa_psspad_tmpl = {
+ .name = "psspad",
+ .create = psspad_create,
+ .module = THIS_MODULE,
+};
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 5c4eece5b8028..de4ad34f9cd95 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -258,17 +258,31 @@ static int rsa_init(void)
return err;
err = crypto_register_template(&rsa_pkcs1pad_tmpl);
+ if (err)
+ goto out_err;
+
+#ifdef CONFIG_CRYPTO_RSASSA_PSS
+ err = crypto_register_template(&rsa_psspad_tmpl);
if (err) {
- crypto_unregister_akcipher(&rsa);
- return err;
+ crypto_unregister_template(&rsa_pkcs1pad_tmpl);
+ goto out_err;
}
+#endif
- return 0;
+ goto out;
+
+out_err:
+ crypto_unregister_akcipher(&rsa);
+out:
+ return err;
}
static void rsa_exit(void)
{
crypto_unregister_template(&rsa_pkcs1pad_tmpl);
+#ifdef CONFIG_CRYPTO_RSASSA_PSS
+ crypto_unregister_template(&rsa_psspad_tmpl);
+#endif
crypto_unregister_akcipher(&rsa);
}
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index e73c61f788e68..4c168ea2f050a 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -61,4 +61,7 @@ struct rsa_mpi_key {
};
extern struct crypto_template rsa_pkcs1pad_tmpl;
+#ifdef CONFIG_CRYPTO_RSASSA_PSS
+extern struct crypto_template rsa_psspad_tmpl;
+#endif /* CONFIG_CRYPTO_RSASSA_PSS */
#endif
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (10 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 11/18] crypto: Scaffolding for RSA-PSS signature style Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 13/18] crypto: rsa-psspad: Get signature parameters from a given signature Varad Gautam
` (7 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
RSASSA-PSS verify operation needs to compute digests for its
Mask Generation Function (MGF1), and for digest comparison.
Add helpers to populate a crypto_shash and desc for use in both cases.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-psspad.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index 0e5422b05c081..855e82ca071a7 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -6,9 +6,33 @@
* Authors: Varad Gautam <varad.gautam@suse.com>
*/
+#include <crypto/hash.h>
#include <crypto/internal/akcipher.h>
#include <crypto/internal/rsa-common.h>
+static int psspad_setup_shash(struct crypto_shash **hash_tfm, struct shash_desc **desc,
+ const char *hash_algo)
+{
+ *hash_tfm = crypto_alloc_shash(hash_algo, 0, 0);
+ if (IS_ERR(*hash_tfm))
+ return PTR_ERR(*hash_tfm);
+
+ *desc = kzalloc(crypto_shash_descsize(*hash_tfm) + sizeof(**desc),
+ GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ (*desc)->tfm = *hash_tfm;
+
+ return 0;
+}
+
+static void psspad_free_shash(struct crypto_shash *hash_tfm, struct shash_desc *desc)
+{
+ kfree(desc);
+ crypto_free_shash(hash_tfm);
+}
+
static int psspad_s_v_e_d(struct akcipher_request *req)
{
return -EOPNOTSUPP;
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 13/18] crypto: rsa-psspad: Get signature parameters from a given signature
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (11 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 12/18] crypto: rsa-psspad: Introduce shash alloc/dealloc helpers Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS Varad Gautam
` (6 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Implement akcipher_alg->set_sig_params for rsassa-psspad to receive the
salt length and MGF hash function for the signature being verified.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
v2: Set mgf_hash_algo in psspad_set_sig_params. v1 assumed this to be the same
as the digest hash.
crypto/rsa-psspad.c | 21 ++++++++++++++++++++-
include/crypto/internal/rsa-common.h | 2 ++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index 855e82ca071a7..eec303bb55b2d 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -9,6 +9,7 @@
#include <crypto/hash.h>
#include <crypto/internal/akcipher.h>
#include <crypto/internal/rsa-common.h>
+#include <crypto/public_key.h>
static int psspad_setup_shash(struct crypto_shash **hash_tfm, struct shash_desc **desc,
const char *hash_algo)
@@ -33,6 +34,23 @@ static void psspad_free_shash(struct crypto_shash *hash_tfm, struct shash_desc *
crypto_free_shash(hash_tfm);
}
+static int psspad_set_sig_params(struct crypto_akcipher *tfm,
+ const void *sig,
+ unsigned int siglen)
+{
+ struct akcipher_instance *inst = akcipher_alg_instance(tfm);
+ struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+ const struct public_key_signature *s = sig;
+
+ if (!sig)
+ return -EINVAL;
+
+ ictx->salt_len = s->salt_length;
+ ictx->mgf_hash_algo = s->mgf_hash_algo;
+
+ return 0;
+}
+
static int psspad_s_v_e_d(struct akcipher_request *req)
{
return -EOPNOTSUPP;
@@ -48,7 +66,8 @@ static struct akcipher_alg psspad_alg = {
.verify = psspad_s_v_e_d,
.set_pub_key = rsapad_set_pub_key,
.set_priv_key = rsapad_set_priv_key,
- .max_size = rsapad_get_max_size
+ .max_size = rsapad_get_max_size,
+ .set_sig_params = psspad_set_sig_params
};
static int psspad_create(struct crypto_template *tmpl, struct rtattr **tb)
diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h
index 4fa3cf5a989cc..8b7ba0174d5bf 100644
--- a/include/crypto/internal/rsa-common.h
+++ b/include/crypto/internal/rsa-common.h
@@ -26,6 +26,8 @@ struct rsapad_tfm_ctx {
struct rsapad_inst_ctx {
struct crypto_akcipher_spawn spawn;
const struct rsa_asn1_template *digest_info;
+ u16 salt_len;
+ const char *mgf_hash_algo;
};
struct rsapad_akciper_req_ctx {
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (12 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 13/18] crypto: rsa-psspad: Get signature parameters from a given signature Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 15/18] crypto: rsa-psspad: Provide PSS signature verify operation Varad Gautam
` (5 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
This generates a "mask" byte array of size mask_len bytes as a
concatenation of digests, where each digest is calculated on a
concatenation of an input seed and a running counter to fill up
mask_len bytes - as described by RFC8017 sec B.2.1. "MGF1".
The mask is useful for RSA signing/verification process with
encoding RSASSA-PSS.
Reference: https://tools.ietf.org/html/rfc8017#appendix-B.2.1
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-psspad.c | 54 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index eec303bb55b2d..ed5374c381513 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -51,6 +51,60 @@ static int psspad_set_sig_params(struct crypto_akcipher *tfm,
return 0;
}
+/* MGF1 per RFC8017 B.2.1. */
+static int pkcs1_mgf1(u8 *seed, unsigned int seed_len,
+ struct shash_desc *desc,
+ u8 *mask, unsigned int mask_len)
+{
+ unsigned int pos, h_len, i, c;
+ u8 *tmp;
+ int ret = 0;
+
+ h_len = crypto_shash_digestsize(desc->tfm);
+
+ pos = i = 0;
+ while ((i < (mask_len / h_len) + 1) && pos < mask_len) {
+ /* Compute T = T || Hash(mgfSeed || C) into mask at pos. */
+ c = cpu_to_be32(i);
+
+ ret = crypto_shash_init(desc);
+ if (ret < 0)
+ goto out_err;
+
+ ret = crypto_shash_update(desc, seed, seed_len);
+ if (ret < 0)
+ goto out_err;
+
+ ret = crypto_shash_update(desc, (u8 *) &c, sizeof(c));
+ if (ret < 0)
+ goto out_err;
+
+ if (mask_len - pos >= h_len) {
+ ret = crypto_shash_final(desc, mask + pos);
+ pos += h_len;
+ } else {
+ tmp = kzalloc(h_len, GFP_KERNEL);
+ if (!tmp) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+ ret = crypto_shash_final(desc, tmp);
+ /* copy the last hash */
+ memcpy(mask + pos, tmp, mask_len - pos);
+ kfree(tmp);
+ pos = mask_len;
+ }
+ if (ret < 0) {
+ goto out_err;
+ }
+
+ i++;
+ }
+
+out_err:
+ return ret;
+}
+
static int psspad_s_v_e_d(struct akcipher_request *req)
{
return -EOPNOTSUPP;
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 15/18] crypto: rsa-psspad: Provide PSS signature verify operation
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (13 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 14/18] crypto: Implement MGF1 Mask Generation Function for RSASSA-PSS Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 16/18] crypto: rsa-psspad: Implement signature verify callback Varad Gautam
` (4 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Trigger RSA transform on the signature being verified from
psspad_verify, to produce intermediary data which will be handled
in the psspad_verify_complete callback.
Reference: https://tools.ietf.org/html/rfc8017#section-8.1.2
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
crypto/rsa-psspad.c | 53 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index ed5374c381513..4ba4d69f6ce17 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -105,7 +105,50 @@ static int pkcs1_mgf1(u8 *seed, unsigned int seed_len,
return ret;
}
-static int psspad_s_v_e_d(struct akcipher_request *req)
+static int psspad_verify_complete(struct akcipher_request *req, int err)
+{
+ return -EOPNOTSUPP;
+}
+
+static void psspad_verify_complete_cb(struct crypto_async_request *child_async_req,
+ int err)
+{
+ rsapad_akcipher_req_complete(child_async_req, err,
+ psspad_verify_complete);
+}
+
+static int psspad_verify(struct akcipher_request *req)
+{
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
+ int err;
+
+ if (WARN_ON(req->dst) ||
+ WARN_ON(!req->dst_len) ||
+ !ctx->key_size || req->src_len < ctx->key_size)
+ return -EINVAL;
+
+ req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL);
+ if (!req_ctx->out_buf)
+ return -ENOMEM;
+
+ rsapad_akcipher_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
+ ctx->key_size, NULL);
+
+ /* Reuse input buffer, output to a new buffer */
+ rsapad_akcipher_setup_child(req, req->src, req_ctx->out_sg,
+ req->src_len, ctx->key_size,
+ psspad_verify_complete_cb);
+
+ err = crypto_akcipher_encrypt(&req_ctx->child_req);
+ if (err != -EINPROGRESS && err != -EBUSY)
+ return psspad_verify_complete(req, err);
+
+ return err;
+}
+
+static int psspad_s_e_d(struct akcipher_request *req)
{
return -EOPNOTSUPP;
}
@@ -114,10 +157,10 @@ static struct akcipher_alg psspad_alg = {
.init = rsapad_akcipher_init_tfm,
.exit = rsapad_akcipher_exit_tfm,
- .encrypt = psspad_s_v_e_d,
- .decrypt = psspad_s_v_e_d,
- .sign = psspad_s_v_e_d,
- .verify = psspad_s_v_e_d,
+ .encrypt = psspad_s_e_d,
+ .decrypt = psspad_s_e_d,
+ .sign = psspad_s_e_d,
+ .verify = psspad_verify,
.set_pub_key = rsapad_set_pub_key,
.set_priv_key = rsapad_set_priv_key,
.max_size = rsapad_get_max_size,
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 16/18] crypto: rsa-psspad: Implement signature verify callback
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (14 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 15/18] crypto: rsa-psspad: Provide PSS signature verify operation Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 17/18] crypto: Accept pss as valid encoding during signature verification Varad Gautam
` (3 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
The RSA output must be processed as per the EMSA-PSS-VERIFY operation
from RFC8017, which forms the core of the PSS signature verification.
Implement the verification callback, which operates on the RSA output
buffer.
Reference: https://tools.ietf.org/html/rfc8017#section-9.1.2
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
v2: Allow mgf_hash_algo to be different from digest hash algorithm.
crypto/rsa-psspad.c | 114 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 113 insertions(+), 1 deletion(-)
diff --git a/crypto/rsa-psspad.c b/crypto/rsa-psspad.c
index 4ba4d69f6ce17..87e90479a4fa7 100644
--- a/crypto/rsa-psspad.c
+++ b/crypto/rsa-psspad.c
@@ -8,6 +8,7 @@
#include <crypto/hash.h>
#include <crypto/internal/akcipher.h>
+#include <crypto/internal/rsa.h>
#include <crypto/internal/rsa-common.h>
#include <crypto/public_key.h>
@@ -107,7 +108,118 @@ static int pkcs1_mgf1(u8 *seed, unsigned int seed_len,
static int psspad_verify_complete(struct akcipher_request *req, int err)
{
- return -EOPNOTSUPP;
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct rsapad_akciper_req_ctx *req_ctx = akcipher_request_ctx(req);
+ struct akcipher_instance *inst = akcipher_alg_instance(tfm);
+ struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst);
+ const struct rsa_asn1_template *digest_info = ictx->digest_info;
+ struct crypto_shash *hash_tfm = NULL;
+ struct shash_desc *desc = NULL;
+ struct rsa_mpi_key *pkey = akcipher_tfm_ctx(ctx->child);
+
+ u8 *em, *h, *salt, *maskeddb;
+ unsigned int em_len, em_bits, h_len, s_len, maskeddb_len;
+ u8 *m_hash, *db_mask, *db, *h_;
+ static u8 zeroes[8] = { 0 };
+ unsigned int pos;
+
+ if (err)
+ goto out;
+
+ err = -EINVAL;
+ if (!digest_info)
+ goto out;
+
+ em = req_ctx->out_buf;
+ em_len = ctx->key_size;
+ em_bits = mpi_get_nbits(pkey->n) - 1;
+ if ((em_bits & 0x7) == 0) {
+ em_len--;
+ em++;
+ }
+
+ h_len = req->dst_len;
+ s_len = ictx->salt_len;
+
+ if (em_len < h_len + s_len + 2)
+ goto out;
+
+ if (em[em_len - 1] != 0xbc)
+ goto out;
+
+ maskeddb = em;
+ maskeddb_len = em_len - h_len - 1;
+ h = em + maskeddb_len;
+
+ if (em[0] & ~((u8) 0xff >> (8 * em_len - em_bits)))
+ goto out;
+
+ db_mask = kzalloc(maskeddb_len, GFP_KERNEL);
+ if (!db_mask) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = psspad_setup_shash(&hash_tfm, &desc, ictx->mgf_hash_algo);
+ if (err < 0)
+ goto out_db_mask;
+
+ err = pkcs1_mgf1(h, h_len, desc, db_mask, maskeddb_len);
+ if (err < 0)
+ goto out_shash;
+
+ for (pos = 0; pos < maskeddb_len; pos++)
+ maskeddb[pos] ^= db_mask[pos];
+ db = maskeddb;
+
+ db[0] &= ((u8) 0xff >> (8 * em_len - em_bits));
+
+ err = -EINVAL;
+ for (pos = 0; pos < em_len - h_len - s_len - 2; pos++) {
+ if (db[pos] != 0)
+ goto out_shash;
+ }
+ if (db[pos] != 0x01)
+ goto out_shash;
+
+ salt = db + (maskeddb_len - s_len);
+
+ m_hash = req_ctx->out_buf + ctx->key_size;
+ sg_pcopy_to_buffer(req->src,
+ sg_nents_for_len(req->src, req->src_len + req->dst_len),
+ m_hash,
+ req->dst_len, ctx->key_size);
+
+ if (strcmp(ictx->mgf_hash_algo, digest_info->name) != 0) {
+ psspad_free_shash(hash_tfm, desc);
+ err = psspad_setup_shash(&hash_tfm, &desc, digest_info->name);
+ if (err < 0)
+ goto out_db_mask;
+ }
+
+ err = crypto_shash_init(desc);
+ if (!err)
+ err = crypto_shash_update(desc, zeroes, 8);
+ if (!err)
+ err = crypto_shash_update(desc, m_hash, h_len);
+ if (!err)
+ err = crypto_shash_finup(desc, salt, s_len, m_hash);
+ if (err < 0)
+ goto out_shash;
+
+ h_ = m_hash;
+
+ if (memcmp(h_, h, h_len) != 0)
+ err = -EKEYREJECTED;
+
+out_shash:
+ psspad_free_shash(hash_tfm, desc);
+out_db_mask:
+ kfree(db_mask);
+out:
+ kfree_sensitive(req_ctx->out_buf);
+ return err;
}
static void psspad_verify_complete_cb(struct crypto_async_request *child_async_req,
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 17/18] crypto: Accept pss as valid encoding during signature verification
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (15 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 16/18] crypto: rsa-psspad: Implement signature verify callback Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-08 14:15 ` [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS Varad Gautam
` (2 subsequent siblings)
19 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Accept pss encoding for public_key_verify_signature. If
CONFIG_CRYPTO_RSASSA_PSS is disabled, crypto_alloc_akcipher will
fail to find a pss backend anyway.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
---
crypto/asymmetric_keys/public_key.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 788a4ba1e2e74..b9cc83ba7a127 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -69,19 +69,20 @@ int software_key_determine_akcipher(const char *encoding,
{
int n;
- if (strcmp(encoding, "pkcs1") == 0) {
+ if (strcmp(encoding, "pkcs1") == 0 || strcmp(encoding, "pss") == 0) {
/* The data wangled by the RSA algorithm is typically padded
* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
- * sec 8.2].
+ * sec 8.2] or EMSA-PSS [RFC8017 sec 9.1].
*/
if (!hash_algo)
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s)",
+ "%spad(%s)",
+ encoding,
pkey->pkey_algo);
else
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s,%s)",
- pkey->pkey_algo, hash_algo);
+ "%spad(%s,%s)",
+ encoding, pkey->pkey_algo, hash_algo);
return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
}
@@ -363,6 +364,13 @@ int public_key_verify_signature(const struct public_key *pkey,
goto error_free_key;
}
+ if (strcmp(sig->encoding, "pss") == 0) {
+ ret = crypto_akcipher_set_sig_params(tfm, sig, sizeof(*sig));
+ if (ret) {
+ goto error_free_key;
+ }
+ }
+
sg_init_table(src_sg, 2);
sg_set_buf(&src_sg[0], sig->s, sig->s_size);
sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (16 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 17/18] crypto: Accept pss as valid encoding during signature verification Varad Gautam
@ 2021-04-08 14:15 ` Varad Gautam
2021-04-09 14:15 ` Ben Boeckel
2021-04-08 15:05 ` David Howells
2021-04-08 15:08 ` [PATCH v2 00/18] Implement RSASSA-PSS signature verification David Howells
19 siblings, 1 reply; 24+ messages in thread
From: Varad Gautam @ 2021-04-08 14:15 UTC (permalink / raw)
To: linux-crypto
Cc: varad.gautam, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko, James Morris, Serge E. Hallyn,
open list:SECURITY SUBSYSTEM
keyctl pkey_* operations accept enc and hash parameters at present.
RSASSA-PSS signatures also require passing in the signature salt
length and the mgf hash function.
Add parameters:
- 'slen' to feed in salt length of a PSS signature.
- 'mgfhash' to feed in the hash function used for MGF.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
CC: Jarkko Sakkinen <jarkko@kernel.org>
---
v2: Accept 'mgfhash' as a parameter. v1 assumed this to be the same
as the digest hash.
crypto/asymmetric_keys/asymmetric_type.c | 2 ++
include/linux/keyctl.h | 2 ++
security/keys/keyctl_pkey.c | 13 +++++++++++++
3 files changed, 17 insertions(+)
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index ad8af3d70ac04..72c1bf964826f 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -571,6 +571,8 @@ static int asymmetric_key_verify_signature(struct kernel_pkey_params *params,
.hash_algo = params->hash_algo,
.digest = (void *)in,
.s = (void *)in2,
+ .salt_length = params->slen,
+ .mgf_hash_algo = params->mgf_hash_algo,
};
return verify_signature(params->key, &sig);
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 5b79847207ef2..753d004d76ece 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -37,6 +37,8 @@ struct kernel_pkey_params {
__u32 in2_len; /* 2nd input data size (verify) */
};
enum kernel_pkey_operation op : 8;
+ __u32 slen;
+ const char *mgf_hash_algo;
};
#endif /* __LINUX_KEYCTL_H */
diff --git a/security/keys/keyctl_pkey.c b/security/keys/keyctl_pkey.c
index 5de0d599a2748..ae3a81c726322 100644
--- a/security/keys/keyctl_pkey.c
+++ b/security/keys/keyctl_pkey.c
@@ -24,11 +24,15 @@ enum {
Opt_err,
Opt_enc, /* "enc=<encoding>" eg. "enc=oaep" */
Opt_hash, /* "hash=<digest-name>" eg. "hash=sha1" */
+ Opt_slen, /* "slen=<salt-length>" eg. "slen=32" */
+ Opt_mgfhash, /* "mgfhash=<digest-name>" eg. "mgfhash=sha1" */
};
static const match_table_t param_keys = {
{ Opt_enc, "enc=%s" },
{ Opt_hash, "hash=%s" },
+ { Opt_slen, "slen=%u" },
+ { Opt_mgfhash, "mgfhash=%s" },
{ Opt_err, NULL }
};
@@ -63,6 +67,15 @@ static int keyctl_pkey_params_parse(struct kernel_pkey_params *params)
params->hash_algo = q;
break;
+ case Opt_slen:
+ if (kstrtouint(q, 0, ¶ms->slen))
+ return -EINVAL;
+ break;
+
+ case Opt_mgfhash:
+ params->mgf_hash_algo = q;
+ break;
+
default:
return -EINVAL;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS
2021-04-08 14:15 ` [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS Varad Gautam
@ 2021-04-09 14:15 ` Ben Boeckel
2021-04-20 11:46 ` Varad Gautam
0 siblings, 1 reply; 24+ messages in thread
From: Ben Boeckel @ 2021-04-09 14:15 UTC (permalink / raw)
To: Varad Gautam
Cc: linux-crypto, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko, James Morris, Serge E. Hallyn,
open list:SECURITY SUBSYSTEM
On Thu, Apr 08, 2021 at 16:15:16 +0200, Varad Gautam wrote:
> keyctl pkey_* operations accept enc and hash parameters at present.
> RSASSA-PSS signatures also require passing in the signature salt
> length and the mgf hash function.
>
> Add parameters:
> - 'slen' to feed in salt length of a PSS signature.
> - 'mgfhash' to feed in the hash function used for MGF.
Could `Documentation/security/keys/core.rst` be updated to mention these
new parameters? Statements on what values are allowed would be
appreciated as well (e.g., that `saltlen` (a far better name IMO) is
unsigned 32-bits and where valid algorithm names could be found as
well).
Thanks,
--Ben
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS
2021-04-09 14:15 ` Ben Boeckel
@ 2021-04-20 11:46 ` Varad Gautam
0 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-20 11:46 UTC (permalink / raw)
To: Ben Boeckel
Cc: linux-crypto, dhowells, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko, James Morris, Serge E. Hallyn,
open list:SECURITY SUBSYSTEM
On 4/9/21 4:15 PM, Ben Boeckel wrote:
> On Thu, Apr 08, 2021 at 16:15:16 +0200, Varad Gautam wrote:
>> keyctl pkey_* operations accept enc and hash parameters at present.
>> RSASSA-PSS signatures also require passing in the signature salt
>> length and the mgf hash function.
>>
>> Add parameters:
>> - 'slen' to feed in salt length of a PSS signature.
>> - 'mgfhash' to feed in the hash function used for MGF.
>
> Could `Documentation/security/keys/core.rst` be updated to mention these
> new parameters? Statements on what values are allowed would be
> appreciated as well (e.g., that `saltlen` (a far better name IMO) is
> unsigned 32-bits and where valid algorithm names could be found as
> well).
>
Thanks, I've added these to v3.
> Thanks,
>
> --Ben
>
--
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5
90409 Nürnberg
Germany
HRB 36809, AG Nürnberg
Geschäftsführer: Felix Imendörffer
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (17 preceding siblings ...)
2021-04-08 14:15 ` [PATCH v2 18/18] keyctl_pkey: Add pkey parameters slen and mgfhash for PSS Varad Gautam
@ 2021-04-08 15:05 ` David Howells
2021-04-08 15:08 ` [PATCH v2 00/18] Implement RSASSA-PSS signature verification David Howells
19 siblings, 0 replies; 24+ messages in thread
From: David Howells @ 2021-04-08 15:05 UTC (permalink / raw)
To: Varad Gautam
Cc: dhowells, linux-crypto, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko, James Morris, Serge E. Hallyn,
open list:SECURITY SUBSYSTEM
Varad Gautam <varad.gautam@suse.com> wrote:
> + Opt_slen, /* "slen=<salt-length>" eg. "slen=32" */
"slen" seems a bit unobvious. Maybe "saltlen=..."?
David
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 00/18] Implement RSASSA-PSS signature verification
2021-04-08 14:14 [PATCH v2 00/18] Implement RSASSA-PSS signature verification Varad Gautam
` (18 preceding siblings ...)
2021-04-08 15:05 ` David Howells
@ 2021-04-08 15:08 ` David Howells
2021-04-20 11:47 ` Varad Gautam
19 siblings, 1 reply; 24+ messages in thread
From: David Howells @ 2021-04-08 15:08 UTC (permalink / raw)
To: Varad Gautam
Cc: dhowells, linux-crypto, herbert, davem, vt, tianjia.zhang,
keyrings, linux-kernel, jarkko
Varad Gautam <varad.gautam@suse.com> wrote:
> The test harness is available at [5].
Can you add this to the keyutils testsuite?
https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git
David
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 00/18] Implement RSASSA-PSS signature verification
2021-04-08 15:08 ` [PATCH v2 00/18] Implement RSASSA-PSS signature verification David Howells
@ 2021-04-20 11:47 ` Varad Gautam
0 siblings, 0 replies; 24+ messages in thread
From: Varad Gautam @ 2021-04-20 11:47 UTC (permalink / raw)
To: David Howells
Cc: linux-crypto, herbert, davem, vt, tianjia.zhang, keyrings,
linux-kernel, jarkko
Hi David,
On 4/8/21 5:08 PM, David Howells wrote:
> Varad Gautam <varad.gautam@suse.com> wrote:
>
>> The test harness is available at [5].
>
> Can you add this to the keyutils testsuite?
>
These are two separate things IMO - the keyutils tests test
for "the keyctl interface behaves as advertised". Testing the underlying
algorithms used for key operations (against reference vectors eg. NIST /
Wycheproof atm) is independent of the keyctl interface, and can also
happen at a layer below (eg. a kmod). I doubt keyutils is the best place
to keep this.
Regards,
Varad
> https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git
>
> David
>
--
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5
90409 Nürnberg
Germany
HRB 36809, AG Nürnberg
Geschäftsführer: Felix Imendörffer
^ permalink raw reply [flat|nested] 24+ messages in thread