11e562deaSLukas Wunner // SPDX-License-Identifier: GPL-2.0-or-later
21e562deaSLukas Wunner /*
31e562deaSLukas Wunner * RSA Signature Scheme with Appendix - PKCS #1 v1.5 (RFC 8017 sec 8.2)
41e562deaSLukas Wunner *
51e562deaSLukas Wunner * https://www.rfc-editor.org/rfc/rfc8017#section-8.2
61e562deaSLukas Wunner *
71e562deaSLukas Wunner * Copyright (c) 2015 - 2024 Intel Corporation
81e562deaSLukas Wunner */
91e562deaSLukas Wunner
101e562deaSLukas Wunner #include <linux/module.h>
111e562deaSLukas Wunner #include <linux/scatterlist.h>
121e562deaSLukas Wunner #include <crypto/akcipher.h>
131e562deaSLukas Wunner #include <crypto/algapi.h>
145e00481bSLukas Wunner #include <crypto/hash.h>
151e562deaSLukas Wunner #include <crypto/sig.h>
161e562deaSLukas Wunner #include <crypto/internal/akcipher.h>
171e562deaSLukas Wunner #include <crypto/internal/rsa.h>
181e562deaSLukas Wunner #include <crypto/internal/sig.h>
191e562deaSLukas Wunner
201e562deaSLukas Wunner /*
211e562deaSLukas Wunner * Full Hash Prefix for EMSA-PKCS1-v1_5 encoding method (RFC 9580 table 24)
221e562deaSLukas Wunner *
231e562deaSLukas Wunner * RSA keys are usually much larger than the hash of the message to be signed.
241e562deaSLukas Wunner * The hash is therefore prepended by the Full Hash Prefix and a 0xff padding.
251e562deaSLukas Wunner * The Full Hash Prefix is an ASN.1 SEQUENCE containing the hash algorithm OID.
261e562deaSLukas Wunner *
271e562deaSLukas Wunner * https://www.rfc-editor.org/rfc/rfc9580#table-24
281e562deaSLukas Wunner */
291e562deaSLukas Wunner
30a03a728eSLukas Wunner static const u8 hash_prefix_none[] = { };
31a03a728eSLukas Wunner
321e562deaSLukas Wunner static const u8 hash_prefix_md5[] = {
331e562deaSLukas Wunner 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, /* SEQUENCE (SEQUENCE (OID */
341e562deaSLukas Wunner 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* <algorithm>, */
351e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x10 /* NULL), OCTET STRING <hash>) */
361e562deaSLukas Wunner };
371e562deaSLukas Wunner
381e562deaSLukas Wunner static const u8 hash_prefix_sha1[] = {
391e562deaSLukas Wunner 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
401e562deaSLukas Wunner 0x2b, 0x0e, 0x03, 0x02, 0x1a,
411e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x14
421e562deaSLukas Wunner };
431e562deaSLukas Wunner
441e562deaSLukas Wunner static const u8 hash_prefix_rmd160[] = {
451e562deaSLukas Wunner 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
461e562deaSLukas Wunner 0x2b, 0x24, 0x03, 0x02, 0x01,
471e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x14
481e562deaSLukas Wunner };
491e562deaSLukas Wunner
501e562deaSLukas Wunner static const u8 hash_prefix_sha224[] = {
511e562deaSLukas Wunner 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
521e562deaSLukas Wunner 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
531e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x1c
541e562deaSLukas Wunner };
551e562deaSLukas Wunner
561e562deaSLukas Wunner static const u8 hash_prefix_sha256[] = {
571e562deaSLukas Wunner 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
581e562deaSLukas Wunner 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
591e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x20
601e562deaSLukas Wunner };
611e562deaSLukas Wunner
621e562deaSLukas Wunner static const u8 hash_prefix_sha384[] = {
631e562deaSLukas Wunner 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
641e562deaSLukas Wunner 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
651e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x30
661e562deaSLukas Wunner };
671e562deaSLukas Wunner
681e562deaSLukas Wunner static const u8 hash_prefix_sha512[] = {
691e562deaSLukas Wunner 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
701e562deaSLukas Wunner 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
711e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x40
721e562deaSLukas Wunner };
731e562deaSLukas Wunner
741e562deaSLukas Wunner static const u8 hash_prefix_sha3_256[] = {
751e562deaSLukas Wunner 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
761e562deaSLukas Wunner 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08,
771e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x20
781e562deaSLukas Wunner };
791e562deaSLukas Wunner
801e562deaSLukas Wunner static const u8 hash_prefix_sha3_384[] = {
811e562deaSLukas Wunner 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
821e562deaSLukas Wunner 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09,
831e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x30
841e562deaSLukas Wunner };
851e562deaSLukas Wunner
861e562deaSLukas Wunner static const u8 hash_prefix_sha3_512[] = {
871e562deaSLukas Wunner 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
881e562deaSLukas Wunner 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0a,
891e562deaSLukas Wunner 0x05, 0x00, 0x04, 0x40
901e562deaSLukas Wunner };
911e562deaSLukas Wunner
921e562deaSLukas Wunner static const struct hash_prefix {
931e562deaSLukas Wunner const char *name;
941e562deaSLukas Wunner const u8 *data;
951e562deaSLukas Wunner size_t size;
961e562deaSLukas Wunner } hash_prefixes[] = {
971e562deaSLukas Wunner #define _(X) { #X, hash_prefix_##X, sizeof(hash_prefix_##X) }
98a03a728eSLukas Wunner _(none),
991e562deaSLukas Wunner _(md5),
1001e562deaSLukas Wunner _(sha1),
1011e562deaSLukas Wunner _(rmd160),
1021e562deaSLukas Wunner _(sha256),
1031e562deaSLukas Wunner _(sha384),
1041e562deaSLukas Wunner _(sha512),
1051e562deaSLukas Wunner _(sha224),
1061e562deaSLukas Wunner #undef _
1071e562deaSLukas Wunner #define _(X) { "sha3-" #X, hash_prefix_sha3_##X, sizeof(hash_prefix_sha3_##X) }
1081e562deaSLukas Wunner _(256),
1091e562deaSLukas Wunner _(384),
1101e562deaSLukas Wunner _(512),
1111e562deaSLukas Wunner #undef _
1121e562deaSLukas Wunner { NULL }
1131e562deaSLukas Wunner };
1141e562deaSLukas Wunner
rsassa_pkcs1_find_hash_prefix(const char * name)1151e562deaSLukas Wunner static const struct hash_prefix *rsassa_pkcs1_find_hash_prefix(const char *name)
1161e562deaSLukas Wunner {
1171e562deaSLukas Wunner const struct hash_prefix *p;
1181e562deaSLukas Wunner
1191e562deaSLukas Wunner for (p = hash_prefixes; p->name; p++)
1201e562deaSLukas Wunner if (strcmp(name, p->name) == 0)
1211e562deaSLukas Wunner return p;
1221e562deaSLukas Wunner return NULL;
1231e562deaSLukas Wunner }
1241e562deaSLukas Wunner
rsassa_pkcs1_invalid_hash_len(unsigned int len,const struct hash_prefix * p)125a03a728eSLukas Wunner static bool rsassa_pkcs1_invalid_hash_len(unsigned int len,
126a03a728eSLukas Wunner const struct hash_prefix *p)
1275e00481bSLukas Wunner {
1285e00481bSLukas Wunner /*
129a03a728eSLukas Wunner * Legacy protocols such as TLS 1.1 or earlier and IKE version 1
130a03a728eSLukas Wunner * do not prepend a Full Hash Prefix to the hash. In that case,
131a03a728eSLukas Wunner * the size of the Full Hash Prefix is zero.
132a03a728eSLukas Wunner */
133a03a728eSLukas Wunner if (p->data == hash_prefix_none)
134a03a728eSLukas Wunner return false;
135a03a728eSLukas Wunner
136a03a728eSLukas Wunner /*
1375e00481bSLukas Wunner * The final byte of the Full Hash Prefix encodes the hash length.
1385e00481bSLukas Wunner *
1395e00481bSLukas Wunner * This needs to be revisited should hash algorithms with more than
1405e00481bSLukas Wunner * 1016 bits (127 bytes * 8) ever be added. The length would then
1415e00481bSLukas Wunner * be encoded into more than one byte by ASN.1.
1425e00481bSLukas Wunner */
1435e00481bSLukas Wunner static_assert(HASH_MAX_DIGESTSIZE <= 127);
1445e00481bSLukas Wunner
145a03a728eSLukas Wunner return len != p->data[p->size - 1];
1465e00481bSLukas Wunner }
1475e00481bSLukas Wunner
1481e562deaSLukas Wunner struct rsassa_pkcs1_ctx {
1491e562deaSLukas Wunner struct crypto_akcipher *child;
1501e562deaSLukas Wunner unsigned int key_size;
1511e562deaSLukas Wunner };
1521e562deaSLukas Wunner
1531e562deaSLukas Wunner struct rsassa_pkcs1_inst_ctx {
1541e562deaSLukas Wunner struct crypto_akcipher_spawn spawn;
1551e562deaSLukas Wunner const struct hash_prefix *hash_prefix;
1561e562deaSLukas Wunner };
1571e562deaSLukas Wunner
rsassa_pkcs1_sign(struct crypto_sig * tfm,const void * src,unsigned int slen,void * dst,unsigned int dlen)1581e562deaSLukas Wunner static int rsassa_pkcs1_sign(struct crypto_sig *tfm,
1591e562deaSLukas Wunner const void *src, unsigned int slen,
1601e562deaSLukas Wunner void *dst, unsigned int dlen)
1611e562deaSLukas Wunner {
1621e562deaSLukas Wunner struct sig_instance *inst = sig_alg_instance(tfm);
1631e562deaSLukas Wunner struct rsassa_pkcs1_inst_ctx *ictx = sig_instance_ctx(inst);
1641e562deaSLukas Wunner const struct hash_prefix *hash_prefix = ictx->hash_prefix;
1651e562deaSLukas Wunner struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
1661e562deaSLukas Wunner unsigned int pad_len;
1671e562deaSLukas Wunner unsigned int ps_end;
1681e562deaSLukas Wunner unsigned int len;
1691e562deaSLukas Wunner u8 *in_buf;
1701e562deaSLukas Wunner int err;
1711e562deaSLukas Wunner
1721e562deaSLukas Wunner if (!ctx->key_size)
1731e562deaSLukas Wunner return -EINVAL;
1741e562deaSLukas Wunner
1751e562deaSLukas Wunner if (dlen < ctx->key_size)
1761e562deaSLukas Wunner return -EOVERFLOW;
1771e562deaSLukas Wunner
178a03a728eSLukas Wunner if (rsassa_pkcs1_invalid_hash_len(slen, hash_prefix))
1795e00481bSLukas Wunner return -EINVAL;
1805e00481bSLukas Wunner
1811e562deaSLukas Wunner if (slen + hash_prefix->size > ctx->key_size - 11)
1821e562deaSLukas Wunner return -EOVERFLOW;
1831e562deaSLukas Wunner
184778206d8SLukas Wunner pad_len = ctx->key_size - slen - hash_prefix->size - 1;
185778206d8SLukas Wunner
1861e562deaSLukas Wunner /* RFC 8017 sec 8.2.1 step 1 - EMSA-PKCS1-v1_5 encoding generation */
1878552cb04SHerbert Xu in_buf = dst;
1888552cb04SHerbert Xu memmove(in_buf + pad_len + hash_prefix->size, src, slen);
1898552cb04SHerbert Xu memcpy(in_buf + pad_len, hash_prefix->data, hash_prefix->size);
1908552cb04SHerbert Xu
191778206d8SLukas Wunner ps_end = pad_len - 1;
1921e562deaSLukas Wunner in_buf[0] = 0x01;
1931e562deaSLukas Wunner memset(in_buf + 1, 0xff, ps_end - 1);
1941e562deaSLukas Wunner in_buf[ps_end] = 0x00;
1951e562deaSLukas Wunner
1961e562deaSLukas Wunner
1978552cb04SHerbert Xu /* RFC 8017 sec 8.2.1 step 2 - RSA signature */
1988552cb04SHerbert Xu err = crypto_akcipher_sync_decrypt(ctx->child, in_buf,
1998552cb04SHerbert Xu ctx->key_size - 1, in_buf,
2008552cb04SHerbert Xu ctx->key_size);
2018552cb04SHerbert Xu if (err < 0)
2021e562deaSLukas Wunner return err;
2031e562deaSLukas Wunner
2048552cb04SHerbert Xu len = err;
2051e562deaSLukas Wunner pad_len = ctx->key_size - len;
2061e562deaSLukas Wunner
2071e562deaSLukas Wunner /* Four billion to one */
2081e562deaSLukas Wunner if (unlikely(pad_len)) {
2091e562deaSLukas Wunner memmove(dst + pad_len, dst, len);
2101e562deaSLukas Wunner memset(dst, 0, pad_len);
2111e562deaSLukas Wunner }
2121e562deaSLukas Wunner
213f4144b6bSLukas Wunner return ctx->key_size;
2141e562deaSLukas Wunner }
2151e562deaSLukas Wunner
rsassa_pkcs1_verify(struct crypto_sig * tfm,const void * src,unsigned int slen,const void * digest,unsigned int dlen)2161e562deaSLukas Wunner static int rsassa_pkcs1_verify(struct crypto_sig *tfm,
2171e562deaSLukas Wunner const void *src, unsigned int slen,
2181e562deaSLukas Wunner const void *digest, unsigned int dlen)
2191e562deaSLukas Wunner {
2201e562deaSLukas Wunner struct sig_instance *inst = sig_alg_instance(tfm);
2211e562deaSLukas Wunner struct rsassa_pkcs1_inst_ctx *ictx = sig_instance_ctx(inst);
2221e562deaSLukas Wunner const struct hash_prefix *hash_prefix = ictx->hash_prefix;
2231e562deaSLukas Wunner struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
2241e562deaSLukas Wunner unsigned int child_reqsize = crypto_akcipher_reqsize(ctx->child);
2251e562deaSLukas Wunner struct akcipher_request *child_req __free(kfree_sensitive) = NULL;
2261e562deaSLukas Wunner struct crypto_wait cwait;
2278552cb04SHerbert Xu struct scatterlist sg;
2281e562deaSLukas Wunner unsigned int dst_len;
2291e562deaSLukas Wunner unsigned int pos;
2301e562deaSLukas Wunner u8 *out_buf;
2311e562deaSLukas Wunner int err;
2321e562deaSLukas Wunner
2331e562deaSLukas Wunner /* RFC 8017 sec 8.2.2 step 1 - length checking */
2341e562deaSLukas Wunner if (!ctx->key_size ||
2351e562deaSLukas Wunner slen != ctx->key_size ||
236a03a728eSLukas Wunner rsassa_pkcs1_invalid_hash_len(dlen, hash_prefix))
2371e562deaSLukas Wunner return -EINVAL;
2381e562deaSLukas Wunner
2391e562deaSLukas Wunner /* RFC 8017 sec 8.2.2 step 2 - RSA verification */
2401e562deaSLukas Wunner child_req = kmalloc(sizeof(*child_req) + child_reqsize + ctx->key_size,
2411e562deaSLukas Wunner GFP_KERNEL);
2421e562deaSLukas Wunner if (!child_req)
2431e562deaSLukas Wunner return -ENOMEM;
2441e562deaSLukas Wunner
2451e562deaSLukas Wunner out_buf = (u8 *)(child_req + 1) + child_reqsize;
2468552cb04SHerbert Xu memcpy(out_buf, src, slen);
2471e562deaSLukas Wunner
2481e562deaSLukas Wunner crypto_init_wait(&cwait);
2498552cb04SHerbert Xu sg_init_one(&sg, out_buf, slen);
2501e562deaSLukas Wunner akcipher_request_set_tfm(child_req, ctx->child);
2518552cb04SHerbert Xu akcipher_request_set_crypt(child_req, &sg, &sg, slen, slen);
2521e562deaSLukas Wunner akcipher_request_set_callback(child_req, CRYPTO_TFM_REQ_MAY_SLEEP,
2531e562deaSLukas Wunner crypto_req_done, &cwait);
2541e562deaSLukas Wunner
2551e562deaSLukas Wunner err = crypto_akcipher_encrypt(child_req);
2561e562deaSLukas Wunner err = crypto_wait_req(err, &cwait);
2571e562deaSLukas Wunner if (err)
2581e562deaSLukas Wunner return err;
2591e562deaSLukas Wunner
2601e562deaSLukas Wunner /* RFC 8017 sec 8.2.2 step 3 - EMSA-PKCS1-v1_5 encoding verification */
2611e562deaSLukas Wunner dst_len = child_req->dst_len;
2621e562deaSLukas Wunner if (dst_len < ctx->key_size - 1)
2631e562deaSLukas Wunner return -EINVAL;
2641e562deaSLukas Wunner
2651e562deaSLukas Wunner if (dst_len == ctx->key_size) {
2661e562deaSLukas Wunner if (out_buf[0] != 0x00)
2671e562deaSLukas Wunner /* Encrypted value had no leading 0 byte */
2681e562deaSLukas Wunner return -EINVAL;
2691e562deaSLukas Wunner
2701e562deaSLukas Wunner dst_len--;
2711e562deaSLukas Wunner out_buf++;
2721e562deaSLukas Wunner }
2731e562deaSLukas Wunner
2741e562deaSLukas Wunner if (out_buf[0] != 0x01)
2751e562deaSLukas Wunner return -EBADMSG;
2761e562deaSLukas Wunner
2771e562deaSLukas Wunner for (pos = 1; pos < dst_len; pos++)
2781e562deaSLukas Wunner if (out_buf[pos] != 0xff)
2791e562deaSLukas Wunner break;
2801e562deaSLukas Wunner
2811e562deaSLukas Wunner if (pos < 9 || pos == dst_len || out_buf[pos] != 0x00)
2821e562deaSLukas Wunner return -EBADMSG;
2831e562deaSLukas Wunner pos++;
2841e562deaSLukas Wunner
2851e562deaSLukas Wunner if (hash_prefix->size > dst_len - pos)
2861e562deaSLukas Wunner return -EBADMSG;
2871e562deaSLukas Wunner if (crypto_memneq(out_buf + pos, hash_prefix->data, hash_prefix->size))
2881e562deaSLukas Wunner return -EBADMSG;
2891e562deaSLukas Wunner pos += hash_prefix->size;
2901e562deaSLukas Wunner
2911e562deaSLukas Wunner /* RFC 8017 sec 8.2.2 step 4 - comparison of digest with out_buf */
2921e562deaSLukas Wunner if (dlen != dst_len - pos)
2931e562deaSLukas Wunner return -EKEYREJECTED;
2941e562deaSLukas Wunner if (memcmp(digest, out_buf + pos, dlen) != 0)
2951e562deaSLukas Wunner return -EKEYREJECTED;
2961e562deaSLukas Wunner
2971e562deaSLukas Wunner return 0;
2981e562deaSLukas Wunner }
2991e562deaSLukas Wunner
rsassa_pkcs1_key_size(struct crypto_sig * tfm)300221f0041SLukas Wunner static unsigned int rsassa_pkcs1_key_size(struct crypto_sig *tfm)
3011e562deaSLukas Wunner {
3021e562deaSLukas Wunner struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
3031e562deaSLukas Wunner
304*6b7f9397SLukas Wunner return ctx->key_size * BITS_PER_BYTE;
3051e562deaSLukas Wunner }
3061e562deaSLukas Wunner
rsassa_pkcs1_set_pub_key(struct crypto_sig * tfm,const void * key,unsigned int keylen)3071e562deaSLukas Wunner static int rsassa_pkcs1_set_pub_key(struct crypto_sig *tfm,
3081e562deaSLukas Wunner const void *key, unsigned int keylen)
3091e562deaSLukas Wunner {
3101e562deaSLukas Wunner struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
3111e562deaSLukas Wunner
3121e562deaSLukas Wunner return rsa_set_key(ctx->child, &ctx->key_size, RSA_PUB, key, keylen);
3131e562deaSLukas Wunner }
3141e562deaSLukas Wunner
rsassa_pkcs1_set_priv_key(struct crypto_sig * tfm,const void * key,unsigned int keylen)3151e562deaSLukas Wunner static int rsassa_pkcs1_set_priv_key(struct crypto_sig *tfm,
3161e562deaSLukas Wunner const void *key, unsigned int keylen)
3171e562deaSLukas Wunner {
3181e562deaSLukas Wunner struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
3191e562deaSLukas Wunner
3201e562deaSLukas Wunner return rsa_set_key(ctx->child, &ctx->key_size, RSA_PRIV, key, keylen);
3211e562deaSLukas Wunner }
3221e562deaSLukas Wunner
rsassa_pkcs1_init_tfm(struct crypto_sig * tfm)3231e562deaSLukas Wunner static int rsassa_pkcs1_init_tfm(struct crypto_sig *tfm)
3241e562deaSLukas Wunner {
3251e562deaSLukas Wunner struct sig_instance *inst = sig_alg_instance(tfm);
3261e562deaSLukas Wunner struct rsassa_pkcs1_inst_ctx *ictx = sig_instance_ctx(inst);
3271e562deaSLukas Wunner struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
3281e562deaSLukas Wunner struct crypto_akcipher *child_tfm;
3291e562deaSLukas Wunner
3301e562deaSLukas Wunner child_tfm = crypto_spawn_akcipher(&ictx->spawn);
3311e562deaSLukas Wunner if (IS_ERR(child_tfm))
3321e562deaSLukas Wunner return PTR_ERR(child_tfm);
3331e562deaSLukas Wunner
3341e562deaSLukas Wunner ctx->child = child_tfm;
3351e562deaSLukas Wunner
3361e562deaSLukas Wunner return 0;
3371e562deaSLukas Wunner }
3381e562deaSLukas Wunner
rsassa_pkcs1_exit_tfm(struct crypto_sig * tfm)3391e562deaSLukas Wunner static void rsassa_pkcs1_exit_tfm(struct crypto_sig *tfm)
3401e562deaSLukas Wunner {
3411e562deaSLukas Wunner struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
3421e562deaSLukas Wunner
3431e562deaSLukas Wunner crypto_free_akcipher(ctx->child);
3441e562deaSLukas Wunner }
3451e562deaSLukas Wunner
rsassa_pkcs1_free(struct sig_instance * inst)3461e562deaSLukas Wunner static void rsassa_pkcs1_free(struct sig_instance *inst)
3471e562deaSLukas Wunner {
3481e562deaSLukas Wunner struct rsassa_pkcs1_inst_ctx *ctx = sig_instance_ctx(inst);
3491e562deaSLukas Wunner struct crypto_akcipher_spawn *spawn = &ctx->spawn;
3501e562deaSLukas Wunner
3511e562deaSLukas Wunner crypto_drop_akcipher(spawn);
3521e562deaSLukas Wunner kfree(inst);
3531e562deaSLukas Wunner }
3541e562deaSLukas Wunner
rsassa_pkcs1_create(struct crypto_template * tmpl,struct rtattr ** tb)3551e562deaSLukas Wunner static int rsassa_pkcs1_create(struct crypto_template *tmpl, struct rtattr **tb)
3561e562deaSLukas Wunner {
3571e562deaSLukas Wunner struct rsassa_pkcs1_inst_ctx *ctx;
3581e562deaSLukas Wunner struct akcipher_alg *rsa_alg;
3591e562deaSLukas Wunner struct sig_instance *inst;
3601e562deaSLukas Wunner const char *hash_name;
3611e562deaSLukas Wunner u32 mask;
3621e562deaSLukas Wunner int err;
3631e562deaSLukas Wunner
3641e562deaSLukas Wunner err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SIG, &mask);
3651e562deaSLukas Wunner if (err)
3661e562deaSLukas Wunner return err;
3671e562deaSLukas Wunner
3681e562deaSLukas Wunner inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
3691e562deaSLukas Wunner if (!inst)
3701e562deaSLukas Wunner return -ENOMEM;
3711e562deaSLukas Wunner
3721e562deaSLukas Wunner ctx = sig_instance_ctx(inst);
3731e562deaSLukas Wunner
3741e562deaSLukas Wunner err = crypto_grab_akcipher(&ctx->spawn, sig_crypto_instance(inst),
3751e562deaSLukas Wunner crypto_attr_alg_name(tb[1]), 0, mask);
3761e562deaSLukas Wunner if (err)
3771e562deaSLukas Wunner goto err_free_inst;
3781e562deaSLukas Wunner
3791e562deaSLukas Wunner rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
3801e562deaSLukas Wunner
3811e562deaSLukas Wunner if (strcmp(rsa_alg->base.cra_name, "rsa") != 0) {
3821e562deaSLukas Wunner err = -EINVAL;
3831e562deaSLukas Wunner goto err_free_inst;
3841e562deaSLukas Wunner }
3851e562deaSLukas Wunner
3861e562deaSLukas Wunner hash_name = crypto_attr_alg_name(tb[2]);
3871e562deaSLukas Wunner if (IS_ERR(hash_name)) {
3881e562deaSLukas Wunner err = PTR_ERR(hash_name);
3891e562deaSLukas Wunner goto err_free_inst;
3901e562deaSLukas Wunner }
3911e562deaSLukas Wunner
3921e562deaSLukas Wunner ctx->hash_prefix = rsassa_pkcs1_find_hash_prefix(hash_name);
3931e562deaSLukas Wunner if (!ctx->hash_prefix) {
3941e562deaSLukas Wunner err = -EINVAL;
3951e562deaSLukas Wunner goto err_free_inst;
3961e562deaSLukas Wunner }
3971e562deaSLukas Wunner
3981e562deaSLukas Wunner err = -ENAMETOOLONG;
3991e562deaSLukas Wunner if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
4001e562deaSLukas Wunner "pkcs1(%s,%s)", rsa_alg->base.cra_name,
4011e562deaSLukas Wunner hash_name) >= CRYPTO_MAX_ALG_NAME)
4021e562deaSLukas Wunner goto err_free_inst;
4031e562deaSLukas Wunner
4041e562deaSLukas Wunner if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
4051e562deaSLukas Wunner "pkcs1(%s,%s)", rsa_alg->base.cra_driver_name,
4061e562deaSLukas Wunner hash_name) >= CRYPTO_MAX_ALG_NAME)
4071e562deaSLukas Wunner goto err_free_inst;
4081e562deaSLukas Wunner
4091e562deaSLukas Wunner inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
4101e562deaSLukas Wunner inst->alg.base.cra_ctxsize = sizeof(struct rsassa_pkcs1_ctx);
4111e562deaSLukas Wunner
4121e562deaSLukas Wunner inst->alg.init = rsassa_pkcs1_init_tfm;
4131e562deaSLukas Wunner inst->alg.exit = rsassa_pkcs1_exit_tfm;
4141e562deaSLukas Wunner
4151e562deaSLukas Wunner inst->alg.sign = rsassa_pkcs1_sign;
4161e562deaSLukas Wunner inst->alg.verify = rsassa_pkcs1_verify;
417221f0041SLukas Wunner inst->alg.key_size = rsassa_pkcs1_key_size;
4181e562deaSLukas Wunner inst->alg.set_pub_key = rsassa_pkcs1_set_pub_key;
4191e562deaSLukas Wunner inst->alg.set_priv_key = rsassa_pkcs1_set_priv_key;
4201e562deaSLukas Wunner
4211e562deaSLukas Wunner inst->free = rsassa_pkcs1_free;
4221e562deaSLukas Wunner
4231e562deaSLukas Wunner err = sig_register_instance(tmpl, inst);
4241e562deaSLukas Wunner if (err) {
4251e562deaSLukas Wunner err_free_inst:
4261e562deaSLukas Wunner rsassa_pkcs1_free(inst);
4271e562deaSLukas Wunner }
4281e562deaSLukas Wunner return err;
4291e562deaSLukas Wunner }
4301e562deaSLukas Wunner
4311e562deaSLukas Wunner struct crypto_template rsassa_pkcs1_tmpl = {
4321e562deaSLukas Wunner .name = "pkcs1",
4331e562deaSLukas Wunner .create = rsassa_pkcs1_create,
4341e562deaSLukas Wunner .module = THIS_MODULE,
4351e562deaSLukas Wunner };
4361e562deaSLukas Wunner
4371e562deaSLukas Wunner MODULE_ALIAS_CRYPTO("pkcs1");
438