]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
crypto: ccp - Fix XTS-AES-128 support on v5 CCPs
authorGary R Hook <gary.hook@amd.com>
Tue, 25 Jul 2017 19:12:11 +0000 (14:12 -0500)
committerSeth Forshee <seth.forshee@canonical.com>
Thu, 28 Sep 2017 14:34:53 +0000 (10:34 -0400)
BugLink: http://bugs.launchpad.net/bugs/1720154
commit e652399edba99a5497f0d80f240c9075d3b43493 upstream.

Version 5 CCPs have some new requirements for XTS-AES: the type field
must be specified, and the key requires 512 bits, with each part
occupying 256 bits and padded with zeroes.

Signed-off-by: Gary R Hook <ghook@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
drivers/crypto/ccp/ccp-crypto-aes-xts.c
drivers/crypto/ccp/ccp-dev-v5.c
drivers/crypto/ccp/ccp-dev.h
drivers/crypto/ccp/ccp-ops.c
include/linux/ccp.h

index 58a4244b4752997fdc645304db0f1f881451e67f..3f26a415ef44b4f4115e695005498db5efc3363a 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
  *
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
+ * Author: Gary R Hook <gary.hook@amd.com>
  * Author: Tom Lendacky <thomas.lendacky@amd.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -164,6 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
        memset(&rctx->cmd, 0, sizeof(rctx->cmd));
        INIT_LIST_HEAD(&rctx->cmd.entry);
        rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
+       rctx->cmd.u.xts.type = CCP_AES_TYPE_128;
        rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
                                           : CCP_AES_ACTION_DECRYPT;
        rctx->cmd.u.xts.unit_size = unit_size;
index b10d2d2075cbd86dbcb7e1403dddb7814c6cfe2f..9bc134a4ebf02a42ee14248de315019560d869fe 100644 (file)
@@ -145,6 +145,7 @@ union ccp_function {
 #define        CCP_AES_MODE(p)         ((p)->aes.mode)
 #define        CCP_AES_TYPE(p)         ((p)->aes.type)
 #define        CCP_XTS_SIZE(p)         ((p)->aes_xts.size)
+#define        CCP_XTS_TYPE(p)         ((p)->aes_xts.type)
 #define        CCP_XTS_ENCRYPT(p)      ((p)->aes_xts.encrypt)
 #define        CCP_DES3_SIZE(p)        ((p)->des3.size)
 #define        CCP_DES3_ENCRYPT(p)     ((p)->des3.encrypt)
@@ -344,6 +345,7 @@ static int ccp5_perform_xts_aes(struct ccp_op *op)
        CCP5_CMD_PROT(&desc) = 0;
 
        function.raw = 0;
+       CCP_XTS_TYPE(&function) = op->u.xts.type;
        CCP_XTS_ENCRYPT(&function) = op->u.xts.action;
        CCP_XTS_SIZE(&function) = op->u.xts.unit_size;
        CCP5_CMD_FUNCTION(&desc) = function.raw;
index a70154ac74056b1da28a1991a9331b5dc821053c..7b8370e9c42eeaa26888d21f80adcdbce7e20914 100644 (file)
 #define CCP_AES_CTX_SB_COUNT           1
 
 #define CCP_XTS_AES_KEY_SB_COUNT       1
+#define CCP5_XTS_AES_KEY_SB_COUNT      2
 #define CCP_XTS_AES_CTX_SB_COUNT       1
 
 #define CCP_DES3_KEY_SB_COUNT          1
@@ -497,6 +498,7 @@ struct ccp_aes_op {
 };
 
 struct ccp_xts_aes_op {
+       enum ccp_aes_type type;
        enum ccp_aes_action action;
        enum ccp_xts_aes_unit_size unit_size;
 };
index c0dfdacbdff525c732b36e411a1efee1e3671e70..f3542aede519ee0eef084037e2ac6d4e7f6d2a53 100644 (file)
@@ -1038,6 +1038,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
        struct ccp_op op;
        unsigned int unit_size, dm_offset;
        bool in_place = false;
+       unsigned int sb_count;
+       enum ccp_aes_type aestype;
        int ret;
 
        switch (xts->unit_size) {
@@ -1061,7 +1063,9 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
                return -EINVAL;
        }
 
-       if (xts->key_len != AES_KEYSIZE_128)
+       if (xts->key_len == AES_KEYSIZE_128)
+               aestype = CCP_AES_TYPE_128;
+       else
                return -EINVAL;
 
        if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
@@ -1083,23 +1087,44 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
        op.sb_key = cmd_q->sb_key;
        op.sb_ctx = cmd_q->sb_ctx;
        op.init = 1;
+       op.u.xts.type = aestype;
        op.u.xts.action = xts->action;
        op.u.xts.unit_size = xts->unit_size;
 
-       /* All supported key sizes fit in a single (32-byte) SB entry
-        * and must be in little endian format. Use the 256-bit byte
-        * swap passthru option to convert from big endian to little
-        * endian.
+       /* A version 3 device only supports 128-bit keys, which fits into a
+        * single SB entry. A version 5 device uses a 512-bit vector, so two
+        * SB entries.
         */
+       if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0))
+               sb_count = CCP_XTS_AES_KEY_SB_COUNT;
+       else
+               sb_count = CCP5_XTS_AES_KEY_SB_COUNT;
        ret = ccp_init_dm_workarea(&key, cmd_q,
-                                  CCP_XTS_AES_KEY_SB_COUNT * CCP_SB_BYTES,
+                                  sb_count * CCP_SB_BYTES,
                                   DMA_TO_DEVICE);
        if (ret)
                return ret;
 
-       dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
-       ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
-       ccp_set_dm_area(&key, 0, xts->key, dm_offset, xts->key_len);
+       if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) {
+               /* All supported key sizes must be in little endian format.
+                * Use the 256-bit byte swap passthru option to convert from
+                * big endian to little endian.
+                */
+               dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
+               ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
+               ccp_set_dm_area(&key, 0, xts->key, xts->key_len, xts->key_len);
+       } else {
+               /* Version 5 CCPs use a 512-bit space for the key: each portion
+                * occupies 256 bits, or one entire slot, and is zero-padded.
+                */
+               unsigned int pad;
+
+               dm_offset = CCP_SB_BYTES;
+               pad = dm_offset - xts->key_len;
+               ccp_set_dm_area(&key, pad, xts->key, 0, xts->key_len);
+               ccp_set_dm_area(&key, dm_offset + pad, xts->key, xts->key_len,
+                               xts->key_len);
+       }
        ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key,
                             CCP_PASSTHRU_BYTESWAP_256BIT);
        if (ret) {
index 3285c944194adcccdde5ae31745c939471260da6..ab693c3afd0d3dd5de929e27d0db0c482e12db0e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * AMD Cryptographic Coprocessor (CCP) driver
  *
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
  *
  * Author: Tom Lendacky <thomas.lendacky@amd.com>
  * Author: Gary R Hook <gary.hook@amd.com>
@@ -231,6 +231,7 @@ enum ccp_xts_aes_unit_size {
  * AES operation the new IV overwrites the old IV.
  */
 struct ccp_xts_aes_engine {
+       enum ccp_aes_type type;
        enum ccp_aes_action action;
        enum ccp_xts_aes_unit_size unit_size;