posix-cpu-timers: Move state tracking to struct posix_cputimers
[sfrench/cifs-2.6.git] / crypto / rsa-pkcs1pad.c
index 0a6680ca8cb6fc09b003806d0b40c5561c8526dc..0aa489711ec497b53309a7c44fe87ec00faffe5a 100644 (file)
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * RSA padding templates.
  *
  * Copyright (c) 2015  Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
  */
 
 #include <crypto/algapi.h>
@@ -429,7 +425,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
        akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
                                   req->dst, ctx->key_size - 1, req->dst_len);
 
-       err = crypto_akcipher_sign(&req_ctx->child_req);
+       err = crypto_akcipher_decrypt(&req_ctx->child_req);
        if (err != -EINPROGRESS && err != -EBUSY)
                return pkcs1pad_encrypt_sign_complete(req, err);
 
@@ -488,14 +484,21 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
 
        err = 0;
 
-       if (req->dst_len < dst_len - pos)
-               err = -EOVERFLOW;
-       req->dst_len = dst_len - pos;
-
-       if (!err)
-               sg_copy_from_buffer(req->dst,
-                               sg_nents_for_len(req->dst, req->dst_len),
-                               out_buf + pos, req->dst_len);
+       if (req->dst_len != dst_len - pos) {
+               err = -EKEYREJECTED;
+               req->dst_len = dst_len - pos;
+               goto done;
+       }
+       /* Extract appended digest. */
+       sg_pcopy_to_buffer(req->src,
+                          sg_nents_for_len(req->src,
+                                           req->src_len + req->dst_len),
+                          req_ctx->out_buf + ctx->key_size,
+                          req->dst_len, ctx->key_size);
+       /* Do the actual verification step. */
+       if (memcmp(req_ctx->out_buf + ctx->key_size, out_buf + pos,
+                  req->dst_len) != 0)
+               err = -EKEYREJECTED;
 done:
        kzfree(req_ctx->out_buf);
 
@@ -532,10 +535,12 @@ static int pkcs1pad_verify(struct akcipher_request *req)
        struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
        int err;
 
-       if (!ctx->key_size || req->src_len < ctx->key_size)
+       if (WARN_ON(req->dst) ||
+           WARN_ON(!req->dst_len) ||
+           !ctx->key_size || req->src_len < ctx->key_size)
                return -EINVAL;
 
-       req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL);
+       req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL);
        if (!req_ctx->out_buf)
                return -ENOMEM;
 
@@ -551,7 +556,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
                                   req_ctx->out_sg, req->src_len,
                                   ctx->key_size);
 
-       err = crypto_akcipher_verify(&req_ctx->child_req);
+       err = crypto_akcipher_encrypt(&req_ctx->child_req);
        if (err != -EINPROGRESS && err != -EBUSY)
                return pkcs1pad_verify_complete(req, err);