/* * The verify operation is here for completeness similar to the verification * defined in RFC2313 section 10.2 except that block type 0 is not accepted, * as in RFC2437. RFC2437 section 9.2 doesn't define any operation to * retrieve the DigestInfo from a signature, instead the user is expected * to call the sign operation to generate the expected signature and compare * signatures instead of the message-digests. */ static int pkcs1pad_verify(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); int err; if (!ctx->key_size || req->src_len < ctx->key_size) return -EINVAL; req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL); if (!req_ctx->out_buf) return -ENOMEM; pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf, ctx->key_size, NULL); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, pkcs1pad_verify_complete_cb, req); /* Reuse input buffer, output to a new buffer */ akcipher_request_set_crypt(&req_ctx->child_req, req->src, req_ctx->out_sg, req->src_len, ctx->key_size); err = crypto_akcipher_verify(&req_ctx->child_req); if (err != -EINPROGRESS && err != -EBUSY) return pkcs1pad_verify_complete(req, err); return err; }
static void pkcs1pad_verify_complete_cb( struct crypto_async_request *child_async_req, int err) { struct akcipher_request *req = child_async_req->data; struct crypto_async_request async_req; if (err == -EINPROGRESS) return; async_req.data = req->base.data; async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req)); async_req.flags = child_async_req->flags; req->base.complete(&async_req, pkcs1pad_verify_complete(req, err)); }
/* * The verify operation is here for completeness similar to the verification * defined in RFC2313 section 10.2 except that block type 0 is not accepted, * as in RFC2437. RFC2437 section 9.2 doesn't define any operation to * retrieve the DigestInfo from a signature, instead the user is expected * to call the sign operation to generate the expected signature and compare * signatures instead of the message-digests. */ static int pkcs1pad_verify(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); int err; if (!ctx->key_size || req->src_len < ctx->key_size) return -EINVAL; if (ctx->key_size > PAGE_SIZE) return -ENOTSUPP; /* Reuse input buffer, output to a new buffer */ req_ctx->child_req.src = req->src; req_ctx->child_req.src_len = req->src_len; req_ctx->child_req.dst = req_ctx->out_sg; req_ctx->child_req.dst_len = ctx->key_size - 1; req_ctx->out_buf = kmalloc(ctx->key_size - 1, (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC); if (!req_ctx->out_buf) return -ENOMEM; pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf, ctx->key_size - 1, NULL); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, pkcs1pad_verify_complete_cb, req); err = crypto_akcipher_verify(&req_ctx->child_req); if (err != -EINPROGRESS && (err != -EBUSY || !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))) return pkcs1pad_verify_complete(req, err); return err; }