Commit 35717cff authored by Roberto Sassu's avatar Roberto Sassu Committed by zgzxx
Browse files

rsa: add parser of raw format

euleros inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I91FSN


CVE: NA

-------------------------------------------------

Parse the RSA key with RAW format if the ASN.1 parser returns an error.

v4:
 - fix checkpatch warning MISSING_EOF_NEWLINE in crypto/rsa_helper.c
   (zhangguangzhi)

Signed-off-by: default avatarRoberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: default avatarTianxing Zhang <zhangtianxing3@huawei.com>
Reviewed-by: default avatarJason Yan <yanaijie@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: default avatarzhoushuiqing <zhoushuiqing2@huawei.com>
Signed-off-by: default avatarzhangguangzhi <zhangguangzhi3@huawei.com>
parent 3f5238f5
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -242,8 +242,16 @@ static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
	rsa_free_mpi_key(mpi_key);

	ret = rsa_parse_pub_key(&raw_key, key, keylen);
#ifdef CONFIG_PGP_LIBRARY
	if (ret) {
		ret = rsa_parse_pub_key_raw(&raw_key, key, keylen);
		if (ret)
			return ret;
	}
#else
	if (ret)
		return ret;
#endif

	mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
	if (!mpi_key->e)
@@ -281,8 +289,16 @@ static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
	rsa_free_mpi_key(mpi_key);

	ret = rsa_parse_priv_key(&raw_key, key, keylen);
#ifdef CONFIG_PGP_LIBRARY
	if (ret) {
		ret = rsa_parse_priv_key_raw(&raw_key, key, keylen);
		if (ret)
			return ret;
	}
#else
	if (ret)
		return ret;
#endif

	mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz);
	if (!mpi_key->d)
+77 −0
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@
#include <linux/export.h>
#include <linux/err.h>
#include <linux/fips.h>
#ifdef CONFIG_PGP_LIBRARY
#include <linux/mpi.h>
#endif
#include <crypto/internal/rsa.h>
#include "rsapubkey.asn1.h"
#include "rsaprivkey.asn1.h"
@@ -148,6 +151,34 @@ int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag,
	return 0;
}

#ifdef CONFIG_PGP_LIBRARY
typedef int (*rsa_get_func)(void *, size_t, unsigned char,
			    const void *, size_t);

static int rsa_parse_key_raw(struct rsa_key *rsa_key,
			     const void *key, unsigned int key_len,
			     rsa_get_func *func, int n_func)
{
	unsigned int nbytes, len = key_len;
	const void *key_ptr = key;
	int ret, i;

	for (i = 0; i < n_func; i++) {
		ret = mpi_key_length(key_ptr, len, NULL, &nbytes);
		if (ret < 0)
			return ret;

		ret = func[i](rsa_key, 0, 0, key_ptr + 2, nbytes);
		if (ret < 0)
			return ret;

		key_ptr += nbytes + 2;
	}

	return (key_ptr == key + key_len) ? 0 : -EINVAL;
}
#endif

/**
 * rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
 *                       provided struct rsa_key, pointers to the raw key as is,
@@ -166,6 +197,28 @@ int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
}
EXPORT_SYMBOL_GPL(rsa_parse_pub_key);

#ifdef CONFIG_PGP_LIBRARY
/**
 * rsa_parse_pub_key_raw() - parse the RAW key and store in the provided struct
 *                           rsa_key, pointers to the raw key as is, so that
 *                           the caller can copy it or MPI parse it, etc.
 *
 * @rsa_key:	struct rsa_key key representation
 * @key:	key in RAW format
 * @key_len:	length of key
 *
 * Return:	0 on success or error code in case of error
 */
int rsa_parse_pub_key_raw(struct rsa_key *rsa_key, const void *key,
			  unsigned int key_len)
{
	rsa_get_func pub_func[] = {rsa_get_n, rsa_get_e};

	return rsa_parse_key_raw(rsa_key, key, key_len,
				 pub_func, ARRAY_SIZE(pub_func));
}
EXPORT_SYMBOL_GPL(rsa_parse_pub_key_raw);
#endif
/**
 * rsa_parse_priv_key() - decodes the BER encoded buffer and stores in the
 *                        provided struct rsa_key, pointers to the raw key
@@ -184,3 +237,27 @@ int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
	return asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
}
EXPORT_SYMBOL_GPL(rsa_parse_priv_key);

#ifdef CONFIG_PGP_LIBRARY
/**
 * rsa_parse_priv_key_raw() - parse the RAW key and store in the provided struct
 *                            rsa_key, pointers to the raw key as is, so that
 *                            the caller can copy it or MPI parse it, etc.
 *
 * @rsa_key:	struct rsa_key key representation
 * @key:	key in RAW format
 * @key_len:	length of key
 *
 * Return:	0 on success or error code in case of error
 */
int rsa_parse_priv_key_raw(struct rsa_key *rsa_key, const void *key,
			   unsigned int key_len)
{
	rsa_get_func priv_func[] = {rsa_get_n, rsa_get_e, rsa_get_d};

	return rsa_parse_key_raw(rsa_key, key, key_len,
				 priv_func, ARRAY_SIZE(priv_func));
}
EXPORT_SYMBOL_GPL(rsa_parse_priv_key_raw);
#endif
+10 −0
Original line number Diff line number Diff line
@@ -50,8 +50,18 @@ struct rsa_key {
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
		      unsigned int key_len);

#ifdef CONFIG_PGP_LIBRARY
int rsa_parse_pub_key_raw(struct rsa_key *rsa_key, const void *key,
			  unsigned int key_len);
#endif

int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
		       unsigned int key_len);

#ifdef CONFIG_PGP_LIBRARY
int rsa_parse_priv_key_raw(struct rsa_key *rsa_key, const void *key,
			   unsigned int key_len);
#endif

extern struct crypto_template rsa_pkcs1pad_tmpl;
#endif