]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: ecrdsa - Migrate to sig_alg backend
authorLukas Wunner <lukas@wunner.de>
Tue, 10 Sep 2024 14:30:14 +0000 (16:30 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Sat, 5 Oct 2024 05:22:04 +0000 (13:22 +0800)
A sig_alg backend has just been introduced with the intent of moving all
asymmetric sign/verify algorithms to it one by one.

Migrate ecrdsa.c to the new backend.

One benefit of the new API is the use of kernel buffers instead of
sglists, which avoids the overhead of copying signature and digest
sglists back into kernel buffers.  ecrdsa.c is thus simplified quite
a bit.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/Kconfig
crypto/ecrdsa.c
crypto/testmgr.c
crypto/testmgr.h

index 768b28745a8a5ffb7ece6c2d95251f9576e3405f..989418fe75eb149ba6f61e7b4f2034b4dc83aed5 100644 (file)
@@ -302,7 +302,7 @@ config CRYPTO_ECDSA
 config CRYPTO_ECRDSA
        tristate "EC-RDSA (Elliptic Curve Russian Digital Signature Algorithm)"
        select CRYPTO_ECC
-       select CRYPTO_AKCIPHER
+       select CRYPTO_SIG
        select CRYPTO_STREEBOG
        select OID_REGISTRY
        select ASN1
index 3811f3805b5d880245a57a7e655e00e0a1f282e3..7383dd11089b080fc42e073525a6d9421b91bae4 100644 (file)
 
 #include <linux/module.h>
 #include <linux/crypto.h>
+#include <crypto/sig.h>
 #include <crypto/streebog.h>
-#include <crypto/internal/akcipher.h>
 #include <crypto/internal/ecc.h>
-#include <crypto/akcipher.h>
+#include <crypto/internal/sig.h>
 #include <linux/oid_registry.h>
-#include <linux/scatterlist.h>
 #include "ecrdsa_params.asn1.h"
 #include "ecrdsa_pub_key.asn1.h"
 #include "ecrdsa_defs.h"
@@ -68,13 +67,12 @@ static const struct ecc_curve *get_curve_by_oid(enum OID oid)
        }
 }
 
-static int ecrdsa_verify(struct akcipher_request *req)
+static int ecrdsa_verify(struct crypto_sig *tfm,
+                        const void *src, unsigned int slen,
+                        const void *digest, unsigned int dlen)
 {
-       struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-       struct ecrdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
-       unsigned char sig[ECRDSA_MAX_SIG_SIZE];
-       unsigned char digest[STREEBOG512_DIGEST_SIZE];
-       unsigned int ndigits = req->dst_len / sizeof(u64);
+       struct ecrdsa_ctx *ctx = crypto_sig_ctx(tfm);
+       unsigned int ndigits = dlen / sizeof(u64);
        u64 r[ECRDSA_MAX_DIGITS]; /* witness (r) */
        u64 _r[ECRDSA_MAX_DIGITS]; /* -r */
        u64 s[ECRDSA_MAX_DIGITS]; /* second part of sig (s) */
@@ -91,25 +89,19 @@ static int ecrdsa_verify(struct akcipher_request *req)
         */
        if (!ctx->curve ||
            !ctx->digest ||
-           !req->src ||
+           !src ||
+           !digest ||
            !ctx->pub_key.x ||
-           req->dst_len != ctx->digest_len ||
-           req->dst_len != ctx->curve->g.ndigits * sizeof(u64) ||
+           dlen != ctx->digest_len ||
+           dlen != ctx->curve->g.ndigits * sizeof(u64) ||
            ctx->pub_key.ndigits != ctx->curve->g.ndigits ||
-           req->dst_len * 2 != req->src_len ||
-           WARN_ON(req->src_len > sizeof(sig)) ||
-           WARN_ON(req->dst_len > sizeof(digest)))
+           dlen * 2 != slen ||
+           WARN_ON(slen > ECRDSA_MAX_SIG_SIZE) ||
+           WARN_ON(dlen > STREEBOG512_DIGEST_SIZE))
                return -EBADMSG;
 
-       sg_copy_to_buffer(req->src, sg_nents_for_len(req->src, req->src_len),
-                         sig, req->src_len);
-       sg_pcopy_to_buffer(req->src,
-                          sg_nents_for_len(req->src,
-                                           req->src_len + req->dst_len),
-                          digest, req->dst_len, req->src_len);
-
-       vli_from_be64(s, sig, ndigits);
-       vli_from_be64(r, sig + ndigits * sizeof(u64), ndigits);
+       vli_from_be64(s, src, ndigits);
+       vli_from_be64(r, src + ndigits * sizeof(u64), ndigits);
 
        /* Step 1: verify that 0 < r < q, 0 < s < q */
        if (vli_is_zero(r, ndigits) ||
@@ -188,10 +180,10 @@ static u8 *ecrdsa_unpack_u32(u32 *dst, void *src)
 }
 
 /* Parse BER encoded subjectPublicKey. */
-static int ecrdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+static int ecrdsa_set_pub_key(struct crypto_sig *tfm, const void *key,
                              unsigned int keylen)
 {
-       struct ecrdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+       struct ecrdsa_ctx *ctx = crypto_sig_ctx(tfm);
        unsigned int ndigits;
        u32 algo, paramlen;
        u8 *params;
@@ -249,9 +241,9 @@ static int ecrdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
        return 0;
 }
 
-static unsigned int ecrdsa_max_size(struct crypto_akcipher *tfm)
+static unsigned int ecrdsa_max_size(struct crypto_sig *tfm)
 {
-       struct ecrdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+       struct ecrdsa_ctx *ctx = crypto_sig_ctx(tfm);
 
        /*
         * Verify doesn't need any output, so it's just informational
@@ -260,11 +252,11 @@ static unsigned int ecrdsa_max_size(struct crypto_akcipher *tfm)
        return ctx->pub_key.ndigits * sizeof(u64);
 }
 
-static void ecrdsa_exit_tfm(struct crypto_akcipher *tfm)
+static void ecrdsa_exit_tfm(struct crypto_sig *tfm)
 {
 }
 
-static struct akcipher_alg ecrdsa_alg = {
+static struct sig_alg ecrdsa_alg = {
        .verify         = ecrdsa_verify,
        .set_pub_key    = ecrdsa_set_pub_key,
        .max_size       = ecrdsa_max_size,
@@ -280,12 +272,12 @@ static struct akcipher_alg ecrdsa_alg = {
 
 static int __init ecrdsa_mod_init(void)
 {
-       return crypto_register_akcipher(&ecrdsa_alg);
+       return crypto_register_sig(&ecrdsa_alg);
 }
 
 static void __exit ecrdsa_mod_fini(void)
 {
-       crypto_unregister_akcipher(&ecrdsa_alg);
+       crypto_unregister_sig(&ecrdsa_alg);
 }
 
 module_init(ecrdsa_mod_init);
index 4e6f2eb7c4962615d833fc80e6740db1cacafb0c..ed971d857057b62fabea11959abda87e7f11ad7c 100644 (file)
@@ -5268,9 +5268,9 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecrdsa",
-               .test = alg_test_akcipher,
+               .test = alg_test_sig,
                .suite = {
-                       .akcipher = __VECS(ecrdsa_tv_template)
+                       .sig = __VECS(ecrdsa_tv_template)
                }
        }, {
                .alg = "essiv(authenc(hmac(sha256),cbc(aes)),sha256)",
index a4987610fcb5cb3aec2c4ab1c519db6885bd65ea..fd4823c26d93eb9005a06d934d2c5a4fb052e04e 100644 (file)
@@ -1119,7 +1119,7 @@ static const struct sig_testvec ecdsa_nist_p521_tv_template[] = {
 /*
  * EC-RDSA test vectors are generated by gost-engine.
  */
-static const struct akcipher_testvec ecrdsa_tv_template[] = {
+static const struct sig_testvec ecrdsa_tv_template[] = {
        {
        .key =
        "\x04\x40\xd5\xa7\x77\xf9\x26\x2f\x8c\xbd\xcc\xe3\x1f\x01\x94\x05"
@@ -1144,7 +1144,6 @@ static const struct akcipher_testvec ecrdsa_tv_template[] = {
        "\x79\xd2\x76\x64\xa3\xbd\x66\x10\x79\x05\x5a\x06\x42\xec\xb9\xc9",
        .m_size = 32,
        .public_key_vec = true,
-       .siggen_sigver_test = true,
        },
        {
        .key =
@@ -1170,7 +1169,6 @@ static const struct akcipher_testvec ecrdsa_tv_template[] = {
        "\x11\x23\x4a\x70\x43\x52\x7a\x68\x11\x65\x45\x37\xbb\x25\xb7\x40",
        .m_size = 32,
        .public_key_vec = true,
-       .siggen_sigver_test = true,
        },
        {
        .key =
@@ -1196,7 +1194,6 @@ static const struct akcipher_testvec ecrdsa_tv_template[] = {
        "\x9f\x16\xc6\x1c\xb1\x3f\x84\x41\x69\xec\x34\xfd\xf1\xf9\xa3\x39",
        .m_size = 32,
        .public_key_vec = true,
-       .siggen_sigver_test = true,
        },
        {
        .key =
@@ -1231,7 +1228,6 @@ static const struct akcipher_testvec ecrdsa_tv_template[] = {
        "\xa8\xf6\x80\x01\xb9\x27\xac\xd8\x45\x96\x66\xa1\xee\x48\x08\x3f",
        .m_size = 64,
        .public_key_vec = true,
-       .siggen_sigver_test = true,
        },
        {
        .key =
@@ -1266,7 +1262,6 @@ static const struct akcipher_testvec ecrdsa_tv_template[] = {
        "\x6d\xf4\xd2\x45\xc2\x83\xa0\x42\x95\x05\x9d\x89\x8e\x0a\xca\xcc",
        .m_size = 64,
        .public_key_vec = true,
-       .siggen_sigver_test = true,
        },
 };