Re: [RFC PATCH] crypto: pcrypt - forbid recursive instantiation

2018-03-22 Thread Herbert Xu
On Sat, Mar 10, 2018 at 03:22:31PM -0800, Eric Biggers wrote:
> From: Eric Biggers 
> 
> If the pcrypt template is used multiple times in an algorithm, then a
> deadlock occurs because all pcrypt instances share the same
> padata_instance, which completes requests in the order submitted.  That
> is, the inner pcrypt request waits for the outer pcrypt request while
> the outer request is already waiting for the inner.
> 
> Fix this by making pcrypt forbid instantiation if pcrypt appears in the
> underlying ->cra_driver_name.  This is somewhat of a hack, but it's a
> simple fix that should be sufficient to prevent the deadlock.

I'm a bit uneasy with this fix.  What if pcrypt is used in the
underlying algorithm as a fallback? Wouldn't it still dead-lock
without triggering this check?

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


crypto: lrw - Free rctx->ext with kzfree

2018-03-22 Thread Herbert Xu
The buffer rctx->ext contains potentially sensitive data and should
be freed with kzfree.

Cc: 
Fixes: 700cb3f5fe75 ("crypto: lrw - Convert to skcipher")
Reported-by: Dan Carpenter 
Signed-off-by: Herbert Xu 

diff --git a/crypto/lrw.c b/crypto/lrw.c
index a09cdaa..954a706 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -317,7 +317,7 @@ static void exit_crypt(struct skcipher_request *req)
rctx->left = 0;
 
if (rctx->ext)
-   kfree(rctx->ext);
+   kzfree(rctx->ext);
 }
 
 static int do_encrypt(struct skcipher_request *req, int err)
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 1/1] lz4: Implement lz4 with dynamic offset length.

2018-03-22 Thread kbuild test robot
Hi Maninder,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.16-rc6]
[cannot apply to next-20180322]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maninder-Singh/cover-letter-lz4-Implement-lz4-with-dynamic-offset-length/20180323-064137
config: i386-randconfig-s1-03221113 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

   fs/squashfs/lz4_wrapper.c: In function 'lz4_uncompress':
>> fs/squashfs/lz4_wrapper.c:110:8: error: too few arguments to function 
>> 'LZ4_decompress_safe'
 res = LZ4_decompress_safe(stream->input, stream->output,
   ^~~
   In file included from fs/squashfs/lz4_wrapper.c:13:0:
   include/linux/lz4.h:301:5: note: declared here
int LZ4_decompress_safe(const char *source, char *dest, int compressedSize,
^~~

vim +/LZ4_decompress_safe +110 fs/squashfs/lz4_wrapper.c

9c06a46f Phillip Lougher2014-11-27   91  
9c06a46f Phillip Lougher2014-11-27   92  
9c06a46f Phillip Lougher2014-11-27   93  static int lz4_uncompress(struct 
squashfs_sb_info *msblk, void *strm,
9c06a46f Phillip Lougher2014-11-27   94 struct buffer_head **bh, int b, 
int offset, int length,
9c06a46f Phillip Lougher2014-11-27   95 struct squashfs_page_actor 
*output)
9c06a46f Phillip Lougher2014-11-27   96  {
9c06a46f Phillip Lougher2014-11-27   97 struct squashfs_lz4 *stream = 
strm;
9c06a46f Phillip Lougher2014-11-27   98 void *buff = stream->input, 
*data;
9c06a46f Phillip Lougher2014-11-27   99 int avail, i, bytes = length, 
res;
9c06a46f Phillip Lougher2014-11-27  100  
9c06a46f Phillip Lougher2014-11-27  101 for (i = 0; i < b; i++) {
9c06a46f Phillip Lougher2014-11-27  102 avail = min(bytes, 
msblk->devblksize - offset);
9c06a46f Phillip Lougher2014-11-27  103 memcpy(buff, 
bh[i]->b_data + offset, avail);
9c06a46f Phillip Lougher2014-11-27  104 buff += avail;
9c06a46f Phillip Lougher2014-11-27  105 bytes -= avail;
9c06a46f Phillip Lougher2014-11-27  106 offset = 0;
9c06a46f Phillip Lougher2014-11-27  107 put_bh(bh[i]);
9c06a46f Phillip Lougher2014-11-27  108 }
9c06a46f Phillip Lougher2014-11-27  109  
d21b5ff1 Sven Schmidt   2017-02-24 @110 res = 
LZ4_decompress_safe(stream->input, stream->output,
d21b5ff1 Sven Schmidt   2017-02-24  111 length, output->length);
d21b5ff1 Sven Schmidt   2017-02-24  112  
d21b5ff1 Sven Schmidt   2017-02-24  113 if (res < 0)
9c06a46f Phillip Lougher2014-11-27  114 return -EIO;
9c06a46f Phillip Lougher2014-11-27  115  
d21b5ff1 Sven Schmidt   2017-02-24  116 bytes = res;
9c06a46f Phillip Lougher2014-11-27  117 data = 
squashfs_first_page(output);
9c06a46f Phillip Lougher2014-11-27  118 buff = stream->output;
9c06a46f Phillip Lougher2014-11-27  119 while (data) {
09cbfeaf Kirill A. Shutemov 2016-04-01  120 if (bytes <= PAGE_SIZE) 
{
9c06a46f Phillip Lougher2014-11-27  121 memcpy(data, 
buff, bytes);
9c06a46f Phillip Lougher2014-11-27  122 break;
9c06a46f Phillip Lougher2014-11-27  123 }
09cbfeaf Kirill A. Shutemov 2016-04-01  124 memcpy(data, buff, 
PAGE_SIZE);
09cbfeaf Kirill A. Shutemov 2016-04-01  125 buff += PAGE_SIZE;
09cbfeaf Kirill A. Shutemov 2016-04-01  126 bytes -= PAGE_SIZE;
9c06a46f Phillip Lougher2014-11-27  127 data = 
squashfs_next_page(output);
9c06a46f Phillip Lougher2014-11-27  128 }
9c06a46f Phillip Lougher2014-11-27  129 squashfs_finish_page(output);
9c06a46f Phillip Lougher2014-11-27  130  
d21b5ff1 Sven Schmidt   2017-02-24  131 return res;
9c06a46f Phillip Lougher2014-11-27  132  }
9c06a46f Phillip Lougher2014-11-27  133  

:: The code at line 110 was first introduced by commit
:: d21b5ff12df45a65bb220c7e8103a5f0f5609377 fs/pstore: fs/squashfs: change 
usage of LZ4 to work with new LZ4 version

:: TO: Sven Schmidt <4ssch...@informatik.uni-hamburg.de>
:: CC: Linus Torvalds <torva...@linux-foundation.org>

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 1/1] lz4: Implement lz4 with dynamic offset length.

2018-03-22 Thread kbuild test robot
Hi Maninder,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.16-rc6]
[cannot apply to next-20180322]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maninder-Singh/cover-letter-lz4-Implement-lz4-with-dynamic-offset-length/20180323-064137
config: i386-randconfig-x073-201811 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

   fs/pstore/platform.c: In function 'decompress_lz4':
>> fs/pstore/platform.c:357:8: error: too few arguments to function 
>> 'LZ4_decompress_safe'
 ret = LZ4_decompress_safe(in, out, inlen, outlen);
   ^~~
   In file included from fs/pstore/platform.c:38:0:
   include/linux/lz4.h:301:5: note: declared here
int LZ4_decompress_safe(const char *source, char *dest, int compressedSize,
^~~

vim +/LZ4_decompress_safe +357 fs/pstore/platform.c

8cfc8ddc Geliang Tang 2016-02-18  352  
8cfc8ddc Geliang Tang 2016-02-18  353  static int decompress_lz4(void *in, void 
*out, size_t inlen, size_t outlen)
8cfc8ddc Geliang Tang 2016-02-18  354  {
8cfc8ddc Geliang Tang 2016-02-18  355   int ret;
8cfc8ddc Geliang Tang 2016-02-18  356  
d21b5ff1 Sven Schmidt 2017-02-24 @357   ret = LZ4_decompress_safe(in, out, 
inlen, outlen);
d21b5ff1 Sven Schmidt 2017-02-24  358   if (ret < 0) {
d21b5ff1 Sven Schmidt 2017-02-24  359   /*
d21b5ff1 Sven Schmidt 2017-02-24  360* LZ4_decompress_safe will 
return an error code
d21b5ff1 Sven Schmidt 2017-02-24  361* (< 0) if decompression failed
d21b5ff1 Sven Schmidt 2017-02-24  362*/
d21b5ff1 Sven Schmidt 2017-02-24  363   pr_err("LZ4_decompress_safe 
error, ret = %d!\n", ret);
8cfc8ddc Geliang Tang 2016-02-18  364   return -EIO;
8cfc8ddc Geliang Tang 2016-02-18  365   }
8cfc8ddc Geliang Tang 2016-02-18  366  
d21b5ff1 Sven Schmidt 2017-02-24  367   return ret;
8cfc8ddc Geliang Tang 2016-02-18  368  }
8cfc8ddc Geliang Tang 2016-02-18  369  

:: The code at line 357 was first introduced by commit
:: d21b5ff12df45a65bb220c7e8103a5f0f5609377 fs/pstore: fs/squashfs: change 
usage of LZ4 to work with new LZ4 version

:: TO: Sven Schmidt <4ssch...@informatik.uni-hamburg.de>
:: CC: Linus Torvalds <torva...@linux-foundation.org>

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH v6 03/12] PKCS#7: Introduce pkcs7_get_digest()

2018-03-22 Thread Mimi Zohar
On Fri, 2018-03-16 at 17:38 -0300, Thiago Jung Bauermann wrote:
> IMA will need to access the digest of the PKCS7 message (as calculated by
> the kernel) before the signature is verified, so introduce
> pkcs7_get_digest() for that purpose.
> 
> Also, modify pkcs7_digest() to detect when the digest was already
> calculated so that it doesn't have to do redundant work. Verifying that
> sinfo->sig->digest isn't NULL is sufficient because both places which
> allocate sinfo->sig (pkcs7_parse_message() and pkcs7_note_signed_info())
> use kzalloc() so sig->digest is always initialized to zero.
> 
> Signed-off-by: Thiago Jung Bauermann 
> Cc: David Howells 
> Cc: Herbert Xu 
> Cc: "David S. Miller" 

Reviewed-by: Mimi Zohar 

> ---
>  crypto/asymmetric_keys/pkcs7_verify.c | 25 +
>  include/crypto/pkcs7.h|  3 +++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
> b/crypto/asymmetric_keys/pkcs7_verify.c
> index 39e6de0c2761..bd02360f8be5 100644
> --- a/crypto/asymmetric_keys/pkcs7_verify.c
> +++ b/crypto/asymmetric_keys/pkcs7_verify.c
> @@ -33,6 +33,10 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
> 
>   kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
> 
> + /* The digest was calculated already. */
> + if (sig->digest)
> + return 0;
> +
>   if (!sinfo->sig->hash_algo)
>   return -ENOPKG;
> 
> @@ -122,6 +126,27 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
>   return ret;
>  }
> 
> +int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u8 *len)
> +{
> + struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
> + int ret;
> +
> + /*
> +  * This function doesn't support messages with more than one signature.
> +  */
> + if (sinfo == NULL || sinfo->next != NULL)
> + return -EBADMSG;
> +
> + ret = pkcs7_digest(pkcs7, sinfo);
> + if (ret)
> + return ret;
> +
> + *buf = sinfo->sig->digest;
> + *len = sinfo->sig->digest_size;
> +
> + return 0;
> +}
> +
>  /*
>   * Find the key (X.509 certificate) to use to verify a PKCS#7 message.  
> PKCS#7
>   * uses the issuer's name and the issuing certificate serial number for
> diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h
> index 6f51d0cb6d12..cfaea9c37f4a 100644
> --- a/include/crypto/pkcs7.h
> +++ b/include/crypto/pkcs7.h
> @@ -46,4 +46,7 @@ extern int pkcs7_verify(struct pkcs7_message *pkcs7,
>  extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
> const void *data, size_t datalen);
> 
> +extern int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf,
> + u8 *len);
> +
>  #endif /* _CRYPTO_PKCS7_H */
> 



Re: [PATCH v6 02/12] PKCS#7: Introduce pkcs7_get_message_sig() and verify_pkcs7_message_sig()

2018-03-22 Thread Mimi Zohar
Hi Thiago,

On Fri, 2018-03-16 at 17:38 -0300, Thiago Jung Bauermann wrote:
> IMA will need to know the key that signed a given PKCS#7 message, so add
> pkcs7_get_message_sig().
> 
> It will also need to verify an already parsed PKCS#7 message. For this
> purpose, add verify_pkcs7_message_sig() which takes a struct pkcs7_message
> for verification instead of the raw bytes that verify_pkcs7_signature()
> takes.

The title "PKCS#7: refactor verify_pkcs7_signature()" might be more
appropriate.  The patch description would then explain why it needs to
be refactored.  In this case, verify_pkcs7_signature() verifies the
signature using keys on the builtin and secondary keyrings.  IMA-
appraisal needs to verify the signature using keys on its keyring.

The patch itself looks good!

Reviewed-by: Mimi Zohar 


> Signed-off-by: Thiago Jung Bauermann 
> Cc: David Howells 
> Cc: David Woodhouse 
> Cc: Herbert Xu 
> Cc: "David S. Miller" 
> ---
>  certs/system_keyring.c| 61 
> ++-
>  crypto/asymmetric_keys/pkcs7_parser.c | 16 +
>  include/crypto/pkcs7.h|  2 ++
>  include/linux/verification.h  | 10 ++
>  4 files changed, 73 insertions(+), 16 deletions(-)
> 
> diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> index 6251d1b27f0c..7ddc8b7a3062 100644
> --- a/certs/system_keyring.c
> +++ b/certs/system_keyring.c
> @@ -190,33 +190,27 @@ late_initcall(load_system_certificate_list);
>  #ifdef CONFIG_SYSTEM_DATA_VERIFICATION
> 
>  /**
> - * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
> + * verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system data.
>   * @data: The data to be verified (NULL if expecting internal data).
>   * @len: Size of @data.
> - * @raw_pkcs7: The PKCS#7 message that is the signature.
> - * @pkcs7_len: The size of @raw_pkcs7.
> + * @pkcs7: The PKCS#7 message that is the signature.
>   * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
>   *   (void *)1UL for all trusted keys).
>   * @usage: The use to which the key is being put.
>   * @view_content: Callback to gain access to content.
>   * @ctx: Context for callback.
>   */
> -int verify_pkcs7_signature(const void *data, size_t len,
> -const void *raw_pkcs7, size_t pkcs7_len,
> -struct key *trusted_keys,
> -enum key_being_used_for usage,
> -int (*view_content)(void *ctx,
> -const void *data, size_t len,
> -size_t asn1hdrlen),
> -void *ctx)
> +int verify_pkcs7_message_sig(const void *data, size_t len,
> +  struct pkcs7_message *pkcs7,
> +  struct key *trusted_keys,
> +  enum key_being_used_for usage,
> +  int (*view_content)(void *ctx,
> +  const void *data, size_t len,
> +  size_t asn1hdrlen),
> +  void *ctx)
>  {
> - struct pkcs7_message *pkcs7;
>   int ret;
> 
> - pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
> - if (IS_ERR(pkcs7))
> - return PTR_ERR(pkcs7);
> -
>   /* The data should be detached - so we need to supply it. */
>   if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
>   pr_err("PKCS#7 signature with non-detached data\n");
> @@ -258,6 +252,41 @@ int verify_pkcs7_signature(const void *data, size_t len,
>   }
> 
>  error:
> + pr_devel("<==%s() = %d\n", __func__, ret);
> + return ret;
> +}
> +
> +/**
> + * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
> + * @data: The data to be verified (NULL if expecting internal data).
> + * @len: Size of @data.
> + * @raw_pkcs7: The PKCS#7 message that is the signature.
> + * @pkcs7_len: The size of @raw_pkcs7.
> + * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
> + *   (void *)1UL for all trusted keys).
> + * @usage: The use to which the key is being put.
> + * @view_content: Callback to gain access to content.
> + * @ctx: Context for callback.
> + */
> +int verify_pkcs7_signature(const void *data, size_t len,
> +const void *raw_pkcs7, size_t pkcs7_len,
> +struct key *trusted_keys,
> +enum key_being_used_for usage,
> +int (*view_content)(void *ctx,
> +const void *data, size_t len,
> +size_t asn1hdrlen),
> +

Re: [PATCH v14 02/10] iomap: Add big endian sparse annotations to mmio_{read|write}XXbe()

2018-03-22 Thread Logan Gunthorpe

On 3/22/2018 11:27 AM, Luc Van Oostenryck wrote:

On Thu, Mar 22, 2018 at 11:16:55AM -0600, Logan Gunthorpe wrote:

Sparse produces a few warnings of the form:

lib/iomap.c:84:9: warning: cast to restricted __be16

(The kbuild robot has recently started running such checks)


Reviewed-by: Luc Van Oostenryck 



Thanks Luc!

Logan



Re: [PATCH v14 02/10] iomap: Add big endian sparse annotations to mmio_{read|write}XXbe()

2018-03-22 Thread Luc Van Oostenryck
On Thu, Mar 22, 2018 at 11:16:55AM -0600, Logan Gunthorpe wrote:
> Sparse produces a few warnings of the form:
> 
> lib/iomap.c:84:9: warning: cast to restricted __be16
> 
> (The kbuild robot has recently started running such checks)

Reviewed-by: Luc Van Oostenryck  


[PATCH v14 10/10] ntb: ntb_hw_switchtec: Cleanup 64bit IO defines to use the common header

2018-03-22 Thread Logan Gunthorpe
Clean up the ifdefs which conditionally defined the io{read|write}64
functions in favour of the new common io-64-nonatomic-lo-hi header.

Per a nit from Andy Shevchenko, the include list is also made
alphabetical.

Signed-off-by: Logan Gunthorpe 
Reviewed-by: Andy Shevchenko 
Cc: Jon Mason 
---
 drivers/ntb/hw/mscc/ntb_hw_switchtec.c | 36 --
 1 file changed, 4 insertions(+), 32 deletions(-)

diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c 
b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
index f624ae27eabe..f403da24b833 100644
--- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
+++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
@@ -13,12 +13,13 @@
  *
  */
 
-#include 
-#include 
+#include 
+#include 
 #include 
 #include 
-#include 
+#include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver");
 MODULE_VERSION("0.1");
@@ -35,35 +36,6 @@ module_param(use_lut_mws, bool, 0644);
 MODULE_PARM_DESC(use_lut_mws,
 "Enable the use of the LUT based memory windows");
 
-#ifndef ioread64
-#ifdef readq
-#define ioread64 readq
-#else
-#define ioread64 _ioread64
-static inline u64 _ioread64(void __iomem *mmio)
-{
-   u64 low, high;
-
-   low = ioread32(mmio);
-   high = ioread32(mmio + sizeof(u32));
-   return low | (high << 32);
-}
-#endif
-#endif
-
-#ifndef iowrite64
-#ifdef writeq
-#define iowrite64 writeq
-#else
-#define iowrite64 _iowrite64
-static inline void _iowrite64(u64 val, void __iomem *mmio)
-{
-   iowrite32(val, mmio);
-   iowrite32(val >> 32, mmio + sizeof(u32));
-}
-#endif
-#endif
-
 #define SWITCHTEC_NTB_MAGIC 0x45CC0001
 #define MAX_MWS 128
 
-- 
2.11.0



[PATCH v14 08/10] ntb: ntb_hw_intel: use io-64-nonatomic instead of in-driver hacks

2018-03-22 Thread Logan Gunthorpe
Now that ioread64 and iowrite64 are available in io-64-nonatomic,
we can remove the hack at the top of ntb_hw_intel.c and replace it
with an include.

Signed-off-by: Logan Gunthorpe 
Reviewed-by: Andy Shevchenko 
Acked-by: Dave Jiang 
Acked-by: Allen Hubbe 
Acked-by: Jon Mason 
---
 drivers/ntb/hw/intel/ntb_hw_intel.c | 30 +-
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/drivers/ntb/hw/intel/ntb_hw_intel.c 
b/drivers/ntb/hw/intel/ntb_hw_intel.c
index 156b45cd4a19..5cf40ab21366 100644
--- a/drivers/ntb/hw/intel/ntb_hw_intel.c
+++ b/drivers/ntb/hw/intel/ntb_hw_intel.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ntb_hw_intel.h"
 
@@ -149,35 +150,6 @@ MODULE_PARM_DESC(xeon_b2b_dsd_bar5_addr32,
 static inline enum ntb_topo xeon_ppd_topo(struct intel_ntb_dev *ndev, u8 ppd);
 static int xeon_init_isr(struct intel_ntb_dev *ndev);
 
-#ifndef ioread64
-#ifdef readq
-#define ioread64 readq
-#else
-#define ioread64 _ioread64
-static inline u64 _ioread64(void __iomem *mmio)
-{
-   u64 low, high;
-
-   low = ioread32(mmio);
-   high = ioread32(mmio + sizeof(u32));
-   return low | (high << 32);
-}
-#endif
-#endif
-
-#ifndef iowrite64
-#ifdef writeq
-#define iowrite64 writeq
-#else
-#define iowrite64 _iowrite64
-static inline void _iowrite64(u64 val, void __iomem *mmio)
-{
-   iowrite32(val, mmio);
-   iowrite32(val >> 32, mmio + sizeof(u32));
-}
-#endif
-#endif
-
 static inline int pdev_is_xeon(struct pci_dev *pdev)
 {
switch (pdev->device) {
-- 
2.11.0



[PATCH v14 00/10] Add io{read|write}64 to io-64-atomic headers

2018-03-22 Thread Logan Gunthorpe
This is v14 of my cleanup series to push a number of instances of people
defining their own io{read|write}64 functions into common headers seing
they don't exist in non-64bit systems. This series adds inline functions to the
io-64-nonatomic headers and then cleans up the drivers that defined their
own copies.

This cleanup was originally requested by Greg after he reviewed my
Switchtec NTB code. And I hope someone can pick it up or at least give
feedback on it soon as it's been around relatively unchanged for a few
cycles now and I'm getting a bit tired of resubmitting it with little to
no interest.

Thanks,

Logan

--

Changes since v13:
- Changed the subject of patch 0001 to correct a nit pointed out by Luc

Changes since v12:
- Rebased onto v4.16-rc6
- Split patch 0001 into two and reworked the commit log as requested
  by Luc Van Oostenryck

Changes since v11:
- Rebased onto v4.16-rc5
- Added a patch (0001) to fix some old and new sparse warnings
  that the kbuild robot warned about this cycle. The latest version
  of sparse was required to reproduce these.
- Added a patch (0002) to add io{read|write}64 to parisc which the kbuild
  robot also found errors for this cycle

Changes since v10:
- Rebased onto v4.16-rc4, this droped the drm/tilcdc patch which was
  picked up by that tree and is already in 4.16.

Changes since v9:
- Rebased onto v4.15-rc6
- Fixed a couple of issues in the new version of the CAAM patch as
  pointed out by Horia

Changes since v8:
- Rebased onto v4.15-rc2, as a result rewrote patch 7 seeing someone did
  some similar cleanup in that area.
- Added a patch to clean up the Switchtec NTB driver which landed in
  v4.15-rc1

Changes since v7:
- Fix minor nits from Andy Shevchenko
- Rebased onto v4.14-rc1

Changes since v6:
 ** none **

Changes since v5:
- Added a fix to the tilcdc driver to ensure it doesn't use the
  non-atomic operation. (This includes adding io{read|write}64[be]_is_nonatomic
  defines).

Changes since v4:
- Add functions so the powerpc implementation of iomap.c compiles. (As
  noticed by Horia)

Changes since v3:

- I noticed powerpc didn't use the appropriate functions seeing
  readq/writeq were not defined when iomap.h was included. Thus I've
  included a patch to adjust this
- Fixed some mistakes with a couple of the defines in io-64-nonatomic*
  headers
- Fixed a typo noticed by Horia.

(earlier versions were drastically different)

--

Logan Gunthorpe (10):
  iomap: Use correct endian conversion function in mmio_writeXXbe
  iomap: Add big endian sparse annotations to mmio_{read|write}XXbe()
  parisc: iomap: introduce io{read|write}64
  powerpc: io.h: move iomap.h include so that it can use readq/writeq
defs
  powerpc: iomap.c: introduce io{read|write}64_{lo_hi|hi_lo}
  iomap: introduce io{read|write}64_{lo_hi|hi_lo}
  io-64-nonatomic: add io{read|write}64[be]{_lo_hi|_hi_lo} macros
  ntb: ntb_hw_intel: use io-64-nonatomic instead of in-driver hacks
  crypto: caam: cleanup CONFIG_64BIT ifdefs when using io{read|write}64
  ntb: ntb_hw_switchtec: Cleanup 64bit IO defines to use the common
header

 arch/parisc/include/asm/io.h   |   9 +++
 arch/parisc/lib/iomap.c|  64 +++
 arch/powerpc/include/asm/io.h  |   6 +-
 arch/powerpc/kernel/iomap.c|  40 ++
 drivers/crypto/caam/regs.h |  30 +--
 drivers/ntb/hw/intel/ntb_hw_intel.c|  30 +--
 drivers/ntb/hw/mscc/ntb_hw_switchtec.c |  36 +
 include/asm-generic/iomap.h|  26 --
 include/linux/io-64-nonatomic-hi-lo.h  |  64 +++
 include/linux/io-64-nonatomic-lo-hi.h  |  64 +++
 lib/iomap.c| 140 -
 11 files changed, 409 insertions(+), 100 deletions(-)

--
2.11.0


[PATCH v14 04/10] powerpc: io.h: move iomap.h include so that it can use readq/writeq defs

2018-03-22 Thread Logan Gunthorpe
Subsequent patches in this series makes use of the readq and writeq
defines in iomap.h. However, as is, they get missed on the powerpc
platform seeing the include comes before the define. This patch
moves the include down to fix this.

Signed-off-by: Logan Gunthorpe 
Acked-by: Michael Ellerman 
Reviewed-by: Andy Shevchenko 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Suresh Warrier 
Cc: "Oliver O'Halloran" 
---
 arch/powerpc/include/asm/io.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 422f99cf9924..af074923d598 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -33,8 +33,6 @@ extern struct pci_dev *isa_bridge_pcidev;
 #include 
 #include 
 
-#include 
-
 #ifdef CONFIG_PPC64
 #include 
 #endif
@@ -663,6 +661,8 @@ static inline void name at  
\
 #define writel_relaxed(v, addr)writel(v, addr)
 #define writeq_relaxed(v, addr)writeq(v, addr)
 
+#include 
+
 #ifdef CONFIG_PPC32
 #define mmiowb()
 #else
-- 
2.11.0



[PATCH v14 07/10] io-64-nonatomic: add io{read|write}64[be]{_lo_hi|_hi_lo} macros

2018-03-22 Thread Logan Gunthorpe
This patch adds generic io{read|write}64[be]{_lo_hi|_hi_lo} macros if
they are not already defined by the architecture. (As they are provided
by the generic iomap library).

The patch also points io{read|write}64[be] to the variant specified by the
header name.

This is because new drivers are encouraged to use ioreadXX, et al instead
of readX[1], et al -- and mixing ioreadXX with readq is pretty ugly.

[1] LDD3: section 9.4.2

Signed-off-by: Logan Gunthorpe 
Reviewed-by: Andy Shevchenko 
Cc: Christoph Hellwig 
Cc: Arnd Bergmann 
Cc: Alan Cox 
Cc: Greg Kroah-Hartman 
---
 include/linux/io-64-nonatomic-hi-lo.h | 64 +++
 include/linux/io-64-nonatomic-lo-hi.h | 64 +++
 2 files changed, 128 insertions(+)

diff --git a/include/linux/io-64-nonatomic-hi-lo.h 
b/include/linux/io-64-nonatomic-hi-lo.h
index 862d786a904f..ae21b72cce85 100644
--- a/include/linux/io-64-nonatomic-hi-lo.h
+++ b/include/linux/io-64-nonatomic-hi-lo.h
@@ -55,4 +55,68 @@ static inline void hi_lo_writeq_relaxed(__u64 val, volatile 
void __iomem *addr)
 #define writeq_relaxed hi_lo_writeq_relaxed
 #endif
 
+#ifndef ioread64_hi_lo
+#define ioread64_hi_lo ioread64_hi_lo
+static inline u64 ioread64_hi_lo(void __iomem *addr)
+{
+   u32 low, high;
+
+   high = ioread32(addr + sizeof(u32));
+   low = ioread32(addr);
+
+   return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef iowrite64_hi_lo
+#define iowrite64_hi_lo iowrite64_hi_lo
+static inline void iowrite64_hi_lo(u64 val, void __iomem *addr)
+{
+   iowrite32(val >> 32, addr + sizeof(u32));
+   iowrite32(val, addr);
+}
+#endif
+
+#ifndef ioread64be_hi_lo
+#define ioread64be_hi_lo ioread64be_hi_lo
+static inline u64 ioread64be_hi_lo(void __iomem *addr)
+{
+   u32 low, high;
+
+   high = ioread32be(addr);
+   low = ioread32be(addr + sizeof(u32));
+
+   return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef iowrite64be_hi_lo
+#define iowrite64be_hi_lo iowrite64be_hi_lo
+static inline void iowrite64be_hi_lo(u64 val, void __iomem *addr)
+{
+   iowrite32be(val >> 32, addr);
+   iowrite32be(val, addr + sizeof(u32));
+}
+#endif
+
+#ifndef ioread64
+#define ioread64_is_nonatomic
+#define ioread64 ioread64_hi_lo
+#endif
+
+#ifndef iowrite64
+#define iowrite64_is_nonatomic
+#define iowrite64 iowrite64_hi_lo
+#endif
+
+#ifndef ioread64be
+#define ioread64be_is_nonatomic
+#define ioread64be ioread64be_hi_lo
+#endif
+
+#ifndef iowrite64be
+#define iowrite64be_is_nonatomic
+#define iowrite64be iowrite64be_hi_lo
+#endif
+
 #endif /* _LINUX_IO_64_NONATOMIC_HI_LO_H_ */
diff --git a/include/linux/io-64-nonatomic-lo-hi.h 
b/include/linux/io-64-nonatomic-lo-hi.h
index d042e7bb5adb..faaa842dbdb9 100644
--- a/include/linux/io-64-nonatomic-lo-hi.h
+++ b/include/linux/io-64-nonatomic-lo-hi.h
@@ -55,4 +55,68 @@ static inline void lo_hi_writeq_relaxed(__u64 val, volatile 
void __iomem *addr)
 #define writeq_relaxed lo_hi_writeq_relaxed
 #endif
 
+#ifndef ioread64_lo_hi
+#define ioread64_lo_hi ioread64_lo_hi
+static inline u64 ioread64_lo_hi(void __iomem *addr)
+{
+   u32 low, high;
+
+   low = ioread32(addr);
+   high = ioread32(addr + sizeof(u32));
+
+   return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef iowrite64_lo_hi
+#define iowrite64_lo_hi iowrite64_lo_hi
+static inline void iowrite64_lo_hi(u64 val, void __iomem *addr)
+{
+   iowrite32(val, addr);
+   iowrite32(val >> 32, addr + sizeof(u32));
+}
+#endif
+
+#ifndef ioread64be_lo_hi
+#define ioread64be_lo_hi ioread64be_lo_hi
+static inline u64 ioread64be_lo_hi(void __iomem *addr)
+{
+   u32 low, high;
+
+   low = ioread32be(addr + sizeof(u32));
+   high = ioread32be(addr);
+
+   return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef iowrite64be_lo_hi
+#define iowrite64be_lo_hi iowrite64be_lo_hi
+static inline void iowrite64be_lo_hi(u64 val, void __iomem *addr)
+{
+   iowrite32be(val, addr + sizeof(u32));
+   iowrite32be(val >> 32, addr);
+}
+#endif
+
+#ifndef ioread64
+#define ioread64_is_nonatomic
+#define ioread64 ioread64_lo_hi
+#endif
+
+#ifndef iowrite64
+#define iowrite64_is_nonatomic
+#define iowrite64 iowrite64_lo_hi
+#endif
+
+#ifndef ioread64be
+#define ioread64be_is_nonatomic
+#define ioread64be ioread64be_lo_hi
+#endif
+
+#ifndef iowrite64be
+#define iowrite64be_is_nonatomic
+#define iowrite64be iowrite64be_lo_hi
+#endif
+
 #endif /* _LINUX_IO_64_NONATOMIC_LO_HI_H_ */
-- 
2.11.0



[PATCH v14 02/10] iomap: Add big endian sparse annotations to mmio_{read|write}XXbe()

2018-03-22 Thread Logan Gunthorpe
Sparse produces a few warnings of the form:

lib/iomap.c:84:9: warning: cast to restricted __be16

(The kbuild robot has recently started running such checks)

The warning is not valid because the __raw_readX() and __raw_writeX()
functions have an endianess determined by the semantics of whichever
register they are operating on (which is intern dependant on the address
passed to the function).

In the iomap case, the register being operated on is known,
semantically, to be Big Endian when an ioXXbe() function is used
by the caller. These functions wrap a raw read or write function
in an endianness conversion function.

Sparse enforces that all values that aren't in CPU endianness
be marked with types like __be16 and similar and said types cannot
be mixed with other types. However, per above, the raw functions
cannot be marked as such seeing the endianness is indeterminate.
Thus, the output of __raw_readX() and the input of __raw_writeX()
must be cast with the __force keyword to supress the invalid warning.

Signed-off-by: Logan Gunthorpe 
Reviewed-by: Andy Shevchenko 
Cc: Thomas Gleixner 
Cc: Greg Kroah-Hartman 
Cc: Philippe Ombredanne 
Cc: Kate Stewart 
Cc: Luc Van Oostenryck 
---
 lib/iomap.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/iomap.c b/lib/iomap.c
index be120c13d6cc..44645c4b516c 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -65,8 +65,8 @@ static void bad_io_access(unsigned long port, const char 
*access)
 #endif
 
 #ifndef mmio_read16be
-#define mmio_read16be(addr) be16_to_cpu(__raw_readw(addr))
-#define mmio_read32be(addr) be32_to_cpu(__raw_readl(addr))
+#define mmio_read16be(addr) be16_to_cpu((__be16 __force)__raw_readw(addr))
+#define mmio_read32be(addr) be32_to_cpu((__be32 __force)__raw_readl(addr))
 #endif
 
 unsigned int ioread8(void __iomem *addr)
@@ -106,8 +106,8 @@ EXPORT_SYMBOL(ioread32be);
 #endif
 
 #ifndef mmio_write16be
-#define mmio_write16be(val,port) __raw_writew(cpu_to_be16(val),port)
-#define mmio_write32be(val,port) __raw_writel(cpu_to_be32(val),port)
+#define mmio_write16be(val,port) __raw_writew((u16 
__force)cpu_to_be16(val),port)
+#define mmio_write32be(val,port) __raw_writel((u32 
__force)cpu_to_be32(val),port)
 #endif
 
 void iowrite8(u8 val, void __iomem *addr)
-- 
2.11.0



[PATCH v14 01/10] iomap: Use correct endian conversion function in mmio_writeXXbe

2018-03-22 Thread Logan Gunthorpe
The semantics of the iowriteXXbe() functions are to write a
value in CPU endianess to an IO register that is known by the
caller to be in Big Endian. The mmio_writeXXbe() macro, which
is called by iowriteXXbe(), should therefore use cpu_to_beXX()
instead of beXX_to_cpu().

Seeing both beXX_to_cpu() and cpu_to_beXX() are both functionally
implemented as either null operations or swabXX operations there
was no noticable bug here. But it is confusing for both developers
and code analysis tools alike.

Signed-off-by: Logan Gunthorpe 
Reviewed-by: Luc Van Oostenryck 
Reviewed-by: Andy Shevchenko 
Cc: Philippe Ombredanne 
Cc: Thomas Gleixner 
Cc: Kate Stewart 
Cc: Greg Kroah-Hartman 
---
 lib/iomap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/iomap.c b/lib/iomap.c
index 541d926da95e..be120c13d6cc 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -106,8 +106,8 @@ EXPORT_SYMBOL(ioread32be);
 #endif
 
 #ifndef mmio_write16be
-#define mmio_write16be(val,port) __raw_writew(be16_to_cpu(val),port)
-#define mmio_write32be(val,port) __raw_writel(be32_to_cpu(val),port)
+#define mmio_write16be(val,port) __raw_writew(cpu_to_be16(val),port)
+#define mmio_write32be(val,port) __raw_writel(cpu_to_be32(val),port)
 #endif
 
 void iowrite8(u8 val, void __iomem *addr)
-- 
2.11.0



[PATCH v14 05/10] powerpc: iomap.c: introduce io{read|write}64_{lo_hi|hi_lo}

2018-03-22 Thread Logan Gunthorpe
These functions will be introduced into the generic iomap.c so
they can deal with PIO accesses in hi-lo/lo-hi variants. Thus,
the powerpc version of iomap.c will need to provide the same
functions even though, in this arch, they are identical to the
regular io{read|write}64 functions.

Signed-off-by: Logan Gunthorpe 
Tested-by: Horia Geantă 
Reviewed-by: Andy Shevchenko 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
---
 arch/powerpc/kernel/iomap.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index aab456ed2a00..5ac84efc6ede 100644
--- a/arch/powerpc/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
@@ -45,12 +45,32 @@ u64 ioread64(void __iomem *addr)
 {
return readq(addr);
 }
+u64 ioread64_lo_hi(void __iomem *addr)
+{
+   return readq(addr);
+}
+u64 ioread64_hi_lo(void __iomem *addr)
+{
+   return readq(addr);
+}
 u64 ioread64be(void __iomem *addr)
 {
return readq_be(addr);
 }
+u64 ioread64be_lo_hi(void __iomem *addr)
+{
+   return readq_be(addr);
+}
+u64 ioread64be_hi_lo(void __iomem *addr)
+{
+   return readq_be(addr);
+}
 EXPORT_SYMBOL(ioread64);
+EXPORT_SYMBOL(ioread64_lo_hi);
+EXPORT_SYMBOL(ioread64_hi_lo);
 EXPORT_SYMBOL(ioread64be);
+EXPORT_SYMBOL(ioread64be_lo_hi);
+EXPORT_SYMBOL(ioread64be_hi_lo);
 #endif /* __powerpc64__ */
 
 void iowrite8(u8 val, void __iomem *addr)
@@ -83,12 +103,32 @@ void iowrite64(u64 val, void __iomem *addr)
 {
writeq(val, addr);
 }
+void iowrite64_lo_hi(u64 val, void __iomem *addr)
+{
+   writeq(val, addr);
+}
+void iowrite64_hi_lo(u64 val, void __iomem *addr)
+{
+   writeq(val, addr);
+}
 void iowrite64be(u64 val, void __iomem *addr)
 {
writeq_be(val, addr);
 }
+void iowrite64be_lo_hi(u64 val, void __iomem *addr)
+{
+   writeq_be(val, addr);
+}
+void iowrite64be_hi_lo(u64 val, void __iomem *addr)
+{
+   writeq_be(val, addr);
+}
 EXPORT_SYMBOL(iowrite64);
+EXPORT_SYMBOL(iowrite64_lo_hi);
+EXPORT_SYMBOL(iowrite64_hi_lo);
 EXPORT_SYMBOL(iowrite64be);
+EXPORT_SYMBOL(iowrite64be_lo_hi);
+EXPORT_SYMBOL(iowrite64be_hi_lo);
 #endif /* __powerpc64__ */
 
 /*
-- 
2.11.0



[PATCH v14 09/10] crypto: caam: cleanup CONFIG_64BIT ifdefs when using io{read|write}64

2018-03-22 Thread Logan Gunthorpe
Clean up the extra ifdefs which defined the wr_reg64 and rd_reg64
functions in non-64bit cases in favour of the new common
io-64-nonatomic-lo-hi header.

To be consistent with CAAM engine HW spec: in case of 64-bit registers,
irrespective of device endianness, the lower address should be read from
/ written to first, followed by the upper address. Indeed the I/O
accessors in CAAM driver currently don't follow the spec, however this
is a good opportunity to fix the code.

Signed-off-by: Logan Gunthorpe 
Reviewed-by: Horia Geantă 
Reviewed-by: Andy Shevchenko 
Cc: Dan Douglass 
Cc: Herbert Xu 
Cc: "David S. Miller" 
---
 drivers/crypto/caam/regs.h | 30 +++---
 1 file changed, 3 insertions(+), 27 deletions(-)

diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index fee363865d88..f887b371040f 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -10,7 +10,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Architecture-specific register access methods
@@ -136,10 +136,9 @@ static inline void clrsetbits_32(void __iomem *reg, u32 
clear, u32 set)
  *base + 0x : least-significant 32 bits
  *base + 0x0004 : most-significant 32 bits
  */
-#ifdef CONFIG_64BIT
 static inline void wr_reg64(void __iomem *reg, u64 data)
 {
-   if (caam_little_end)
+   if (!caam_imx && caam_little_end)
iowrite64(data, reg);
else
iowrite64be(data, reg);
@@ -147,35 +146,12 @@ static inline void wr_reg64(void __iomem *reg, u64 data)
 
 static inline u64 rd_reg64(void __iomem *reg)
 {
-   if (caam_little_end)
+   if (!caam_imx && caam_little_end)
return ioread64(reg);
else
return ioread64be(reg);
 }
 
-#else /* CONFIG_64BIT */
-static inline void wr_reg64(void __iomem *reg, u64 data)
-{
-   if (!caam_imx && caam_little_end) {
-   wr_reg32((u32 __iomem *)(reg) + 1, data >> 32);
-   wr_reg32((u32 __iomem *)(reg), data);
-   } else {
-   wr_reg32((u32 __iomem *)(reg), data >> 32);
-   wr_reg32((u32 __iomem *)(reg) + 1, data);
-   }
-}
-
-static inline u64 rd_reg64(void __iomem *reg)
-{
-   if (!caam_imx && caam_little_end)
-   return ((u64)rd_reg32((u32 __iomem *)(reg) + 1) << 32 |
-   (u64)rd_reg32((u32 __iomem *)(reg)));
-
-   return ((u64)rd_reg32((u32 __iomem *)(reg)) << 32 |
-   (u64)rd_reg32((u32 __iomem *)(reg) + 1));
-}
-#endif /* CONFIG_64BIT  */
-
 static inline u64 cpu_to_caam_dma64(dma_addr_t value)
 {
if (caam_imx)
-- 
2.11.0



[PATCH v2 net-next 5/6] tls: RX path for ktls

2018-03-22 Thread Dave Watson
Add rx path for tls software implementation.

recvmsg, splice_read, and poll implemented.

An additional sockopt TLS_RX is added, with the same interface as
TLS_TX.  Either TLX_RX or TLX_TX may be provided separately, or
together (with two different setsockopt calls with appropriate keys).

Control messages are passed via CMSG in a similar way to transmit.
If no cmsg buffer is passed, then only application data records
will be passed to userspace, and EIO is returned for other types of
alerts.

EBADMSG is passed for decryption errors, and EMSGSIZE is passed for
framing too big, and EBADMSG for framing too small (matching openssl
semantics). EINVAL is returned for TLS versions that do not match the
original setsockopt call.  All are unrecoverable.

strparser is used to parse TLS framing.   Decryption is done directly
in to userspace buffers if they are large enough to support it, otherwise
sk_cow_data is called (similar to ipsec), and buffers are decrypted in
place and copied.  splice_read always decrypts in place, since no
buffers are provided to decrypt in to.

sk_poll is overridden, and only returns POLLIN if a full TLS message is
received.  Otherwise we wait for strparser to finish reading a full frame.
Actual decryption is only done during recvmsg or splice_read calls.

Signed-off-by: Dave Watson 
---
 include/net/tls.h|  27 ++-
 include/uapi/linux/tls.h |   2 +
 net/tls/Kconfig  |   1 +
 net/tls/tls_main.c   |  62 -
 net/tls/tls_sw.c | 587 ++-
 5 files changed, 609 insertions(+), 70 deletions(-)

diff --git a/include/net/tls.h b/include/net/tls.h
index 095b722..437a746 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -40,6 +40,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -58,8 +59,18 @@
 
 struct tls_sw_context {
struct crypto_aead *aead_send;
+   struct crypto_aead *aead_recv;
struct crypto_wait async_wait;
 
+   /* Receive context */
+   struct strparser strp;
+   void (*saved_data_ready)(struct sock *sk);
+   unsigned int (*sk_poll)(struct file *file, struct socket *sock,
+   struct poll_table_struct *wait);
+   struct sk_buff *recv_pkt;
+   u8 control;
+   bool decrypted;
+
/* Sending context */
char aad_space[TLS_AAD_SPACE_SIZE];
 
@@ -96,12 +107,17 @@ struct tls_context {
struct tls_crypto_info crypto_send;
struct tls12_crypto_info_aes_gcm_128 crypto_send_aes_gcm_128;
};
+   union {
+   struct tls_crypto_info crypto_recv;
+   struct tls12_crypto_info_aes_gcm_128 crypto_recv_aes_gcm_128;
+   };
 
void *priv_ctx;
 
u8 conf:2;
 
struct cipher_context tx;
+   struct cipher_context rx;
 
struct scatterlist *partially_sent_record;
u16 partially_sent_offset;
@@ -128,12 +144,19 @@ int tls_sk_attach(struct sock *sk, int optname, char 
__user *optval,
  unsigned int optlen);
 
 
-int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx);
+int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx);
 int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
 int tls_sw_sendpage(struct sock *sk, struct page *page,
int offset, size_t size, int flags);
 void tls_sw_close(struct sock *sk, long timeout);
-void tls_sw_free_tx_resources(struct sock *sk);
+void tls_sw_free_resources(struct sock *sk);
+int tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+  int nonblock, int flags, int *addr_len);
+unsigned int tls_sw_poll(struct file *file, struct socket *sock,
+struct poll_table_struct *wait);
+ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
+  struct pipe_inode_info *pipe,
+  size_t len, unsigned int flags);
 
 void tls_sk_destruct(struct sock *sk, struct tls_context *ctx);
 void tls_icsk_clean_acked(struct sock *sk);
diff --git a/include/uapi/linux/tls.h b/include/uapi/linux/tls.h
index 293b2cd..c6633e9 100644
--- a/include/uapi/linux/tls.h
+++ b/include/uapi/linux/tls.h
@@ -38,6 +38,7 @@
 
 /* TLS socket options */
 #define TLS_TX 1   /* Set transmit parameters */
+#define TLS_RX 2   /* Set receive parameters */
 
 /* Supported versions */
 #define TLS_VERSION_MINOR(ver) ((ver) & 0xFF)
@@ -59,6 +60,7 @@
 #define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE8
 
 #define TLS_SET_RECORD_TYPE1
+#define TLS_GET_RECORD_TYPE2
 
 struct tls_crypto_info {
__u16 version;
diff --git a/net/tls/Kconfig b/net/tls/Kconfig
index eb58303..89b8745a 100644
--- a/net/tls/Kconfig
+++ b/net/tls/Kconfig
@@ -7,6 +7,7 @@ config TLS
select CRYPTO
select CRYPTO_AES
select CRYPTO_GCM
+   select STREAM_PARSER
default n

[PATCH v2 net-next 3/6] tls: Pass error code explicitly to tls_err_abort

2018-03-22 Thread Dave Watson
Pass EBADMSG explicitly to tls_err_abort.  Receive path will
pass additional codes - EMSGSIZE if framing is larger than max
TLS record size, EINVAL if TLS version mismatch.

Signed-off-by: Dave Watson 
---
 include/net/tls.h | 6 +++---
 net/tls/tls_sw.c  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/net/tls.h b/include/net/tls.h
index 019e52d..6b44875 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -174,9 +174,9 @@ static inline bool tls_is_pending_open_record(struct 
tls_context *tls_ctx)
return tls_ctx->pending_open_record_frags;
 }
 
-static inline void tls_err_abort(struct sock *sk)
+static inline void tls_err_abort(struct sock *sk, int err)
 {
-   sk->sk_err = EBADMSG;
+   sk->sk_err = err;
sk->sk_error_report(sk);
 }
 
@@ -197,7 +197,7 @@ static inline void tls_advance_record_sn(struct sock *sk,
 struct cipher_context *ctx)
 {
if (tls_bigint_increment(ctx->rec_seq, ctx->rec_seq_size))
-   tls_err_abort(sk);
+   tls_err_abort(sk, EBADMSG);
tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
 ctx->iv_size);
 }
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 338d743..1c79d9a 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -214,7 +214,7 @@ static int tls_push_record(struct sock *sk, int flags,
/* Only pass through MSG_DONTWAIT and MSG_NOSIGNAL flags */
rc = tls_push_sg(sk, tls_ctx, ctx->sg_encrypted_data, 0, flags);
if (rc < 0 && rc != -EAGAIN)
-   tls_err_abort(sk);
+   tls_err_abort(sk, EBADMSG);
 
tls_advance_record_sn(sk, _ctx->tx);
return rc;
-- 
2.9.5



[PATCH v2 net-next 1/6] tls: Generalize zerocopy_from_iter

2018-03-22 Thread Dave Watson
Refactor zerocopy_from_iter to take arguments for pages and size,
such that it can be used for both tx and rx. RX will also support
zerocopy direct to output iter, as long as the full message can
be copied at once (a large enough userspace buffer was provided).

Signed-off-by: Dave Watson 
---
 net/tls/tls_sw.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 057a558..ca1d20d 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -226,23 +226,24 @@ static int tls_sw_push_pending_record(struct sock *sk, 
int flags)
 }
 
 static int zerocopy_from_iter(struct sock *sk, struct iov_iter *from,
- int length)
+ int length, int *pages_used,
+ unsigned int *size_used,
+ struct scatterlist *to, int to_max_pages,
+ bool charge)
 {
-   struct tls_context *tls_ctx = tls_get_ctx(sk);
-   struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
struct page *pages[MAX_SKB_FRAGS];
 
size_t offset;
ssize_t copied, use;
int i = 0;
-   unsigned int size = ctx->sg_plaintext_size;
-   int num_elem = ctx->sg_plaintext_num_elem;
+   unsigned int size = *size_used;
+   int num_elem = *pages_used;
int rc = 0;
int maxpages;
 
while (length > 0) {
i = 0;
-   maxpages = ARRAY_SIZE(ctx->sg_plaintext_data) - num_elem;
+   maxpages = to_max_pages - num_elem;
if (maxpages == 0) {
rc = -EFAULT;
goto out;
@@ -262,10 +263,11 @@ static int zerocopy_from_iter(struct sock *sk, struct 
iov_iter *from,
while (copied) {
use = min_t(int, copied, PAGE_SIZE - offset);
 
-   sg_set_page(>sg_plaintext_data[num_elem],
+   sg_set_page([num_elem],
pages[i], use, offset);
-   sg_unmark_end(>sg_plaintext_data[num_elem]);
-   sk_mem_charge(sk, use);
+   sg_unmark_end([num_elem]);
+   if (charge)
+   sk_mem_charge(sk, use);
 
offset = 0;
copied -= use;
@@ -276,8 +278,9 @@ static int zerocopy_from_iter(struct sock *sk, struct 
iov_iter *from,
}
 
 out:
-   ctx->sg_plaintext_size = size;
-   ctx->sg_plaintext_num_elem = num_elem;
+   *size_used = size;
+   *pages_used = num_elem;
+
return rc;
 }
 
@@ -374,7 +377,11 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, 
size_t size)
 
if (full_record || eor) {
ret = zerocopy_from_iter(sk, >msg_iter,
-try_to_copy);
+   try_to_copy, >sg_plaintext_num_elem,
+   >sg_plaintext_size,
+   ctx->sg_plaintext_data,
+   ARRAY_SIZE(ctx->sg_plaintext_data),
+   true);
if (ret)
goto fallback_to_reg_send;
 
-- 
2.9.5



[PATCH v2 net-next 6/6] tls: Add receive path documentation

2018-03-22 Thread Dave Watson
Add documentation on rx path setup and cmsg interface.

Signed-off-by: Dave Watson 
---
 Documentation/networking/tls.txt | 66 ++--
 1 file changed, 64 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/tls.txt b/Documentation/networking/tls.txt
index 77ed006..58b5ef7 100644
--- a/Documentation/networking/tls.txt
+++ b/Documentation/networking/tls.txt
@@ -48,6 +48,9 @@ the transmit and the receive into the kernel.
 
   setsockopt(sock, SOL_TLS, TLS_TX, _info, sizeof(crypto_info));
 
+Transmit and receive are set separately, but the setup is the same, using 
either
+TLS_TX or TLS_RX.
+
 Sending TLS application data
 
 
@@ -79,6 +82,28 @@ for memory), or the encryption will always succeed.  If 
send() returns
 -ENOMEM and some data was left on the socket buffer from a previous
 call using MSG_MORE, the MSG_MORE data is left on the socket buffer.
 
+Receiving TLS application data
+--
+
+After setting the TLS_RX socket option, all recv family socket calls
+are decrypted using TLS parameters provided.  A full TLS record must
+be received before decryption can happen.
+
+  char buffer[16384];
+  recv(sock, buffer, 16384);
+
+Received data is decrypted directly in to the user buffer if it is
+large enough, and no additional allocations occur.  If the userspace
+buffer is too small, data is decrypted in the kernel and copied to
+userspace.
+
+EINVAL is returned if the TLS version in the received message does not
+match the version passed in setsockopt.
+
+EMSGSIZE is returned if the received message is too big.
+
+EBADMSG is returned if decryption failed for any other reason.
+
 Send TLS control messages
 -
 
@@ -118,6 +143,43 @@ using a record of type @record_type.
 Control message data should be provided unencrypted, and will be
 encrypted by the kernel.
 
+Receiving TLS control messages
+--
+
+TLS control messages are passed in the userspace buffer, with message
+type passed via cmsg.  If no cmsg buffer is provided, an error is
+returned if a control message is received.  Data messages may be
+received without a cmsg buffer set.
+
+  char buffer[16384];
+  char cmsg[CMSG_SPACE(sizeof(unsigned char))];
+  struct msghdr msg = {0};
+  msg.msg_control = cmsg;
+  msg.msg_controllen = sizeof(cmsg);
+
+  struct iovec msg_iov;
+  msg_iov.iov_base = buffer;
+  msg_iov.iov_len = 16384;
+
+  msg.msg_iov = _iov;
+  msg.msg_iovlen = 1;
+
+  int ret = recvmsg(sock, , 0 /* flags */);
+
+  struct cmsghdr *cmsg = CMSG_FIRSTHDR();
+  if (cmsg->cmsg_level == SOL_TLS &&
+  cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
+  int record_type = *((unsigned char *)CMSG_DATA(cmsg));
+  // Do something with record_type, and control message data in
+  // buffer.
+  //
+  // Note that record_type may be == to application data (23).
+  } else {
+  // Buffer contains application data.
+  }
+
+recv will never return data from mixed types of TLS records.
+
 Integrating in to userspace TLS library
 ---
 
@@ -126,10 +188,10 @@ layer of a userspace TLS library.
 
 A patchset to OpenSSL to use ktls as the record layer is here:
 
-https://github.com/Mellanox/tls-openssl
+https://github.com/Mellanox/openssl/commits/tls_rx2
 
 An example of calling send directly after a handshake using
 gnutls.  Since it doesn't implement a full record layer, control
 messages are not supported:
 
-https://github.com/Mellanox/tls-af_ktls_tool
+https://github.com/ktls/af_ktls-tool/commits/RX
-- 
2.9.5



[PATCH v2 net-next 4/6] tls: Refactor variable names

2018-03-22 Thread Dave Watson
Several config variables are prefixed with tx, drop the prefix
since these will be used for both tx and rx.

Signed-off-by: Dave Watson 
---
 include/net/tls.h  |  2 +-
 net/tls/tls_main.c | 26 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/include/net/tls.h b/include/net/tls.h
index 6b44875..095b722 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -99,7 +99,7 @@ struct tls_context {
 
void *priv_ctx;
 
-   u8 tx_conf:2;
+   u8 conf:2;
 
struct cipher_context tx;
 
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index c671560..c405bee 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -52,7 +52,7 @@ enum {
 };
 
 enum {
-   TLS_BASE_TX,
+   TLS_BASE,
TLS_SW_TX,
TLS_NUM_CONFIG,
 };
@@ -65,7 +65,7 @@ static inline void update_sk_prot(struct sock *sk, struct 
tls_context *ctx)
 {
int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
 
-   sk->sk_prot = _prots[ip_ver][ctx->tx_conf];
+   sk->sk_prot = _prots[ip_ver][ctx->conf];
 }
 
 int wait_on_pending_writer(struct sock *sk, long *timeo)
@@ -238,7 +238,7 @@ static void tls_sk_proto_close(struct sock *sk, long 
timeout)
lock_sock(sk);
sk_proto_close = ctx->sk_proto_close;
 
-   if (ctx->tx_conf == TLS_BASE_TX) {
+   if (ctx->conf == TLS_BASE) {
kfree(ctx);
goto skip_tx_cleanup;
}
@@ -262,7 +262,7 @@ static void tls_sk_proto_close(struct sock *sk, long 
timeout)
kfree(ctx->tx.rec_seq);
kfree(ctx->tx.iv);
 
-   if (ctx->tx_conf == TLS_SW_TX)
+   if (ctx->conf == TLS_SW_TX)
tls_sw_free_tx_resources(sk);
 
 skip_tx_cleanup:
@@ -371,7 +371,7 @@ static int do_tls_setsockopt_tx(struct sock *sk, char 
__user *optval,
struct tls_crypto_info *crypto_info;
struct tls_context *ctx = tls_get_ctx(sk);
int rc = 0;
-   int tx_conf;
+   int conf;
 
if (!optval || (optlen < sizeof(*crypto_info))) {
rc = -EINVAL;
@@ -418,11 +418,11 @@ static int do_tls_setsockopt_tx(struct sock *sk, char 
__user *optval,
 
/* currently SW is default, we will have ethtool in future */
rc = tls_set_sw_offload(sk, ctx);
-   tx_conf = TLS_SW_TX;
+   conf = TLS_SW_TX;
if (rc)
goto err_crypto_info;
 
-   ctx->tx_conf = tx_conf;
+   ctx->conf = conf;
update_sk_prot(sk, ctx);
ctx->sk_write_space = sk->sk_write_space;
sk->sk_write_space = tls_write_space;
@@ -465,12 +465,12 @@ static int tls_setsockopt(struct sock *sk, int level, int 
optname,
 
 static void build_protos(struct proto *prot, struct proto *base)
 {
-   prot[TLS_BASE_TX] = *base;
-   prot[TLS_BASE_TX].setsockopt= tls_setsockopt;
-   prot[TLS_BASE_TX].getsockopt= tls_getsockopt;
-   prot[TLS_BASE_TX].close = tls_sk_proto_close;
+   prot[TLS_BASE] = *base;
+   prot[TLS_BASE].setsockopt   = tls_setsockopt;
+   prot[TLS_BASE].getsockopt   = tls_getsockopt;
+   prot[TLS_BASE].close= tls_sk_proto_close;
 
-   prot[TLS_SW_TX] = prot[TLS_BASE_TX];
+   prot[TLS_SW_TX] = prot[TLS_BASE];
prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg;
prot[TLS_SW_TX].sendpage= tls_sw_sendpage;
 }
@@ -513,7 +513,7 @@ static int tls_init(struct sock *sk)
mutex_unlock(_prot_mutex);
}
 
-   ctx->tx_conf = TLS_BASE_TX;
+   ctx->conf = TLS_BASE;
update_sk_prot(sk, ctx);
 out:
return rc;
-- 
2.9.5



[PATCH v2 net-next 2/6] tls: Move cipher info to a separate struct

2018-03-22 Thread Dave Watson
Separate tx crypto parameters to a separate cipher_context struct.
The same parameters will be used for rx using the same struct.

tls_advance_record_sn is modified to only take the cipher info.

Signed-off-by: Dave Watson 
---
 include/net/tls.h  | 26 +---
 net/tls/tls_main.c |  8 
 net/tls/tls_sw.c   | 58 --
 3 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/include/net/tls.h b/include/net/tls.h
index 4913430..019e52d 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -81,6 +81,16 @@ enum {
TLS_PENDING_CLOSED_RECORD
 };
 
+struct cipher_context {
+   u16 prepend_size;
+   u16 tag_size;
+   u16 overhead_size;
+   u16 iv_size;
+   char *iv;
+   u16 rec_seq_size;
+   char *rec_seq;
+};
+
 struct tls_context {
union {
struct tls_crypto_info crypto_send;
@@ -91,13 +101,7 @@ struct tls_context {
 
u8 tx_conf:2;
 
-   u16 prepend_size;
-   u16 tag_size;
-   u16 overhead_size;
-   u16 iv_size;
-   char *iv;
-   u16 rec_seq_size;
-   char *rec_seq;
+   struct cipher_context tx;
 
struct scatterlist *partially_sent_record;
u16 partially_sent_offset;
@@ -190,7 +194,7 @@ static inline bool tls_bigint_increment(unsigned char *seq, 
int len)
 }
 
 static inline void tls_advance_record_sn(struct sock *sk,
-struct tls_context *ctx)
+struct cipher_context *ctx)
 {
if (tls_bigint_increment(ctx->rec_seq, ctx->rec_seq_size))
tls_err_abort(sk);
@@ -203,9 +207,9 @@ static inline void tls_fill_prepend(struct tls_context *ctx,
 size_t plaintext_len,
 unsigned char record_type)
 {
-   size_t pkt_len, iv_size = ctx->iv_size;
+   size_t pkt_len, iv_size = ctx->tx.iv_size;
 
-   pkt_len = plaintext_len + iv_size + ctx->tag_size;
+   pkt_len = plaintext_len + iv_size + ctx->tx.tag_size;
 
/* we cover nonce explicit here as well, so buf should be of
 * size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE
@@ -217,7 +221,7 @@ static inline void tls_fill_prepend(struct tls_context *ctx,
buf[3] = pkt_len >> 8;
buf[4] = pkt_len & 0xFF;
memcpy(buf + TLS_NONCE_OFFSET,
-  ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv_size);
+  ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv_size);
 }
 
 static inline void tls_make_aad(char *buf,
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index d824d54..c671560 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -259,8 +259,8 @@ static void tls_sk_proto_close(struct sock *sk, long 
timeout)
}
}
 
-   kfree(ctx->rec_seq);
-   kfree(ctx->iv);
+   kfree(ctx->tx.rec_seq);
+   kfree(ctx->tx.iv);
 
if (ctx->tx_conf == TLS_SW_TX)
tls_sw_free_tx_resources(sk);
@@ -319,9 +319,9 @@ static int do_tls_getsockopt_tx(struct sock *sk, char 
__user *optval,
}
lock_sock(sk);
memcpy(crypto_info_aes_gcm_128->iv,
-  ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
+  ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
   TLS_CIPHER_AES_GCM_128_IV_SIZE);
-   memcpy(crypto_info_aes_gcm_128->rec_seq, ctx->rec_seq,
+   memcpy(crypto_info_aes_gcm_128->rec_seq, ctx->tx.rec_seq,
   TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
release_sock(sk);
if (copy_to_user(optval,
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index ca1d20d..338d743 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -79,7 +79,7 @@ static void trim_both_sgl(struct sock *sk, int target_size)
target_size);
 
if (target_size > 0)
-   target_size += tls_ctx->overhead_size;
+   target_size += tls_ctx->tx.overhead_size;
 
trim_sg(sk, ctx->sg_encrypted_data,
>sg_encrypted_num_elem,
@@ -152,21 +152,21 @@ static int tls_do_encryption(struct tls_context *tls_ctx,
if (!aead_req)
return -ENOMEM;
 
-   ctx->sg_encrypted_data[0].offset += tls_ctx->prepend_size;
-   ctx->sg_encrypted_data[0].length -= tls_ctx->prepend_size;
+   ctx->sg_encrypted_data[0].offset += tls_ctx->tx.prepend_size;
+   ctx->sg_encrypted_data[0].length -= tls_ctx->tx.prepend_size;
 
aead_request_set_tfm(aead_req, ctx->aead_send);
aead_request_set_ad(aead_req, TLS_AAD_SPACE_SIZE);
aead_request_set_crypt(aead_req, ctx->sg_aead_in, ctx->sg_aead_out,
-  data_len, tls_ctx->iv);
+  data_len, tls_ctx->tx.iv);
 
aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,

[PATCH v2 net-next 0/6] TLS Rx

2018-03-22 Thread Dave Watson
TLS tcp socket RX implementation, to match existing TX code.

This patchset completes the software TLS socket, allowing full
bi-directional communication over TLS using normal socket syscalls,
after the handshake has been done in userspace.  Only the symmetric
encryption is done in the kernel.

This allows usage of TLS sockets from within the kernel (for example
with network block device, or from bpf).  Performance can be better
than userspace, with appropriate crypto routines [1].

sk->sk_socket->ops must be overridden to implement splice_read and
poll, but otherwise the interface & implementation match TX closely.
strparser is used to parse TLS framing on receive.

There are Openssl RX patches that work with this interface [2], as
well as a testing tool using the socket interface directly (without
cmsg support) [3].  An example tcp socket setup is:

  // Normal tcp socket connect/accept, and TLS handshake
  // using any TLS library.
  setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));

  struct tls12_crypto_info_aes_gcm_128 crypto_info_rx;
  // Fill in crypto_info based on negotiated keys.

  setsockopt(sock, SOL_TLS, TLS_RX, _info, sizeof(crypto_info_rx));
  // You can optionally TLX_TX as well.

  char buffer[16384];
  int ret = recv(sock, buffer, 16384);

  // cmsg can be received using recvmsg and a msg_control 
  // of type TLS_GET_RECORD_TYPE will be set.

V1 -> V2

* For too-small framing errors, return EBADMSG, to match openssl error
  code semantics.  Docs and commit logs about this also updated.

RFC -> V1

* Refactor 'tx' variable names to drop tx
* Error return codes changed per discussion
* Only call skb_cow_data based on in-place decryption, 
  drop unnecessary frag list check.

[1] Recent crypto patchset to remove copies, resulting in optimally
zero copies vs. userspace's one, vs. previous kernel's two.  

https://marc.info/?l=linux-crypto-vger=151931242406416=2

[2] https://github.com/Mellanox/openssl/commits/tls_rx2

[3] https://github.com/ktls/af_ktls-tool/tree/RX

Dave Watson (6):
  tls: Generalize zerocopy_from_iter
  tls: Move cipher info to a separate struct
  tls: Pass error code explicitly to tls_err_abort
  tls: Refactor variable names
  tls: RX path for ktls
  tls: Add receive path documentation

 Documentation/networking/tls.txt |  66 +++-
 include/net/tls.h|  61 ++--
 include/uapi/linux/tls.h |   2 +
 net/tls/Kconfig  |   1 +
 net/tls/tls_main.c   |  92 --
 net/tls/tls_sw.c | 644 ++-
 6 files changed, 740 insertions(+), 126 deletions(-)

-- 
2.9.5



Re: [PATCH 0/9] don't leak pointers to authenc keys

2018-03-22 Thread Herbert Xu
On Wed, Mar 21, 2018 at 07:00:48PM +0200, Tudor Ambarus wrote:
> There are few places in crypto where we save pointers to the
> authenc keys to a local variable of type struct crypto_authenc_keys
> and we don't zeroize it after use. Fix all those cases and don't
> leak pointers to the authenc keys.

Please put this blurb into each patch description.  Because when
people look up the commit years from now they won't be able to
find this email.

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


[PATCH] omap-aes - fix crypto cleanup and IV reporting

2018-03-22 Thread Francis Le Bourse

Hello,

omap_aes_(cbc/ctr)(encrypt/decrypt) don't return the updated IV, add the 
code to do just that at the end of the operation.


In omap_aes_done_task(), omap_crypto_cleanup() is called with:
    omap_crypto_cleanup(>out_sgl, dd->orig_out, 0, dd->total_save,
        FLAGS_OUT_DATA_ST_SHIFT, dd->flags);
this ends up in freeing the part of the omap_aes_dev structure starting 
at the address of the out_sgl member.
As the memory released is soon reused the kernel crashes at the next 
encrypt/decrypt call:


    [  334.559643] Unable to handle kernel paging request at virtual 
address 30627375

    [  334.566922] pgd = c0004000
    [  334.569650] [30627375] *pgd=
    [  334.573252] Internal error: Oops: 5 [#1] SMP ARM

    Entering kdb (current=0xee5fb0c0, pid 89) on processor 1 Oops: (null)
    due to oops @ 0xc0b36a20
    CPU: 1 PID: 89 Comm: 4b50.aes-en Tainted: G C 
4.14.13-ti-r25 #55

    Hardware name: Generic DRA74X (Flattened Device Tree)
    task: ee5fb0c0 task.stack: ee782000
    PC is at omap_aes_crypt_dma+0x234/0x58c
    LR is at irq_work_queue+0x14/0x90
    pc : []    lr : []    psr: 60080013
    sp : ee783e48  ip : 0007  fp : ee783eac
    r10: eba7f740  r9 : eba7f740  r8 : ee70d380
    r7 : 0001  r6 : c011a320  r5 : c1504dc8  r4 : ee70d310
    r3 : 5c40a269  r2 : 5c40a269  r1 :   r0 : 30627375
    Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
    Control: 10c5387d  Table: ad69c06a  DAC: 0051
    CPU: 1 PID: 89 Comm: 4b50.aes-en Tainted: G C 
4.14.13-ti-r25 #55

    Hardware name: Generic DRA74X (Flattened Device Tree)

    [] (__dabt_svc) from [] 
(omap_aes_crypt_dma+0x234/0x58c)
    [] (omap_aes_crypt_dma) from [] 
(omap_aes_crypt_dma_start+0x228/0x400)
    [] (omap_aes_crypt_dma_start) from [] 
(omap_aes_crypt_req+0x94/0x128)
    [] (omap_aes_crypt_req) from [] 
(crypto_pump_work+0x278/0x2f8)
    [] (crypto_pump_work) from [] 
(kthread_worker_fn+0x11c/0x20c)
    [] (kthread_worker_fn) from [] 
(kthread+0x170/0x178)

    [] (kthread) from [] (ret_from_fork+0x14/0x2c)

Here the call should be omap_crypt_cleanup(dd->out_sg, ...);
A similar issue exists in omap-des.c.



Signed-off-by: Francis Le Bourse ---
 drivers/crypto/omap-aes.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 49bd56f..b3a8081 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -97,6 +97,13 @@ static void omap_aes_write_n(struct omap_aes_dev *dd, u32 offset,
 		omap_aes_write(dd, offset, *value);
 }
 
+static void omap_aes_read_n(struct omap_aes_dev *dd, u32 offset,
+	u32 *value, int count)
+{
+	for (; count--; value++, offset += 4)
+		*value = omap_aes_read(dd, offset);
+}
+
 static int omap_aes_hw_init(struct omap_aes_dev *dd)
 {
 	int err;
@@ -389,6 +396,9 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
 
 	pr_debug("err: %d\n", err);
 
+	if ((dd->flags & (FLAGS_CBC | FLAGS_CTR)) && dd->req->info)
+		omap_aes_read_n(dd, AES_REG_IV(dd, 0), dd->req->info, 4);
+
 	crypto_finalize_cipher_request(dd->engine, req, err);
 
 	pm_runtime_mark_last_busy(dd->dev);
@@ -498,7 +508,7 @@ static void omap_aes_done_task(unsigned long data)
 	omap_crypto_cleanup(dd->in_sgl, NULL, 0, dd->total_save,
 			FLAGS_IN_DATA_ST_SHIFT, dd->flags);
 
-	omap_crypto_cleanup(>out_sgl, dd->orig_out, 0, dd->total_save,
+	omap_crypto_cleanup(dd->out_sg, dd->orig_out, 0, dd->total_save,
 			FLAGS_OUT_DATA_ST_SHIFT, dd->flags);
 
 	omap_aes_finish_req(dd, 0);


[PATCH] omap-crypto - fix kernel oops and output buffer update

2018-03-22 Thread Francis Le Bourse

Hello,
In omap_crypto_cleanup(),:
    if (orig && (flags & OMAP_CRYPTO_COPY_MASK))
        scatterwalk_map_and_copy(buf, orig, offset, len, 1);
implies that scatterwalk_map_and_copy() is called if flag is set to 
OMAP_CRYPTO_SG_COPIED.
If the output buffer crosses a page boundary, the second and subsequent 
pages are overwritten.

The test should be : if(orig && (flags & OMAP_CRYPTO_DATA_COPIED))

The variable buf is always assigned but not used if flags == 
OMAP_CRYPTO_SG_COPIED.

In:
    buf = sg_virt(sg);
sg_page(sg) can be NULL, leading to a kernel crash:

    [   37.624352] Unable to handle kernel NULL pointer dereference at 
virtual address 

    [   37.632502] pgd = ec15
    [   37.635238] [] *pgd=
    [   37.638842] Internal error: Oops: 5 [#1] SMP ARM

    Entering kdb (current=0xec173080, pid 1125) on processor 0 Oops: (null)
    due to oops @ 0xc02c04f4
    CPU: 0 PID: 1125 Comm: ping Tainted: G C 4.14.13-ti-r25 #62
    Hardware name: Generic DRA74X (Flattened Device Tree)
    task: ec173080 task.stack: ec0a8000
    PC is at pa>  
---
 drivers/crypto/omap-crypto.c   | 24 +++---
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/omap-crypto.c b/drivers/crypto/omap-crypto.c
index 2c42e4b..5056c4b 100644
--- a/drivers/crypto/omap-crypto.c
+++ b/drivers/crypto/omap-crypto.c
@@ -161,24 +161,24 @@ void omap_crypto_cleanup(struct scatterlist *sg, struct scatterlist *orig,
 			 int offset, int len, u8 flags_shift,
 			 unsigned long flags)
 {
-	void *buf;
-	int pages;
-
 	flags >>= flags_shift;
-	flags &= OMAP_CRYPTO_COPY_MASK;
 
-	if (!flags)
-		return;
+	if (flags & OMAP_CRYPTO_DATA_COPIED) {
+		void *buf;
+		int pages;
 
-	buf = sg_virt(sg);
-	pages = get_order(len);
+		if (WARN_ON(sg_page(sg) == NULL))
+			return;
 
-	if (orig && (flags & OMAP_CRYPTO_COPY_MASK))
-		scatterwalk_map_and_copy(buf, orig, offset, len, 1);
+		buf = sg_virt(sg);
+		pages = get_order(len);
 
-	if (flags & OMAP_CRYPTO_DATA_COPIED)
+		if (orig)
+			scatterwalk_map_and_copy(buf, orig, offset, len, 1);
 		free_pages((unsigned long)buf, pages);
-	else if (flags & OMAP_CRYPTO_SG_COPIED)
+	}
+
+	if (flags & OMAP_CRYPTO_SG_COPIED)
 		kfree(sg);
 }
 EXPORT_SYMBOL_GPL(omap_crypto_cleanup);


Re: [PATCH] crypto: talitos - fix IPsec cipher in length

2018-03-22 Thread Christophe LEROY



Le 16/03/2018 à 15:07, Horia Geantă a écrit :

On 3/16/2018 2:42 PM, Christophe LEROY wrote:

Le 16/03/2018 à 09:48, Horia Geantă a écrit :

For SEC 2.x+, cipher in length must contain only the ciphertext length.
In case of using hardware ICV checking, the ICV length is provided via
the "extent" field of the descriptor pointer.

Cc:  # 4.8+
Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using 
HMAC_SNOOP_NO_AFEU")


It looks like the issue comes more from commit fbb22137c4d9b ("crypto:
talitos - fix use of sg_link_tbl_len"), doesn't it ?


No, the first commit that breaks IPsec for SEC 2.x+ is the one I mentioned.


Today without your patch, IPsec works well on my mpc8321E. It was broken
by 549bd8bc5987 and fixed by fbb22137c4d9b.
But it seems the fix is not complete as it doesn't work yet in your case.



Afterwards, the refactoring of helper functions lead to current situation where
talitos_sg_map() is fed with "len" parameter that is used for two things:
-HW S/G table entries generation
-setting talitos pointer length

But in certain cases (like pointer nr. 4 - cipher in - for SEC 2.x+ IPsec),
talitos pointer length is only part of the total length, the other part being
set in the "extent" pointer field.

Currently talitos_sg_map() does not accommodate for this case.
In order to keep the fix to a minimum I've overwritten talitos pointer length:
-first talitos_sg_map() sets length to sg_link_tbl_len = cryptlen + authsize
-in case of SEC 2.x IPsec, length is corrected to cryptlen (while extent = 
authsize)


I have proposed a v2 version of your patch which takes it into 
talitos_sg_map() hence avoiding direct access to ptr[4] without using 
the helpers.


Regards
Christophe



Regards,
Horia



[PATCH v2] crypto: talitos - fix IPsec cipher in length

2018-03-22 Thread Christophe Leroy
For SEC 2.x+, cipher in length must contain only the ciphertext length.
In case of using hardware ICV checking, the ICV length is provided via
the "extent" field of the descriptor pointer.

Cc:  # 4.8+
Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using 
HMAC_SNOOP_NO_AFEU")
Reported-by: Horia Geantă 
Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 6882fa2f8bad..016ff8c4c305 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1130,10 +1130,10 @@ static int sg_to_link_tbl_offset(struct scatterlist 
*sg, int sg_count,
return count;
 }
 
-static int talitos_sg_map(struct device *dev, struct scatterlist *src,
-  unsigned int len, struct talitos_edesc *edesc,
-  struct talitos_ptr *ptr,
-  int sg_count, unsigned int offset, int tbl_off)
+static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
+ unsigned int len, struct talitos_edesc *edesc,
+ struct talitos_ptr *ptr, int sg_count,
+ unsigned int offset, int tbl_off, int elen)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
@@ -1142,6 +1142,7 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
to_talitos_ptr(ptr, 0, 0, is_sec1);
return 1;
}
+   to_talitos_ptr_ext_set(ptr, elen, is_sec1);
if (sg_count == 1) {
to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
return sg_count;
@@ -1150,7 +1151,7 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
return sg_count;
}
-   sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
+   sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
 >link_tbl[tbl_off]);
if (sg_count == 1) {
/* Only one segment now, so no link tbl needed*/
@@ -1164,6 +1165,15 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
return sg_count;
 }
 
+static int talitos_sg_map(struct device *dev, struct scatterlist *src,
+ unsigned int len, struct talitos_edesc *edesc,
+ struct talitos_ptr *ptr, int sg_count,
+ unsigned int offset, int tbl_off)
+{
+   return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
+ tbl_off, 0);
+}
+
 /*
  * fill in and submit ipsec_esp descriptor
  */
@@ -1181,7 +1191,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
unsigned int ivsize = crypto_aead_ivsize(aead);
int tbl_off = 0;
int sg_count, ret;
-   int sg_link_tbl_len;
+   int elen = 0;
bool sync_needed = false;
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
@@ -1223,17 +1233,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
 * extent is bytes of HMAC postpended to ciphertext,
 * typically 12 for ipsec
 */
-   sg_link_tbl_len = cryptlen;
-
-   if (is_ipsec_esp) {
-   to_talitos_ptr_ext_set(>ptr[4], authsize, is_sec1);
-
-   if (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)
-   sg_link_tbl_len += authsize;
-   }
+   if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
+   elen = authsize;
 
-   ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
->ptr[4], sg_count, areq->assoclen, tbl_off);
+   ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, >ptr[4],
+sg_count, areq->assoclen, tbl_off, elen);
 
if (ret > 1) {
tbl_off += ret;
-- 
2.13.3



Re: [PATCH 7/9] crypto: picoxcell - don't leak pointers to authenc keys

2018-03-22 Thread Jamie Iles
On Wed, Mar 21, 2018 at 07:00:55PM +0200, Tudor Ambarus wrote:
> Signed-off-by: Tudor Ambarus 

Reviewed-by: Jamie Iles 

> ---
>  drivers/crypto/picoxcell_crypto.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/crypto/picoxcell_crypto.c 
> b/drivers/crypto/picoxcell_crypto.c
> index 4ef52c9..a4df966 100644
> --- a/drivers/crypto/picoxcell_crypto.c
> +++ b/drivers/crypto/picoxcell_crypto.c
> @@ -499,10 +499,12 @@ static int spacc_aead_setkey(struct crypto_aead *tfm, 
> const u8 *key,
>   memcpy(ctx->hash_ctx, keys.authkey, keys.authkeylen);
>   ctx->hash_key_len = keys.authkeylen;
>  
> + memzero_explicit(, sizeof(keys));
>   return 0;
>  
>  badkey:
>   crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
> + memzero_explicit(, sizeof(keys));
>   return -EINVAL;
>  }
>  
> -- 
> 2.9.4
> 


Re: [PATCH 9/9] crypto: talitos - don't leak pointers to authenc keys

2018-03-22 Thread Christophe LEROY



Le 21/03/2018 à 18:00, Tudor Ambarus a écrit :

Signed-off-by: Tudor Ambarus 


Reviewed-by: Christophe Leroy 


---
  drivers/crypto/talitos.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 447cb8b..c92efc7 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -904,10 +904,12 @@ static int aead_setkey(struct crypto_aead *authenc,
ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
  DMA_TO_DEVICE);
  
+	memzero_explicit(, sizeof(keys));

return 0;
  
  badkey:

crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
+   memzero_explicit(, sizeof(keys));
return -EINVAL;
  }
  



Re: [PATCH 1/5 v4] add compression algorithm zBeWalgo

2018-03-22 Thread Benjamin Warnke
Hi Philippe,

> Actually to be consistent if you want to use GPL-2-0 (and not "or
> later") you should use:
> 
> 1. at the top, for a c. file:
> // SPDX-License-Identifier: GPL-2.0
> 
> or for a .h file:
> /* SPDX-License-Identifier: GPL-2.0 */
> 
> The doc explains it all. Including the comment style (a topic that has
> been discussed also on list quite bit: Linus had the final word there)
> 
> 2. and in your MODULE_LICENSE macro:
> 
> MODULE_LICENSE("GPL v2");
> 
>  because a MODULE_LICENSE("GPL"); would mean GPL-2.0+ (e.g. or any
> later version) and this would not match your top level license tag.

Thanks, I have done this correctly in my files, but accidentally written it 
wrong in my mail.

Cordinally
Benjamin Warnke