2021-01-29 21:28:51

by Saulo Alessandre de Lima

[permalink] [raw]
Subject: [PATCH v2 2/4] ecdsa: prepare akcipher and x509 parser to use incoming ecdsa

From: Saulo Alessandre <[email protected]>

* crypto/asymmetric_keys/pkcs7_parser.c
- pkcs7_sig_note_pkey_algo - changed to recognize OID_id_ecdsa_with_sha(1,256,384,512).

* crypto/asymmetric_keys/pkcs7_verify.c
- pkcs7_digest - added warning when the summary has an unsupported algorithm, to avoid let others waste time, like me.

* crypto/asymmetric_keys/public_key.c
- software_key_determine_akcipher - modified to recognize ecdsa.

* crypto/asymmetric_keys/x509_cert_parser.c
- x509_note_pkey_algo - changed to recognize ecdsa and to use lookup_oid_
routines; added info about certificates found inside kernel;
- x509_note_signature - changed to recognize ecdsa;
- x509_extract_key_data - changed to recognize OID_id_ecPublicKey as ecdsa
---
crypto/asymmetric_keys/pkcs7_parser.c | 7 ++++-
crypto/asymmetric_keys/pkcs7_verify.c | 5 ++-
crypto/asymmetric_keys/public_key.c | 30 ++++++++++++------
crypto/asymmetric_keys/x509_cert_parser.c | 37 ++++++++++++-----------
4 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 967329e0a07b..501af4937516 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -267,12 +267,17 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
switch (ctx->last_oid) {
case OID_rsaEncryption:
ctx->sinfo->sig->pkey_algo = "rsa";
- ctx->sinfo->sig->encoding = "pkcs1";
+ break;
+ case OID_id_ecdsa_with_sha256:
+ case OID_id_ecdsa_with_sha384:
+ case OID_id_ecdsa_with_sha512:
+ ctx->sinfo->sig->pkey_algo = "ecdsa";
break;
default:
printk("Unsupported pkey algo: %u\n", ctx->last_oid);
return -ENOPKG;
}
+ ctx->sinfo->sig->encoding = "pkcs1";
return 0;
}

diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index ce49820caa97..a963aa9ec648 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -41,8 +41,11 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
* big the hash operational data will be.
*/
tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);
- if (IS_ERR(tfm))
+ if (IS_ERR(tfm)) {
+ pr_warn("%s unsupported hash_algo[%s]", __func__,
+ sinfo->sig->hash_algo);
return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
+ }

desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
sig->digest_size = crypto_shash_digestsize(tfm);
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 8892908ad58c..42429a10ef0b 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -70,18 +70,28 @@ int software_key_determine_akcipher(const char *encoding,
int n;

if (strcmp(encoding, "pkcs1") == 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].
- */
- if (!hash_algo)
+ if (pkey->pkey_algo && strcmp(pkey->pkey_algo, "rsa") == 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].
+ */
+ if (!hash_algo)
+ n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+ "pkcs1pad(%s)",
+ pkey->pkey_algo);
+ else
+ n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+ "pkcs1pad(%s,%s)",
+ pkey->pkey_algo, hash_algo);
+ } else if (pkey->pkey_algo &&
+ strcmp(pkey->pkey_algo, "ecdsa") == 0) {
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s)",
- pkey->pkey_algo);
- else
+ "%s(%s)", pkey->pkey_algo, hash_algo);
+ } else {
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s,%s)",
- pkey->pkey_algo, hash_algo);
+ "pkcs1pad(%s,%s)",
+ pkey->pkey_algo, hash_algo);
+ }
return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
}

diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 52c9b455fc7d..a67bdbae1055 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -197,6 +197,7 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,

pr_debug("PubKey Algo: %u\n", ctx->last_oid);

+ ctx->key_algo = ctx->last_oid;
switch (ctx->last_oid) {
case OID_md2WithRSAEncryption:
case OID_md3WithRSAEncryption:
@@ -204,27 +205,15 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
return -ENOPKG; /* Unsupported combination */

case OID_md4WithRSAEncryption:
- ctx->cert->sig->hash_algo = "md4";
- goto rsa_pkcs1;
-
case OID_sha1WithRSAEncryption:
- ctx->cert->sig->hash_algo = "sha1";
- goto rsa_pkcs1;
-
case OID_sha256WithRSAEncryption:
- ctx->cert->sig->hash_algo = "sha256";
- goto rsa_pkcs1;
-
case OID_sha384WithRSAEncryption:
- ctx->cert->sig->hash_algo = "sha384";
- goto rsa_pkcs1;
-
case OID_sha512WithRSAEncryption:
- ctx->cert->sig->hash_algo = "sha512";
- goto rsa_pkcs1;
-
case OID_sha224WithRSAEncryption:
- ctx->cert->sig->hash_algo = "sha224";
+ case OID_id_ecdsa_with_sha1:
+ case OID_id_ecdsa_with_sha256:
+ case OID_id_ecdsa_with_sha384:
+ case OID_id_ecdsa_with_sha512:
goto rsa_pkcs1;

case OID_gost2012Signature256:
@@ -241,9 +230,13 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
}

rsa_pkcs1:
- ctx->cert->sig->pkey_algo = "rsa";
+ lookup_oid_sign_info(ctx->key_algo, &ctx->cert->sig->pkey_algo);
+ lookup_oid_digest_info(ctx->key_algo, &ctx->cert->sig->hash_algo,
+ NULL, NULL);
ctx->cert->sig->encoding = "pkcs1";
ctx->algo_oid = ctx->last_oid;
+ pr_info("Found %s(%s) X509 certificate\n", ctx->cert->sig->pkey_algo,
+ ctx->cert->sig->hash_algo);
return 0;
ecrdsa:
ctx->cert->sig->pkey_algo = "ecrdsa";
@@ -275,6 +268,7 @@ int x509_note_signature(void *context, size_t hdrlen,
}

if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
+ strcmp(ctx->cert->sig->pkey_algo, "ecdsa") == 0 ||
strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0 ||
strcmp(ctx->cert->sig->pkey_algo, "sm2") == 0) {
/* Discard the BIT STRING metadata */
@@ -470,7 +464,14 @@ int x509_extract_key_data(void *context, size_t hdrlen,
ctx->cert->pub->pkey_algo = "ecrdsa";
break;
case OID_id_ecPublicKey:
- ctx->cert->pub->pkey_algo = "sm2";
+ if (ctx->algo_oid == OID_id_ecdsa_with_sha512 ||
+ ctx->algo_oid == OID_id_ecdsa_with_sha384 ||
+ ctx->algo_oid == OID_id_ecdsa_with_sha256 ||
+ ctx->algo_oid == OID_id_ecdsa_with_sha1) {
+ ctx->cert->pub->pkey_algo = "ecdsa";
+ } else {
+ ctx->cert->pub->pkey_algo = "sm2";
+ }
break;
default:
return -ENOPKG;
--
2.25.1