@@ -33,13 +33,18 @@ obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
$(obj)/rsapubkey.asn1.o: $(obj)/rsapubkey.asn1.c $(obj)/rsapubkey.asn1.h
$(obj)/rsaprivkey.asn1.o: $(obj)/rsaprivkey.asn1.c $(obj)/rsaprivkey.asn1.h
-$(obj)/rsa_helper.o: $(obj)/rsapubkey.asn1.h $(obj)/rsaprivkey.asn1.h
+$(obj)/rsapss_params.asn1.o: $(obj)/rsapss_params.asn1.c \
+ $(obj)/rsapss_params.asn1.h
+$(obj)/rsa_helper.o: $(obj)/rsapubkey.asn1.h $(obj)/rsaprivkey.asn1.h \
+ $(obj)/rsapss_params.asn1.h
rsa_generic-y := rsapubkey.asn1.o
rsa_generic-y += rsaprivkey.asn1.o
+rsa_generic-y += rsapss_params.asn1.o
rsa_generic-y += rsa.o
rsa_generic-y += rsa_helper.o
rsa_generic-y += rsa-pkcs1pad.o
+rsa_generic-y += rsa-psspad.o
obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
$(obj)/sm2signature.asn1.o: $(obj)/sm2signature.asn1.c $(obj)/sm2signature.asn1.h
@@ -6,18 +6,11 @@
*/
#include <linux/module.h>
-#include <linux/mpi.h>
#include <crypto/internal/rsa.h>
#include <crypto/internal/akcipher.h>
#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;
@@ -269,12 +262,19 @@ static int rsa_init(void)
return err;
}
+ err = crypto_register_template(&rsa_psspad_tmpl);
+ if (err) {
+ crypto_unregister_akcipher(&rsa);
+ return err;
+ }
+
return 0;
}
static void rsa_exit(void)
{
crypto_unregister_template(&rsa_pkcs1pad_tmpl);
+ crypto_unregister_template(&rsa_psspad_tmpl);
crypto_unregister_akcipher(&rsa);
}
@@ -12,6 +12,7 @@
#include <crypto/internal/rsa.h>
#include "rsapubkey.asn1.h"
#include "rsaprivkey.asn1.h"
+#include "rsapss_params.asn1.h"
int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
const void *value, size_t vlen)
@@ -148,6 +149,115 @@ int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag,
return 0;
}
+int rsa_get_pss_hash(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsa_pss_ctx *ctx = context;
+ enum OID oid;
+
+ if (!value || !vlen)
+ return -EINVAL;
+
+ oid = look_up_OID(value, vlen);
+ switch (oid) {
+ case OID_sha1:
+ ctx->hash_algo = "sha1";
+ break;
+ case OID_sha224:
+ ctx->hash_algo = "sha224";
+ break;
+ case OID_sha256:
+ ctx->hash_algo = "sha256";
+ break;
+ case OID_sha384:
+ ctx->hash_algo = "sha384";
+ break;
+ case OID_sha512:
+ ctx->hash_algo = "sha512";
+ break;
+ default:
+ return -ENOPKG;
+
+ }
+
+ return 0;
+}
+
+int rsa_get_pss_mgf(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsa_pss_ctx *ctx = context;
+ enum OID oid;
+
+ if (!value || !vlen)
+ return -EINVAL;
+
+ oid = look_up_OID(value, vlen);
+ if (oid != OID_rsa_mgf1)
+ return -ENOPKG;
+ ctx->mgf_algo = "mgf1";
+
+ return 0;
+}
+
+int rsa_get_pss_mgf_hash(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsa_pss_ctx *ctx = context;
+ enum OID oid;
+
+ if (!value || !vlen)
+ return -EINVAL;
+ /* todo, merge with get_pss_hash */
+ oid = look_up_OID(value, vlen);
+ switch (oid) {
+ case OID_sha1:
+ ctx->mgf_hash_algo = "sha1";
+ break;
+ case OID_sha224:
+ ctx->mgf_hash_algo = "sha224";
+ break;
+ case OID_sha256:
+ ctx->mgf_hash_algo = "sha256";
+ break;
+ case OID_sha384:
+ ctx->mgf_hash_algo = "sha384";
+ break;
+ case OID_sha512:
+ ctx->mgf_hash_algo = "sha512";
+ break;
+ default:
+ return -ENOPKG;
+ }
+
+ return 0;
+}
+
+int rsa_get_pss_saltlen(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsa_pss_ctx *ctx = context;
+
+ if (!value || vlen < 1 || vlen > 2)
+ return -EINVAL;
+
+ if (vlen == 1)
+ ctx->salt_len = *(u8 *)value;
+ else if (vlen == 2)
+ ctx->salt_len = ntohs(*(u16 *)value);
+
+ return 0;
+}
+
+int rsa_get_pss_trailerfield(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ if (!value || !vlen || *(u8 *)value != 1)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
* provided struct rsa_key, pointers to the raw key as is,
@@ -184,3 +294,20 @@ 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);
+
+/**
+ * rsa_parse_pss_params() - decodes the BER encoded pss padding params
+ *
+ * @ctx: struct rsa_pss_ctx, pss padding context
+ * @params: params in BER format
+ * @params_len: length of params
+ *
+ * Return: 0 on success or error code in case of error
+ */
+int rsa_parse_pss_params(struct rsa_pss_ctx *ctx, const void *params,
+ unsigned int params_len)
+{
+ return asn1_ber_decoder(&rsapss_params_decoder, ctx, params,
+ params_len);
+}
+EXPORT_SYMBOL_GPL(rsa_parse_pss_params);
new file mode 100644
@@ -0,0 +1,21 @@
+-- rfc4055 section 3.1.
+
+RSAPSS_Params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm OPTIONAL,
+ maskGenAlgorithm [1] MaskGenAlgorithm OPTIONAL,
+ saltLen [2] INTEGER OPTIONAL ({ rsa_get_pss_saltlen }),
+ trailerField [3] INTEGER OPTIONAL ({ rsa_get_pss_trailerfield })
+ }
+
+HashAlgorithm ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER ({ rsa_get_pss_hash })
+ }
+
+MaskGenAlgorithm ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER ({ rsa_get_pss_mgf }),
+ hashAlgorithm MgfHashAlgorithm
+ }
+
+MgfHashAlgorithm ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER ({ rsa_get_pss_mgf_hash })
+ }
@@ -8,6 +8,12 @@
#ifndef _RSA_HELPER_
#define _RSA_HELPER_
#include <linux/types.h>
+#include <linux/mpi.h>
+#include <linux/oid_registry.h>
+#include <crypto/sha2.h>
+
+#define RSA_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
+#define RSA_PSS_DEFAULT_SALT_LEN 20
/**
* rsa_key - RSA key structure
@@ -47,11 +53,28 @@ struct rsa_key {
size_t qinv_sz;
};
+struct rsa_mpi_key {
+ MPI n;
+ MPI e;
+ MPI d;
+};
+
+struct rsa_pss_ctx {
+ struct crypto_akcipher *child;
+ unsigned int key_size;
+ const char *hash_algo;
+ const char *mgf_algo;
+ const char *mgf_hash_algo;
+ u32 salt_len;
+};
+
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len);
int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len);
-
+int rsa_parse_pss_params(struct rsa_pss_ctx *ctx, const void *params,
+ unsigned int params_len);
extern struct crypto_template rsa_pkcs1pad_tmpl;
+extern struct crypto_template rsa_psspad_tmpl;
#endif
This patch add the support of rsa-pss encoding which is described rfc8017. Similar to rsa-pkcs1, we create a pss template. Signed-off-by: Hongbo Li <herbert.tencent@gmail.com> --- crypto/Makefile | 7 ++- crypto/rsa.c | 14 ++--- crypto/rsa_helper.c | 127 ++++++++++++++++++++++++++++++++++++++++++ crypto/rsapss_params.asn1 | 21 +++++++ include/crypto/internal/rsa.h | 25 ++++++++- 5 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 crypto/rsapss_params.asn1