Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 9 Aug 2019 16:17:05 +0000 (09:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 9 Aug 2019 16:17:05 +0000 (09:17 -0700)
Pull crypto fixes from Herbert Xu:
 "Fix a number of bugs in the ccp driver"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: ccp - Ignore tag length when decrypting GCM ciphertext
  crypto: ccp - Add support for valid authsize values less than 16
  crypto: ccp - Fix oops by properly managing allocated structures

1  2 
drivers/crypto/ccp/ccp-crypto-aes-galois.c
drivers/crypto/ccp/ccp-ops.c
include/linux/ccp.h

index f9fec2ddf56aef0e3ec72039395bc6044403f8f9,02eba84028b36fd9152cf03a6a7d91d3283abf9f..94c1ad7eeddf7ca84d11f685b90756c2edefcf2f
@@@ -1,4 -1,4 +1,4 @@@
 -// SPDX-License-Identifier: GPL-2.0
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * AMD Cryptographic Coprocessor (CCP) AES GCM crypto API support
   *
@@@ -58,6 -58,19 +58,19 @@@ static int ccp_aes_gcm_setkey(struct cr
  static int ccp_aes_gcm_setauthsize(struct crypto_aead *tfm,
                                   unsigned int authsize)
  {
+       switch (authsize) {
+       case 16:
+       case 15:
+       case 14:
+       case 13:
+       case 12:
+       case 8:
+       case 4:
+               break;
+       default:
+               return -EINVAL;
+       }
        return 0;
  }
  
@@@ -104,6 -117,7 +117,7 @@@ static int ccp_aes_gcm_crypt(struct aea
        memset(&rctx->cmd, 0, sizeof(rctx->cmd));
        INIT_LIST_HEAD(&rctx->cmd.entry);
        rctx->cmd.engine = CCP_ENGINE_AES;
+       rctx->cmd.u.aes.authsize = crypto_aead_authsize(tfm);
        rctx->cmd.u.aes.type = ctx->u.aes.type;
        rctx->cmd.u.aes.mode = ctx->u.aes.mode;
        rctx->cmd.u.aes.action = encrypt;
index c69ed4bae2eb1045dfab71f0f884954756cde4f1,76e1b4dcd1930a7dea8e4ac78d73de86eb0d138c..9bc3c62157d7dc500b3b00c3d4d74bd37d5fd531
@@@ -1,4 -1,4 +1,4 @@@
 -// SPDX-License-Identifier: GPL-2.0
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * AMD Cryptographic Coprocessor (CCP) driver
   *
@@@ -622,6 -622,7 +622,7 @@@ static int ccp_run_aes_gcm_cmd(struct c
  
        unsigned long long *final;
        unsigned int dm_offset;
+       unsigned int authsize;
        unsigned int jobid;
        unsigned int ilen;
        bool in_place = true; /* Default value */
        if (!aes->key) /* Gotta have a key SGL */
                return -EINVAL;
  
+       /* Zero defaults to 16 bytes, the maximum size */
+       authsize = aes->authsize ? aes->authsize : AES_BLOCK_SIZE;
+       switch (authsize) {
+       case 16:
+       case 15:
+       case 14:
+       case 13:
+       case 12:
+       case 8:
+       case 4:
+               break;
+       default:
+               return -EINVAL;
+       }
        /* First, decompose the source buffer into AAD & PT,
         * and the destination buffer into AAD, CT & tag, or
         * the input into CT & tag.
                p_tag = scatterwalk_ffwd(sg_tag, p_outp, ilen);
        } else {
                /* Input length for decryption includes tag */
-               ilen = aes->src_len - AES_BLOCK_SIZE;
+               ilen = aes->src_len - authsize;
                p_tag = scatterwalk_ffwd(sg_tag, p_inp, ilen);
        }
  
                while (src.sg_wa.bytes_left) {
                        ccp_prepare_data(&src, &dst, &op, AES_BLOCK_SIZE, true);
                        if (!src.sg_wa.bytes_left) {
-                               unsigned int nbytes = aes->src_len
-                                                     % AES_BLOCK_SIZE;
+                               unsigned int nbytes = ilen % AES_BLOCK_SIZE;
  
                                if (nbytes) {
                                        op.eom = 1;
  
        if (aes->action == CCP_AES_ACTION_ENCRYPT) {
                /* Put the ciphered tag after the ciphertext. */
-               ccp_get_dm_area(&final_wa, 0, p_tag, 0, AES_BLOCK_SIZE);
+               ccp_get_dm_area(&final_wa, 0, p_tag, 0, authsize);
        } else {
                /* Does this ciphered tag match the input? */
-               ret = ccp_init_dm_workarea(&tag, cmd_q, AES_BLOCK_SIZE,
+               ret = ccp_init_dm_workarea(&tag, cmd_q, authsize,
                                           DMA_BIDIRECTIONAL);
                if (ret)
                        goto e_tag;
-               ret = ccp_set_dm_area(&tag, 0, p_tag, 0, AES_BLOCK_SIZE);
+               ret = ccp_set_dm_area(&tag, 0, p_tag, 0, authsize);
                if (ret)
                        goto e_tag;
  
                ret = crypto_memneq(tag.address, final_wa.address,
-                                   AES_BLOCK_SIZE) ? -EBADMSG : 0;
+                                   authsize) ? -EBADMSG : 0;
                ccp_dm_free(&tag);
        }
  
@@@ -859,11 -874,11 +874,11 @@@ e_tag
        ccp_dm_free(&final_wa);
  
  e_dst:
-       if (aes->src_len && !in_place)
+       if (ilen > 0 && !in_place)
                ccp_free_data(&dst, cmd_q);
  
  e_src:
-       if (aes->src_len)
+       if (ilen > 0)
                ccp_free_data(&src, cmd_q);
  
  e_aad:
diff --combined include/linux/ccp.h
index 55cb455cfcb067f2ccdbdc84d6d2ba9c78deaaf8,43ed9e77cf81a6dec3fac4a8de3648d63f4d454d..a5dfbaf2470d7cbf31f8b339b469f0c85fbaea9d
@@@ -1,4 -1,3 +1,4 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * AMD Cryptographic Coprocessor (CCP) driver
   *
@@@ -6,6 -5,10 +6,6 @@@
   *
   * Author: Tom Lendacky <thomas.lendacky@amd.com>
   * Author: Gary R Hook <gary.hook@amd.com>
 - *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License version 2 as
 - * published by the Free Software Foundation.
   */
  
  #ifndef __CCP_H__
@@@ -170,6 -173,8 +170,8 @@@ struct ccp_aes_engine 
        enum ccp_aes_mode mode;
        enum ccp_aes_action action;
  
+       u32 authsize;
        struct scatterlist *key;
        u32 key_len;            /* In bytes */