From db6c43bd2132dc2dd63d73a6d1ed601cffd0ae06 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Tue, 2 Feb 2016 10:08:53 -0800 Subject: crypto: KEYS: convert public key and digsig asym to the akcipher api This patch converts the module verification code to the new akcipher API. Signed-off-by: Tadeusz Struk Acked-by: Herbert Xu Signed-off-by: David Howells --- include/crypto/public_key.h | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) (limited to 'include/crypto') diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index cc2516df0efa..50ac8759d7ee 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -24,7 +24,6 @@ enum pkey_algo { }; extern const char *const pkey_algo_name[PKEY_ALGO__LAST]; -extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST]; /* asymmetric key implementation supports only up to SHA224 */ #define PKEY_HASH__LAST (HASH_ALGO_SHA224 + 1) @@ -59,31 +58,10 @@ extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR]; * part. */ struct public_key { - const struct public_key_algorithm *algo; - u8 capabilities; -#define PKEY_CAN_ENCRYPT 0x01 -#define PKEY_CAN_DECRYPT 0x02 -#define PKEY_CAN_SIGN 0x04 -#define PKEY_CAN_VERIFY 0x08 + void *key; + u32 keylen; enum pkey_algo pkey_algo : 8; enum pkey_id_type id_type : 8; - union { - MPI mpi[5]; - struct { - MPI p; /* DSA prime */ - MPI q; /* DSA group order */ - MPI g; /* DSA group generator */ - MPI y; /* DSA public-key value = g^x mod p */ - MPI x; /* DSA secret exponent (if present) */ - } dsa; - struct { - MPI n; /* RSA public modulus */ - MPI e; /* RSA public encryption exponent */ - MPI d; /* RSA secret encryption exponent (if present) */ - MPI p; /* RSA secret prime (if present) */ - MPI q; /* RSA secret prime (if present) */ - } rsa; - }; }; extern void public_key_destroy(void *payload); @@ -92,6 +70,8 @@ extern void public_key_destroy(void *payload); * Public key cryptography signature data */ struct public_key_signature { + u8 *s; /* Signature */ + u32 s_size; /* Number of bytes in signature */ u8 *digest; u8 digest_size; /* Number of bytes in digest */ u8 nr_mpi; /* Occupancy of mpi[] */ @@ -109,6 +89,7 @@ struct public_key_signature { }; }; +extern struct asymmetric_key_subtype public_key_subtype; struct key; extern int verify_signature(const struct key *key, const struct public_key_signature *sig); @@ -119,4 +100,9 @@ extern struct key *x509_request_asymmetric_key(struct key *keyring, const struct asymmetric_key_id *skid, bool partial); +int public_key_verify_signature(const struct public_key *pkey, + const struct public_key_signature *sig); + +int rsa_verify_signature(const struct public_key *pkey, + const struct public_key_signature *sig); #endif /* _LINUX_PUBLIC_KEY_H */ -- cgit v1.2.3 From d846e78e491ff4dd0747026c02414844d504fcb6 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Tue, 2 Feb 2016 10:09:03 -0800 Subject: crypto: public_key: remove MPIs from public_key_signature struct After digsig_asymmetric.c is converted the MPIs can be now safely removed from the public_key_signature structure. Signed-off-by: Tadeusz Struk Acked-by: Herbert Xu Signed-off-by: David Howells --- include/crypto/public_key.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'include/crypto') diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index 50ac8759d7ee..a1693ed77be6 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -14,7 +14,6 @@ #ifndef _LINUX_PUBLIC_KEY_H #define _LINUX_PUBLIC_KEY_H -#include #include enum pkey_algo { @@ -73,20 +72,9 @@ struct public_key_signature { u8 *s; /* Signature */ u32 s_size; /* Number of bytes in signature */ u8 *digest; - u8 digest_size; /* Number of bytes in digest */ - u8 nr_mpi; /* Occupancy of mpi[] */ + u8 digest_size; /* Number of bytes in digest */ enum pkey_algo pkey_algo : 8; enum hash_algo pkey_hash_algo : 8; - union { - MPI mpi[2]; - struct { - MPI s; /* m^d mod n */ - } rsa; - struct { - MPI r; - MPI s; - } dsa; - }; }; extern struct asymmetric_key_subtype public_key_subtype; -- cgit v1.2.3 From d43de6c780a84def056afaf4fb3e66bdaa1efc00 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 Mar 2016 21:49:27 +0000 Subject: akcipher: Move the RSA DER encoding check to the crypto layer Move the RSA EMSA-PKCS1-v1_5 encoding from the asymmetric-key public_key subtype to the rsa crypto module's pkcs1pad template. This means that the public_key subtype no longer has any dependencies on public key type. To make this work, the following changes have been made: (1) The rsa pkcs1pad template is now used for RSA keys. This strips off the padding and returns just the message hash. (2) In a previous patch, the pkcs1pad template gained an optional second parameter that, if given, specifies the hash used. We now give this, and pkcs1pad checks the encoded message E(M) for the EMSA-PKCS1-v1_5 encoding and verifies that the correct digest OID is present. (3) The crypto driver in crypto/asymmetric_keys/rsa.c is now reduced to something that doesn't care about what the encryption actually does and and has been merged into public_key.c. (4) CONFIG_PUBLIC_KEY_ALGO_RSA is gone. Module signing must set CONFIG_CRYPTO_RSA=y instead. Thoughts: (*) Should the encoding style (eg. raw, EMSA-PKCS1-v1_5) also be passed to the padding template? Should there be multiple padding templates registered that share most of the code? Signed-off-by: David Howells Signed-off-by: Tadeusz Struk Acked-by: Herbert Xu --- crypto/asymmetric_keys/Kconfig | 7 -- crypto/asymmetric_keys/Makefile | 1 - crypto/asymmetric_keys/public_key.c | 104 +++++++++++++-- crypto/asymmetric_keys/rsa.c | 224 --------------------------------- include/crypto/public_key.h | 2 - init/Kconfig | 2 +- security/integrity/digsig_asymmetric.c | 1 + 7 files changed, 95 insertions(+), 246 deletions(-) delete mode 100644 crypto/asymmetric_keys/rsa.c (limited to 'include/crypto') diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index 905d745c2f85..91a7e047a765 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig @@ -12,7 +12,6 @@ if ASYMMETRIC_KEY_TYPE config ASYMMETRIC_PUBLIC_KEY_SUBTYPE tristate "Asymmetric public-key crypto algorithm subtype" select MPILIB - select PUBLIC_KEY_ALGO_RSA select CRYPTO_HASH_INFO help This option provides support for asymmetric public key type handling. @@ -20,12 +19,6 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE appropriate hash algorithms (such as SHA-1) must be available. ENOPKG will be reported if the requisite algorithm is unavailable. -config PUBLIC_KEY_ALGO_RSA - tristate "RSA public-key algorithm" - select CRYPTO_RSA - help - This option enables support for the RSA algorithm (PKCS#1, RFC3447). - config X509_CERTIFICATE_PARSER tristate "X.509 certificate parser" depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index b78a194ea014..f90486256f01 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o asymmetric_keys-y := asymmetric_type.o signature.o obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o -obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o # # X.509 Certificate handling diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index b383629b9e62..27ebc2f44394 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -17,8 +17,10 @@ #include #include #include +#include #include #include +#include MODULE_LICENSE("GPL"); @@ -35,12 +37,6 @@ const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = { }; EXPORT_SYMBOL_GPL(pkey_id_type_name); -static int (*alg_verify[PKEY_ALGO__LAST])(const struct public_key *pkey, - const struct public_key_signature *sig) = { - NULL, - rsa_verify_signature -}; - /* * Provide a part of a description of the key for /proc/keys. */ @@ -68,24 +64,110 @@ void public_key_destroy(void *payload) } EXPORT_SYMBOL_GPL(public_key_destroy); +struct public_key_completion { + struct completion completion; + int err; +}; + +static void public_key_verify_done(struct crypto_async_request *req, int err) +{ + struct public_key_completion *compl = req->data; + + if (err == -EINPROGRESS) + return; + + compl->err = err; + complete(&compl->completion); +} + /* * Verify a signature using a public key. */ int public_key_verify_signature(const struct public_key *pkey, const struct public_key_signature *sig) { + struct public_key_completion compl; + struct crypto_akcipher *tfm; + struct akcipher_request *req; + struct scatterlist sig_sg, digest_sg; + const char *alg_name; + char alg_name_buf[CRYPTO_MAX_ALG_NAME]; + void *output; + unsigned int outlen; + int ret = -ENOMEM; + + pr_devel("==>%s()\n", __func__); + BUG_ON(!pkey); BUG_ON(!sig); BUG_ON(!sig->digest); BUG_ON(!sig->s); - if (pkey->pkey_algo >= PKEY_ALGO__LAST) - return -ENOPKG; + alg_name = pkey_algo_name[sig->pkey_algo]; + if (sig->pkey_algo == PKEY_ALGO_RSA) { + /* 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 (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME, + "pkcs1pad(rsa,%s)", + hash_algo_name[sig->pkey_hash_algo] + ) >= CRYPTO_MAX_ALG_NAME) + return -EINVAL; + alg_name = alg_name_buf; + } + + tfm = crypto_alloc_akcipher(alg_name, 0, 0); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + req = akcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) + goto error_free_tfm; + + ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); + if (ret) + goto error_free_req; + + outlen = crypto_akcipher_maxsize(tfm); + output = kmalloc(outlen, GFP_KERNEL); + if (!output) + goto error_free_req; + + sg_init_one(&sig_sg, sig->s, sig->s_size); + sg_init_one(&digest_sg, output, outlen); + akcipher_request_set_crypt(req, &sig_sg, &digest_sg, sig->s_size, + outlen); + init_completion(&compl.completion); + akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP, + public_key_verify_done, &compl); + + /* Perform the verification calculation. This doesn't actually do the + * verification, but rather calculates the hash expected by the + * signature and returns that to us. + */ + ret = crypto_akcipher_verify(req); + if (ret == -EINPROGRESS) { + wait_for_completion(&compl.completion); + ret = compl.err; + } + if (ret < 0) + goto out_free_output; - if (!alg_verify[pkey->pkey_algo]) - return -ENOPKG; + /* Do the actual verification step. */ + if (req->dst_len != sig->digest_size || + memcmp(sig->digest, output, sig->digest_size) != 0) + ret = -EKEYREJECTED; - return alg_verify[pkey->pkey_algo](pkey, sig); +out_free_output: + kfree(output); +error_free_req: + akcipher_request_free(req); +error_free_tfm: + crypto_free_akcipher(tfm); + pr_devel("<==%s() = %d\n", __func__, ret); + return ret; } EXPORT_SYMBOL_GPL(public_key_verify_signature); diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c deleted file mode 100644 index 51502bca65e7..000000000000 --- a/crypto/asymmetric_keys/rsa.c +++ /dev/null @@ -1,224 +0,0 @@ -/* RSA asymmetric public-key algorithm [RFC3447] - * - * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#define pr_fmt(fmt) "RSA: "fmt -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("RSA Public Key Algorithm"); - -#define kenter(FMT, ...) \ - pr_devel("==> %s("FMT")\n", __func__, ##__VA_ARGS__) -#define kleave(FMT, ...) \ - pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__) - -/* - * 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_RIPE_MD_160[] = { - 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 { - const u8 *data; - size_t size; -} RSA_ASN1_templates[PKEY_HASH__LAST] = { -#define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) } - [HASH_ALGO_MD5] = _(MD5), - [HASH_ALGO_SHA1] = _(SHA1), - [HASH_ALGO_RIPE_MD_160] = _(RIPE_MD_160), - [HASH_ALGO_SHA256] = _(SHA256), - [HASH_ALGO_SHA384] = _(SHA384), - [HASH_ALGO_SHA512] = _(SHA512), - [HASH_ALGO_SHA224] = _(SHA224), -#undef _ -}; - -struct rsa_completion { - struct completion completion; - int err; -}; - -/* - * Perform the RSA signature verification. - * @H: Value of hash of data and metadata - * @EM: The computed signature value - * @k: The size of EM (EM[0] is an invalid location but should hold 0x00) - * @hash_size: The size of H - * @asn1_template: The DigestInfo ASN.1 template - * @asn1_size: Size of asm1_template[] - */ -static int rsa_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size, - const u8 *asn1_template, size_t asn1_size) -{ - unsigned PS_end, T_offset, i; - - kenter(",,%zu,%zu,%zu", k, hash_size, asn1_size); - - if (k < 2 + 1 + asn1_size + hash_size) - return -EBADMSG; - - /* Decode the EMSA-PKCS1-v1_5 - * note: leading zeros are stripped by the RSA implementation - */ - if (EM[0] != 0x01) { - kleave(" = -EBADMSG [EM[0] == %02u]", EM[0]); - return -EBADMSG; - } - - T_offset = k - (asn1_size + hash_size); - PS_end = T_offset - 1; - if (EM[PS_end] != 0x00) { - kleave(" = -EBADMSG [EM[T-1] == %02u]", EM[PS_end]); - return -EBADMSG; - } - - for (i = 1; i < PS_end; i++) { - if (EM[i] != 0xff) { - kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]); - return -EBADMSG; - } - } - - if (crypto_memneq(asn1_template, EM + T_offset, asn1_size) != 0) { - kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]"); - return -EBADMSG; - } - - if (crypto_memneq(H, EM + T_offset + asn1_size, hash_size) != 0) { - kleave(" = -EKEYREJECTED [EM[T] hash mismatch]"); - return -EKEYREJECTED; - } - - kleave(" = 0"); - return 0; -} - -static void public_key_verify_done(struct crypto_async_request *req, int err) -{ - struct rsa_completion *compl = req->data; - - if (err == -EINPROGRESS) - return; - - compl->err = err; - complete(&compl->completion); -} - -int rsa_verify_signature(const struct public_key *pkey, - const struct public_key_signature *sig) -{ - struct crypto_akcipher *tfm; - struct akcipher_request *req; - struct rsa_completion compl; - struct scatterlist sig_sg, sg_out; - void *outbuf = NULL; - unsigned int outlen = 0; - int ret = -ENOMEM; - - tfm = crypto_alloc_akcipher("rsa", 0, 0); - if (IS_ERR(tfm)) - goto error_out; - - req = akcipher_request_alloc(tfm, GFP_KERNEL); - if (!req) - goto error_free_tfm; - - ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); - if (ret) - goto error_free_req; - - ret = -EINVAL; - outlen = crypto_akcipher_maxsize(tfm); - if (!outlen) - goto error_free_req; - - /* Initialize the output buffer */ - ret = -ENOMEM; - outbuf = kmalloc(outlen, GFP_KERNEL); - if (!outbuf) - goto error_free_req; - - sg_init_one(&sig_sg, sig->s, sig->s_size); - sg_init_one(&sg_out, outbuf, outlen); - akcipher_request_set_crypt(req, &sig_sg, &sg_out, sig->s_size, outlen); - init_completion(&compl.completion); - akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | - CRYPTO_TFM_REQ_MAY_SLEEP, - public_key_verify_done, &compl); - - ret = crypto_akcipher_verify(req); - if (ret == -EINPROGRESS) { - wait_for_completion(&compl.completion); - ret = compl.err; - } - - if (ret) - goto error_free_req; - - /* Output from the operation is an encoded message (EM) of - * length k octets. - */ - outlen = req->dst_len; - ret = rsa_verify(sig->digest, outbuf, outlen, sig->digest_size, - RSA_ASN1_templates[sig->pkey_hash_algo].data, - RSA_ASN1_templates[sig->pkey_hash_algo].size); -error_free_req: - akcipher_request_free(req); -error_free_tfm: - crypto_free_akcipher(tfm); -error_out: - kfree(outbuf); - return ret; -} -EXPORT_SYMBOL_GPL(rsa_verify_signature); diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index a1693ed77be6..80ab099a3edf 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -91,6 +91,4 @@ extern struct key *x509_request_asymmetric_key(struct key *keyring, int public_key_verify_signature(const struct public_key *pkey, const struct public_key_signature *sig); -int rsa_verify_signature(const struct public_key *pkey, - const struct public_key_signature *sig); #endif /* _LINUX_PUBLIC_KEY_H */ diff --git a/init/Kconfig b/init/Kconfig index 22320804fbaf..af4de4f1b02c 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1757,9 +1757,9 @@ config SYSTEM_DATA_VERIFICATION select SYSTEM_TRUSTED_KEYRING select KEYS select CRYPTO + select CRYPTO_RSA select ASYMMETRIC_KEY_TYPE select ASYMMETRIC_PUBLIC_KEY_SUBTYPE - select PUBLIC_KEY_ALGO_RSA select ASN1 select OID_REGISTRY select X509_CERTIFICATE_PARSER diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 2fa3bc681a1b..69a92e6db23d 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -103,6 +103,7 @@ int asymmetric_verify(struct key *keyring, const char *sig, memset(&pks, 0, sizeof(pks)); + pks.pkey_algo = PKEY_ALGO_RSA; pks.pkey_hash_algo = hdr->hash_algo; pks.digest = (u8 *)data; pks.digest_size = datalen; -- cgit v1.2.3 From 4e8ae72a75aae285ec5b93518b9680da198afd0d Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 Mar 2016 21:49:27 +0000 Subject: X.509: Make algo identifiers text instead of enum Make the identifier public key and digest algorithm fields text instead of enum. Signed-off-by: David Howells Acked-by: Herbert Xu --- crypto/asymmetric_keys/mscode_parser.c | 14 +++++++------- crypto/asymmetric_keys/pkcs7_parser.c | 18 ++++++++---------- crypto/asymmetric_keys/pkcs7_verify.c | 8 +++----- crypto/asymmetric_keys/public_key.c | 24 ++++-------------------- crypto/asymmetric_keys/verify_pefile.c | 4 ++-- crypto/asymmetric_keys/verify_pefile.h | 2 +- crypto/asymmetric_keys/x509_cert_parser.c | 26 +++++++++++++------------- crypto/asymmetric_keys/x509_public_key.c | 17 ++++++++--------- include/crypto/public_key.h | 30 ++++-------------------------- kernel/module_signing.c | 6 ++++++ security/integrity/digsig_asymmetric.c | 7 ++++--- security/integrity/integrity.h | 2 +- 12 files changed, 61 insertions(+), 97 deletions(-) (limited to 'include/crypto') diff --git a/crypto/asymmetric_keys/mscode_parser.c b/crypto/asymmetric_keys/mscode_parser.c index adcef59eec0b..3242cbfaeaa2 100644 --- a/crypto/asymmetric_keys/mscode_parser.c +++ b/crypto/asymmetric_keys/mscode_parser.c @@ -86,25 +86,25 @@ int mscode_note_digest_algo(void *context, size_t hdrlen, oid = look_up_OID(value, vlen); switch (oid) { case OID_md4: - ctx->digest_algo = HASH_ALGO_MD4; + ctx->digest_algo = "md4"; break; case OID_md5: - ctx->digest_algo = HASH_ALGO_MD5; + ctx->digest_algo = "md5"; break; case OID_sha1: - ctx->digest_algo = HASH_ALGO_SHA1; + ctx->digest_algo = "sha1"; break; case OID_sha256: - ctx->digest_algo = HASH_ALGO_SHA256; + ctx->digest_algo = "sha256"; break; case OID_sha384: - ctx->digest_algo = HASH_ALGO_SHA384; + ctx->digest_algo = "sha384"; break; case OID_sha512: - ctx->digest_algo = HASH_ALGO_SHA512; + ctx->digest_algo = "sha512"; break; case OID_sha224: - ctx->digest_algo = HASH_ALGO_SHA224; + ctx->digest_algo = "sha224"; break; case OID__NR: diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index cbbd03fd94f8..40de03f49ff8 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -218,25 +218,25 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen, switch (ctx->last_oid) { case OID_md4: - ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_MD4; + ctx->sinfo->sig.hash_algo = "md4"; break; case OID_md5: - ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_MD5; + ctx->sinfo->sig.hash_algo = "md5"; break; case OID_sha1: - ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA1; + ctx->sinfo->sig.hash_algo = "sha1"; break; case OID_sha256: - ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA256; + ctx->sinfo->sig.hash_algo = "sha256"; break; case OID_sha384: - ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA384; + ctx->sinfo->sig.hash_algo = "sha384"; break; case OID_sha512: - ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA512; + ctx->sinfo->sig.hash_algo = "sha512"; break; case OID_sha224: - ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA224; + ctx->sinfo->sig.hash_algo = "sha224"; default: printk("Unsupported digest algo: %u\n", ctx->last_oid); return -ENOPKG; @@ -255,7 +255,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen, switch (ctx->last_oid) { case OID_rsaEncryption: - ctx->sinfo->sig.pkey_algo = PKEY_ALGO_RSA; + ctx->sinfo->sig.pkey_algo = "rsa"; break; default: printk("Unsupported pkey algo: %u\n", ctx->last_oid); @@ -615,8 +615,6 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen, { struct pkcs7_parse_context *ctx = context; - BUG_ON(ctx->sinfo->sig.pkey_algo != PKEY_ALGO_RSA); - ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL); if (!ctx->sinfo->sig.s) return -ENOMEM; diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index f5db1378c096..50be2a15e531 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -31,17 +31,15 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, void *digest; int ret; - kenter(",%u,%u", sinfo->index, sinfo->sig.pkey_hash_algo); + kenter(",%u,%s", sinfo->index, sinfo->sig.hash_algo); - if (sinfo->sig.pkey_hash_algo >= PKEY_HASH__LAST || - !hash_algo_name[sinfo->sig.pkey_hash_algo]) + if (!sinfo->sig.hash_algo) return -ENOPKG; /* Allocate the hashing algorithm we're going to need and find out how * big the hash operational data will be. */ - tfm = crypto_alloc_shash(hash_algo_name[sinfo->sig.pkey_hash_algo], - 0, 0); + tfm = crypto_alloc_shash(sinfo->sig.hash_algo, 0, 0); if (IS_ERR(tfm)) return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 27ebc2f44394..0f8b264b3961 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -24,19 +24,6 @@ MODULE_LICENSE("GPL"); -const char *const pkey_algo_name[PKEY_ALGO__LAST] = { - [PKEY_ALGO_DSA] = "dsa", - [PKEY_ALGO_RSA] = "rsa", -}; -EXPORT_SYMBOL_GPL(pkey_algo_name); - -const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = { - [PKEY_ID_PGP] = "PGP", - [PKEY_ID_X509] = "X509", - [PKEY_ID_PKCS7] = "PKCS#7", -}; -EXPORT_SYMBOL_GPL(pkey_id_type_name); - /* * Provide a part of a description of the key for /proc/keys. */ @@ -46,9 +33,7 @@ static void public_key_describe(const struct key *asymmetric_key, struct public_key *key = asymmetric_key->payload.data[asym_crypto]; if (key) - seq_printf(m, "%s.%s", - pkey_id_type_name[key->id_type], - pkey_algo_name[key->pkey_algo]); + seq_printf(m, "%s.%s", key->id_type, key->pkey_algo); } /* @@ -103,15 +88,14 @@ int public_key_verify_signature(const struct public_key *pkey, BUG_ON(!sig->digest); BUG_ON(!sig->s); - alg_name = pkey_algo_name[sig->pkey_algo]; - if (sig->pkey_algo == PKEY_ALGO_RSA) { + alg_name = sig->pkey_algo; + if (strcmp(sig->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 (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME, - "pkcs1pad(rsa,%s)", - hash_algo_name[sig->pkey_hash_algo] + "pkcs1pad(rsa,%s)", sig->hash_algo ) >= CRYPTO_MAX_ALG_NAME) return -EINVAL; alg_name = alg_name_buf; diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 897b734dabf9..7e8c2338ae25 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -328,12 +328,12 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen, void *digest; int ret; - kenter(",%u", ctx->digest_algo); + kenter(",%s", ctx->digest_algo); /* Allocate the hashing algorithm we're going to need and find out how * big the hash operational data will be. */ - tfm = crypto_alloc_shash(hash_algo_name[ctx->digest_algo], 0, 0); + tfm = crypto_alloc_shash(ctx->digest_algo, 0, 0); if (IS_ERR(tfm)) return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); diff --git a/crypto/asymmetric_keys/verify_pefile.h b/crypto/asymmetric_keys/verify_pefile.h index 55d5f7ebc45a..a133eb81a492 100644 --- a/crypto/asymmetric_keys/verify_pefile.h +++ b/crypto/asymmetric_keys/verify_pefile.h @@ -28,7 +28,7 @@ struct pefile_context { /* PKCS#7 MS Individual Code Signing content */ const void *digest; /* Digest */ unsigned digest_len; /* Digest length */ - enum hash_algo digest_algo; /* Digest algorithm */ + const char *digest_algo; /* Digest algorithm */ }; #define kenter(FMT, ...) \ diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index c02c200a7136..4a29bac70060 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -188,33 +188,33 @@ int x509_note_pkey_algo(void *context, size_t hdrlen, return -ENOPKG; /* Unsupported combination */ case OID_md4WithRSAEncryption: - ctx->cert->sig.pkey_hash_algo = HASH_ALGO_MD5; - ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; + ctx->cert->sig.hash_algo = "md4"; + ctx->cert->sig.pkey_algo = "rsa"; break; case OID_sha1WithRSAEncryption: - ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA1; - ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; + ctx->cert->sig.hash_algo = "sha1"; + ctx->cert->sig.pkey_algo = "rsa"; break; case OID_sha256WithRSAEncryption: - ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA256; - ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; + ctx->cert->sig.hash_algo = "sha256"; + ctx->cert->sig.pkey_algo = "rsa"; break; case OID_sha384WithRSAEncryption: - ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA384; - ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; + ctx->cert->sig.hash_algo = "sha384"; + ctx->cert->sig.pkey_algo = "rsa"; break; case OID_sha512WithRSAEncryption: - ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA512; - ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; + ctx->cert->sig.hash_algo = "sha512"; + ctx->cert->sig.pkey_algo = "rsa"; break; case OID_sha224WithRSAEncryption: - ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA224; - ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; + ctx->cert->sig.hash_algo = "sha224"; + ctx->cert->sig.pkey_algo = "rsa"; break; } @@ -396,7 +396,7 @@ int x509_extract_key_data(void *context, size_t hdrlen, if (ctx->last_oid != OID_rsaEncryption) return -ENOPKG; - ctx->cert->pub->pkey_algo = PKEY_ALGO_RSA; + ctx->cert->pub->pkey_algo = "rsa"; /* Discard the BIT STRING metadata */ ctx->key = value + 1; diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 7092d5cbb5d3..733c046aacc6 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -176,7 +176,7 @@ int x509_get_sig_params(struct x509_certificate *cert) /* Allocate the hashing algorithm we're going to need and find out how * big the hash operational data will be. */ - tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0); + tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0); if (IS_ERR(tfm)) { if (PTR_ERR(tfm) == -ENOENT) { cert->unsupported_crypto = true; @@ -291,21 +291,20 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) pr_devel("Cert Issuer: %s\n", cert->issuer); pr_devel("Cert Subject: %s\n", cert->subject); - if (cert->pub->pkey_algo >= PKEY_ALGO__LAST || - cert->sig.pkey_algo >= PKEY_ALGO__LAST || - cert->sig.pkey_hash_algo >= PKEY_HASH__LAST || - !hash_algo_name[cert->sig.pkey_hash_algo]) { + if (!cert->pub->pkey_algo || + !cert->sig.pkey_algo || + !cert->sig.hash_algo) { ret = -ENOPKG; goto error_free_cert; } - pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pub->pkey_algo]); + pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo); pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to); pr_devel("Cert Signature: %s + %s\n", - pkey_algo_name[cert->sig.pkey_algo], - hash_algo_name[cert->sig.pkey_hash_algo]); + cert->sig.pkey_algo, + cert->sig.hash_algo); - cert->pub->id_type = PKEY_ID_X509; + cert->pub->id_type = "X509"; /* Check the signature on the key if it appears to be self-signed */ if ((!cert->akid_skid && !cert->akid_id) || diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index 80ab099a3edf..aa730ea7faf8 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -14,28 +14,6 @@ #ifndef _LINUX_PUBLIC_KEY_H #define _LINUX_PUBLIC_KEY_H -#include - -enum pkey_algo { - PKEY_ALGO_DSA, - PKEY_ALGO_RSA, - PKEY_ALGO__LAST -}; - -extern const char *const pkey_algo_name[PKEY_ALGO__LAST]; - -/* asymmetric key implementation supports only up to SHA224 */ -#define PKEY_HASH__LAST (HASH_ALGO_SHA224 + 1) - -enum pkey_id_type { - PKEY_ID_PGP, /* OpenPGP generated key ID */ - PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ - PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ - PKEY_ID_TYPE__LAST -}; - -extern const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST]; - /* * The use to which an asymmetric key is being put. */ @@ -59,8 +37,8 @@ extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR]; struct public_key { void *key; u32 keylen; - enum pkey_algo pkey_algo : 8; - enum pkey_id_type id_type : 8; + const char *id_type; + const char *pkey_algo; }; extern void public_key_destroy(void *payload); @@ -73,8 +51,8 @@ struct public_key_signature { u32 s_size; /* Number of bytes in signature */ u8 *digest; u8 digest_size; /* Number of bytes in digest */ - enum pkey_algo pkey_algo : 8; - enum hash_algo pkey_hash_algo : 8; + const char *pkey_algo; + const char *hash_algo; }; extern struct asymmetric_key_subtype public_key_subtype; diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 9cfa46d8d14f..64b9dead4a07 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -16,6 +16,12 @@ #include #include "module-internal.h" +enum pkey_id_type { + PKEY_ID_PGP, /* OpenPGP generated key ID */ + PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ + PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ +}; + /* * Module signature information block. * diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 69a92e6db23d..80052ed8d467 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -94,7 +95,7 @@ int asymmetric_verify(struct key *keyring, const char *sig, if (siglen != __be16_to_cpu(hdr->sig_size)) return -EBADMSG; - if (hdr->hash_algo >= PKEY_HASH__LAST) + if (hdr->hash_algo >= HASH_ALGO__LAST) return -ENOPKG; key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); @@ -103,8 +104,8 @@ int asymmetric_verify(struct key *keyring, const char *sig, memset(&pks, 0, sizeof(pks)); - pks.pkey_algo = PKEY_ALGO_RSA; - pks.pkey_hash_algo = hdr->hash_algo; + pks.pkey_algo = "rsa"; + pks.hash_algo = hash_algo_name[hdr->hash_algo]; pks.digest = (u8 *)data; pks.digest_size = datalen; pks.s = hdr->sig; diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 5efe2ecc538d..c7708d9a1b41 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -94,7 +94,7 @@ struct ima_digest_data { struct signature_v2_hdr { uint8_t type; /* xattr type */ uint8_t version; /* signature format version */ - uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */ + uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */ uint32_t keyid; /* IMA key identifier - not X509/PGP specific */ uint16_t sig_size; /* signature size */ uint8_t sig[0]; /* signature payload */ -- cgit v1.2.3