-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;
-
- /* initlialzie out buf */
- 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 (!RSA_ASN1_templates[sig->pkey_hash_algo].data)
+ return -ENOTSUPP;
+
+ /* (1) Check the signature size against the public key modulus size */
+ k = mpi_get_nbits(key->rsa.n);
+ tsize = mpi_get_nbits(sig->rsa.s);
+
+ /* According to RFC 4880 sec 3.2, length of MPI is computed starting
+ * from most significant bit. So the RFC 3447 sec 8.2.2 size check
+ * must be relaxed to conform with shorter signatures - so we fail here
+ * only if signature length is longer than modulus size.
+ */
+ pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize);
+ if (k < tsize) {
+ ret = -EBADMSG;
+ goto error;