Skip to content
Snippets Groups Projects
  1. Jul 30, 2022
  2. Jun 24, 2022
    • Ignat Korchagin's avatar
      crypto: rsa - implement Chinese Remainder Theorem for faster private key operations · f145d411
      Ignat Korchagin authored
      Changes from v1:
        * exported mpi_sub and mpi_mul, otherwise the build fails when RSA is a module
      
      The kernel RSA ASN.1 private key parser already supports only private keys with
      additional values to be used with the Chinese Remainder Theorem [1], but these
      values are currently not used.
      
      This rudimentary CRT implementation speeds up RSA private key operations for the
      following Go benchmark up to ~3x.
      
      This implementation also tries to minimise the allocation of additional MPIs,
      so existing MPIs are reused as much as possible (hence the variable names are a
      bit weird).
      
      The benchmark used:
      
      ```
      package keyring_test
      
      import (
      	"crypto"
      	"crypto/rand"
      	"crypto/rsa"
      	"crypto/x509"
      	"io"
      	"syscall"
      	"testing"
      	"unsafe"
      )
      
      type KeySerial int32
      type Keyring int32
      
      const (
      	KEY_SPEC_PROCESS_KEYRING Keyring = -2
      	KEYCTL_PKEY_SIGN                 = 27
      )
      
      var (
      	keyTypeAsym = []byte("asymmetric\x00")
      	sha256pkcs1 = []byte("enc=pkcs1 hash=sha256\x00")
      )
      
      func (keyring Keyring) LoadAsym(desc string, payload []byte) (KeySerial, error) {
      	cdesc := []byte(desc + "\x00")
      	serial, _, errno := syscall.Syscall6(syscall.SYS_ADD_KEY, uintptr(unsafe.Pointer(&keyTypeAsym[0])), uintptr(unsafe.Pointer(&cdesc[0])), uintptr(unsafe.Pointer(&payload[0])), uintptr(len(payload)), uintptr(keyring), uintptr(0))
      	if errno == 0 {
      		return KeySerial(serial), nil
      	}
      
      	return KeySerial(serial), errno
      }
      
      type pkeyParams struct {
      	key_id         KeySerial
      	in_len         uint32
      	out_or_in2_len uint32
      	__spare        [7]uint32
      }
      
      // the output signature buffer is an input parameter here, because we want to
      // avoid Go buffer allocation leaking into our benchmarks
      func (key KeySerial) Sign(info, digest, out []byte) error {
      	var params pkeyParams
      	params.key_id = key
      	params.in_len = uint32(len(digest))
      	params.out_or_in2_len = uint32(len(out))
      
      	_, _, errno := syscall.Syscall6(syscall.SYS_KEYCTL, KEYCTL_PKEY_SIGN, uintptr(unsafe.Pointer(&params)), uintptr(unsafe.Pointer(&info[0])), uintptr(unsafe.Pointer(&digest[0])), uintptr(unsafe.Pointer(&out[0])), uintptr(0))
      	if errno == 0 {
      		return nil
      	}
      
      	return errno
      }
      
      func BenchmarkSign(b *testing.B) {
      	priv, err := rsa.GenerateKey(rand.Reader, 2048)
      	if err != nil {
      		b.Fatalf("failed to generate private key: %v", err)
      	}
      
      	pkcs8, err := x509.MarshalPKCS8PrivateKey(priv)
      	if err != nil {
      		b.Fatalf("failed to serialize the private key to PKCS8 blob: %v", err)
      	}
      
      	serial, err := KEY_SPEC_PROCESS_KEYRING.LoadAsym("test rsa key", pkcs8)
      	if err != nil {
      		b.Fatalf("failed to load the private key into the keyring: %v", err)
      	}
      
      	b.Logf("loaded test rsa key: %v", serial)
      
      	digest := make([]byte, 32)
      	_, err = io.ReadFull(rand.Reader, digest)
      	if err != nil {
      		b.Fatalf("failed to generate a random digest: %v", err)
      	}
      
      	sig := make([]byte, 256)
      	for n := 0; n < b.N; n++ {
      		err = serial.Sign(sha256pkcs1, digest, sig)
      		if err != nil {
      			b.Fatalf("failed to sign the digest: %v", err)
      		}
      	}
      
      	err = rsa.VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, digest, sig)
      	if err != nil {
      		b.Fatalf("failed to verify the signature: %v", err)
      	}
      }
      ```
      
      [1]: https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Using_the_Chinese_remainder_algorithm
      
      
      
      Signed-off-by: default avatarIgnat Korchagin <ignat@cloudflare.com>
      Reported-by: default avatarkernel test robot <lkp@intel.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      f145d411
  3. Mar 02, 2022
  4. Jan 07, 2022
  5. Aug 12, 2021
    • Hongbo Li's avatar
      lib/mpi: use kcalloc in mpi_resize · b6f75672
      Hongbo Li authored
      
      We should set the additional space to 0 in mpi_resize().
      So use kcalloc() instead of kmalloc_array().
      
      In lib/mpi/ec.c:
      /****************
       * Resize the array of A to NLIMBS. the additional space is cleared
       * (set to 0) [done by m_realloc()]
       */
      int mpi_resize(MPI a, unsigned nlimbs)
      
      Like the comment of kernel's mpi_resize() said, the additional space
      need to be set to 0, but when a->d is not NULL, it does not set.
      
      The kernel's mpi lib is from libgcrypt, the mpi resize in libgcrypt
      is _gcry_mpi_resize() which set the additional space to 0.
      
      This bug may cause mpi api which use mpi_resize() get wrong result
      under the condition of using the additional space without initiation.
      If this condition is not met, the bug would not be triggered.
      Currently in kernel, rsa, sm2 and dh use mpi lib, and they works well,
      so the bug is not triggered in these cases.
      
      add_points_edwards() use the additional space directly, so it will
      get a wrong result.
      
      Fixes: cdec9cb5 ("crypto: GnuPG based MPI lib - source files (part 1)")
      Signed-off-by: default avatarHongbo Li <herberthbli@tencent.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      b6f75672
  6. Jul 01, 2021
  7. Oct 30, 2020
  8. Oct 16, 2020
  9. Oct 02, 2020
  10. Sep 25, 2020
  11. Aug 09, 2020
    • Masahiro Yamada's avatar
      kbuild: trace functions in subdirectories of lib/ · b16838c6
      Masahiro Yamada authored
      
      ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE)
      
      exists here in sub-directories of lib/ to keep the behavior of
      commit 2464a609 ("ftrace: do not trace library functions").
      
      Since that commit, not only the objects in lib/ but also the ones in
      the sub-directories are excluded from ftrace (although the commit
      description did not explicitly mention this).
      
      However, most of library functions in sub-directories are not so hot.
      Re-add them to ftrace.
      
      Going forward, only the objects right under lib/ will be excluded.
      
      Cc: Ingo Molnar <mingo@kernel.org>
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      Acked-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      b16838c6
    • Masahiro Yamada's avatar
      kbuild: introduce ccflags-remove-y and asflags-remove-y · 15d5761a
      Masahiro Yamada authored
      
      CFLAGS_REMOVE_<file>.o filters out flags when compiling a particular
      object, but there is no convenient way to do that for every object in
      a directory.
      
      Add ccflags-remove-y and asflags-remove-y to make it easily.
      
      Use ccflags-remove-y to clean up some Makefiles.
      
      The add/remove order works as follows:
      
       [1] KBUILD_CFLAGS specifies compiler flags used globally
      
       [2] ccflags-y adds compiler flags for all objects in the
           current Makefile
      
       [3] ccflags-remove-y removes compiler flags for all objects in the
           current Makefile (New feature)
      
       [4] CFLAGS_<file> adds compiler flags per file.
      
       [5] CFLAGS_REMOVE_<file> removes compiler flags per file.
      
      Having [3] before [4] allows us to remove flags from most (but not all)
      objects in the current Makefile.
      
      For example, kernel/trace/Makefile removes $(CC_FLAGS_FTRACE)
      from all objects in the directory, then adds it back to
      trace_selftest_dynamic.o and CFLAGS_trace_kprobe_selftest.o
      
      The same applies to lib/livepatch/Makefile.
      
      Please note ccflags-remove-y has no effect to the sub-directories.
      In contrast, the previous notation got rid of compiler flags also from
      all the sub-directories.
      
      The following are not affected because they have no sub-directories:
      
        arch/arm/boot/compressed/
        arch/powerpc/xmon/
        arch/sh/
        kernel/trace/
      
      However, lib/ has several sub-directories.
      
      To keep the behavior, I added ccflags-remove-y to all Makefiles
      in subdirectories of lib/, except the following:
      
        lib/vdso/Makefile        - Kbuild does not descend into this Makefile
        lib/raid/test/Makefile   - This is not used for the kernel build
      
      I think commit 2464a609 ("ftrace: do not trace library functions")
      excluded too much. In the next commit, I will remove ccflags-remove-y
      from the sub-directories of lib/.
      
      Suggested-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      Acked-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
      Acked-by: Brendan Higgins <brendanhiggins@google.com> (KUnit)
      Tested-by: default avatarAnders Roxell <anders.roxell@linaro.org>
      15d5761a
  12. Aug 07, 2020
    • Waiman Long's avatar
      mm, treewide: rename kzfree() to kfree_sensitive() · 453431a5
      Waiman Long authored
      
      As said by Linus:
      
        A symmetric naming is only helpful if it implies symmetries in use.
        Otherwise it's actively misleading.
      
        In "kzalloc()", the z is meaningful and an important part of what the
        caller wants.
      
        In "kzfree()", the z is actively detrimental, because maybe in the
        future we really _might_ want to use that "memfill(0xdeadbeef)" or
        something. The "zero" part of the interface isn't even _relevant_.
      
      The main reason that kzfree() exists is to clear sensitive information
      that should not be leaked to other future users of the same memory
      objects.
      
      Rename kzfree() to kfree_sensitive() to follow the example of the recently
      added kvfree_sensitive() and make the intention of the API more explicit.
      In addition, memzero_explicit() is used to clear the memory to make sure
      that it won't get optimized away by the compiler.
      
      The renaming is done by using the command sequence:
      
        git grep -w --name-only kzfree |\
        xargs sed -i 's/kzfree/kfree_sensitive/'
      
      followed by some editing of the kfree_sensitive() kerneldoc and adding
      a kzfree backward compatibility macro in slab.h.
      
      [akpm@linux-foundation.org: fs/crypto/inline_crypt.c needs linux/slab.h]
      [akpm@linux-foundation.org: fix fs/crypto/inline_crypt.c some more]
      
      Suggested-by: default avatarJoe Perches <joe@perches.com>
      Signed-off-by: default avatarWaiman Long <longman@redhat.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Acked-by: default avatarDavid Howells <dhowells@redhat.com>
      Acked-by: default avatarMichal Hocko <mhocko@suse.com>
      Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
      Cc: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
      Cc: James Morris <jmorris@namei.org>
      Cc: "Serge E. Hallyn" <serge@hallyn.com>
      Cc: Joe Perches <joe@perches.com>
      Cc: Matthew Wilcox <willy@infradead.org>
      Cc: David Rientjes <rientjes@google.com>
      Cc: Dan Carpenter <dan.carpenter@oracle.com>
      Cc: "Jason A . Donenfeld" <Jason@zx2c4.com>
      Link: http://lkml.kernel.org/r/20200616154311.12314-3-longman@redhat.com
      
      
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      453431a5
  13. Jul 31, 2020
  14. Apr 30, 2020
    • Nathan Chancellor's avatar
      lib/mpi: Fix 64-bit MIPS build with Clang · 18f1ca46
      Nathan Chancellor authored
      When building 64r6_defconfig with CONFIG_MIPS32_O32 disabled and
      CONFIG_CRYPTO_RSA enabled:
      
      lib/mpi/generic_mpih-mul1.c:37:24: error: invalid use of a cast in a
      inline asm context requiring an l-value: remove the cast
      or build with -fheinous-gnu-extensions
                      umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
                      ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      lib/mpi/longlong.h:664:22: note: expanded from macro 'umul_ppmm'
                       : "=d" ((UDItype)(w0))
                               ~~~~~~~~~~^~~
      lib/mpi/generic_mpih-mul1.c:37:13: error: invalid use of a cast in a
      inline asm context requiring an l-value: remove the cast
      or build with -fheinous-gnu-extensions
                      umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
                      ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      lib/mpi/longlong.h:668:22: note: expanded from macro 'umul_ppmm'
                       : "=d" ((UDItype)(w1))
                               ~~~~~~~~~~^~~
      2 errors generated.
      
      This special case for umul_ppmm for MIPS64r6 was added in
      commit bbc25bee ("lib/mpi: Fix umul_ppmm() for MIPS64r6"), due to
      GCC being inefficient and emitting a __multi3 intrinsic.
      
      There is no such issue with clang; with this patch applied, I can build
      this configuration without any problems and there are no link errors
      like mentioned in the commit above (which I can still reproduce with
      GCC 9.3.0 when that commit is reverted). Only use this definition when
      GCC is being used.
      
      This really should have been caught by commit b0c091ae ("lib/mpi:
      Eliminate unused umul_ppmm definitions for MIPS") when I was messing
      around in this area but I was not testing 64-bit MIPS at the time.
      
      Link: https://github.com/ClangBuiltLinux/linux/issues/885
      
      
      Reported-by: default avatarDmitry Golovin <dima@golovin.in>
      Signed-off-by: default avatarNathan Chancellor <natechancellor@gmail.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      18f1ca46
  15. Apr 24, 2020
  16. Aug 22, 2019
    • Nathan Chancellor's avatar
      lib/mpi: Eliminate unused umul_ppmm definitions for MIPS · b0c091ae
      Nathan Chancellor authored
      Clang errors out when building this macro:
      
      lib/mpi/generic_mpih-mul1.c:37:24: error: invalid use of a cast in a
      inline asm context requiring an l-value: remove the cast or build with
      -fheinous-gnu-extensions
                      umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
                      ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      lib/mpi/longlong.h:652:20: note: expanded from macro 'umul_ppmm'
              : "=l" ((USItype)(w0)), \
                      ~~~~~~~~~~^~~
      lib/mpi/generic_mpih-mul1.c:37:3: error: invalid output constraint '=h'
      in asm
                      umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb);
                      ^
      lib/mpi/longlong.h:653:7: note: expanded from macro 'umul_ppmm'
                   "=h" ((USItype)(w1)) \
                   ^
      2 errors generated.
      
      The C version that is used for GCC 4.4 and up works well with clang;
      however, it is not currently being used because Clang masks itself
      as GCC 4.2.1 for compatibility reasons. As Nick points out, we require
      GCC 4.6 and newer in the kernel so we can eliminate all of the
      versioning checks and just use the C version of umul_ppmm for all
      supported compilers.
      
      Link: https://github.com/ClangBuiltLinux/linux/issues/605
      
      
      Suggested-by: default avatarNick Desaulniers <ndesaulniers@google.com>
      Signed-off-by: default avatarNathan Chancellor <natechancellor@gmail.com>
      Reviewed-by: default avatarNick Desaulniers <ndesaulniers@google.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      b0c091ae
  17. Jul 17, 2019
  18. Jul 03, 2019
  19. May 24, 2019
    • Thomas Gleixner's avatar
      treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 26 · 465ae836
      Thomas Gleixner authored
      
      Based on 1 normalized pattern(s):
      
        gnupg 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 gnupg is distributed in the hope that
        it will be useful but without any warranty without even the implied
        warranty of merchantability or fitness for a particular purpose see
        the gnu general public license for more details you should have
        received a copy of the gnu general public license along with this
        program if not write to the free software foundation inc 59 temple
        place suite 330 boston ma 02111 1307 usa note this code is heavily
        based on the gnu mp library actually it s the same code with only
        minor changes in the way the data is stored this is to support the
        abstraction of an optional secure memory allocation which may be
        used to avoid revealing of sensitive data due to paging etc the gnu
        mp library itself is published under the lgpl however i decided to
        publish this code under the plain gpl
      
      extracted by the scancode license scanner the SPDX license identifier
      
        GPL-2.0-or-later
      
      has been chosen to replace the boilerplate/reference in 14 file(s).
      
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Reviewed-by: default avatarAllison Randal <allison@lohutok.net>
      Reviewed-by: default avatarKate Stewart <kstewart@linuxfoundation.org>
      Cc: linux-spdx@vger.kernel.org
      Link: https://lkml.kernel.org/r/20190520170856.639982569@linutronix.de
      
      
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      465ae836
  20. Aug 07, 2018
  21. Jun 12, 2018
    • Kees Cook's avatar
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook authored
      
      The kzalloc() function has a 2-factor argument form, kcalloc(). This
      patch replaces cases of:
      
              kzalloc(a * b, gfp)
      
      with:
              kcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kzalloc(a * b * c, gfp)
      
      with:
      
              kzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kzalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc
      + kcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(sizeof(THING) * C2, ...)
      |
        kzalloc(sizeof(TYPE) * C2, ...)
      |
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(C1 * C2, ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      6396bb22
    • Kees Cook's avatar
      treewide: kmalloc() -> kmalloc_array() · 6da2ec56
      Kees Cook authored
      
      The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
      patch replaces cases of:
      
              kmalloc(a * b, gfp)
      
      with:
              kmalloc_array(a * b, gfp)
      
      as well as handling cases of:
      
              kmalloc(a * b * c, gfp)
      
      with:
      
              kmalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kmalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kmalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The tools/ directory was manually excluded, since it has its own
      implementation of kmalloc().
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kmalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kmalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kmalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kmalloc
      + kmalloc_array
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kmalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(sizeof(THING) * C2, ...)
      |
        kmalloc(sizeof(TYPE) * C2, ...)
      |
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(C1 * C2, ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      6da2ec56
  22. Jun 08, 2018
  23. Dec 22, 2017
    • James Hogan's avatar
      lib/mpi: Fix umul_ppmm() for MIPS64r6 · bbc25bee
      James Hogan authored
      
      Current MIPS64r6 toolchains aren't able to generate efficient
      DMULU/DMUHU based code for the C implementation of umul_ppmm(), which
      performs an unsigned 64 x 64 bit multiply and returns the upper and
      lower 64-bit halves of the 128-bit result. Instead it widens the 64-bit
      inputs to 128-bits and emits a __multi3 intrinsic call to perform a 128
      x 128 multiply. This is both inefficient, and it results in a link error
      since we don't include __multi3 in MIPS linux.
      
      For example commit 90a53e44 ("cfg80211: implement regdb signature
      checking") merged in v4.15-rc1 recently broke the 64r6_defconfig and
      64r6el_defconfig builds by indirectly selecting MPILIB. The same build
      errors can be reproduced on older kernels by enabling e.g. CRYPTO_RSA:
      
      lib/mpi/generic_mpih-mul1.o: In function `mpihelp_mul_1':
      lib/mpi/generic_mpih-mul1.c:50: undefined reference to `__multi3'
      lib/mpi/generic_mpih-mul2.o: In function `mpihelp_addmul_1':
      lib/mpi/generic_mpih-mul2.c:49: undefined reference to `__multi3'
      lib/mpi/generic_mpih-mul3.o: In function `mpihelp_submul_1':
      lib/mpi/generic_mpih-mul3.c:49: undefined reference to `__multi3'
      lib/mpi/mpih-div.o In function `mpihelp_divrem':
      lib/mpi/mpih-div.c:205: undefined reference to `__multi3'
      lib/mpi/mpih-div.c:142: undefined reference to `__multi3'
      
      Therefore add an efficient MIPS64r6 implementation of umul_ppmm() using
      inline assembly and the DMULU/DMUHU instructions, to prevent __multi3
      calls being emitted.
      
      Fixes: 7fd08ca5 ("MIPS: Add build support for the MIPS R6 ISA")
      Signed-off-by: default avatarJames Hogan <jhogan@kernel.org>
      Cc: Ralf Baechle <ralf@linux-mips.org>
      Cc: Herbert Xu <herbert@gondor.apana.org.au>
      Cc: "David S. Miller" <davem@davemloft.net>
      Cc: linux-mips@linux-mips.org
      Cc: linux-crypto@vger.kernel.org
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      bbc25bee
  24. Nov 10, 2017
    • Eric Biggers's avatar
      lib/mpi: call cond_resched() from mpi_powm() loop · 1d9ddde1
      Eric Biggers authored
      
      On a non-preemptible kernel, if KEYCTL_DH_COMPUTE is called with the
      largest permitted inputs (16384 bits), the kernel spends 10+ seconds
      doing modular exponentiation in mpi_powm() without rescheduling.  If all
      threads do it, it locks up the system.  Moreover, it can cause
      rcu_sched-stall warnings.
      
      Notwithstanding the insanity of doing this calculation in kernel mode
      rather than in userspace, fix it by calling cond_resched() as each bit
      from the exponent is processed.  It's still noninterruptible, but at
      least it's preemptible now.
      
      Do the cond_resched() once per bit rather than once per MPI limb because
      each limb might still easily take 100+ milliseconds on slow CPUs.
      
      Cc: <stable@vger.kernel.org> # v4.12+
      Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      1d9ddde1
  25. Nov 02, 2017
    • Greg Kroah-Hartman's avatar
      License cleanup: add SPDX GPL-2.0 license identifier to files with no license · b2441318
      Greg Kroah-Hartman authored
      
      Many source files in the tree are missing licensing information, which
      makes it harder for compliance tools to determine the correct license.
      
      By default all files without license information are under the default
      license of the kernel, which is GPL version 2.
      
      Update the files which contain no license information with the 'GPL-2.0'
      SPDX license identifier.  The SPDX identifier is a legally binding
      shorthand, which can be used instead of the full boiler plate text.
      
      This patch is based on work done by Thomas Gleixner and Kate Stewart and
      Philippe Ombredanne.
      
      How this work was done:
      
      Patches were generated and checked against linux-4.14-rc6 for a subset of
      the use cases:
       - file had no licensing information it it.
       - file was a */uapi/* one with no licensing information in it,
       - file was a */uapi/* one with existing licensing information,
      
      Further patches will be generated in subsequent months to fix up cases
      where non-standard license headers were used, and references to license
      had to be inferred by heuristics based on keywords.
      
      The analysis to determine which SPDX License Identifier to be applied to
      a file was done in a spreadsheet of side by side results from of the
      output of two independent scanners (ScanCode & Windriver) producing SPDX
      tag:value files created by Philippe Ombredanne.  Philippe prepared the
      base worksheet, and did an initial spot review of a few 1000 files.
      
      The 4.13 kernel was the starting point of the analysis with 60,537 files
      assessed.  Kate Stewart did a file by file comparison of the scanner
      results in the spreadsheet to determine which SPDX license identifier(s)
      to be applied to the file. She confirmed any determination that was not
      immediately clear with lawyers working with the Linux Foundation.
      
      Criteria used to select files for SPDX license identifier tagging was:
       - Files considered eligible had to be source code files.
       - Make and config files were included as candidates if they contained >5
         lines of source
       - File already had some variant of a license header in it (even if <5
         lines).
      
      All documentation files were explicitly excluded.
      
      The following heuristics were used to determine which SPDX license
      identifiers to apply.
      
       - when both scanners couldn't find any license traces, file was
         considered to have no license information in it, and the top level
         COPYING file license applied.
      
         For non */uapi/* files that summary was:
      
         SPDX license identifier                            # files
         ---------------------------------------------------|-------
         GPL-2.0                                              11139
      
         and resulted in the first patch in this series.
      
         If that file was a */uapi/* path one, it was "GPL-2.0 WITH
         Linux-syscall-note" otherwise it was "GPL-2.0".  Results of that was:
      
         SPDX license identifier                            # files
         ---------------------------------------------------|-------
         GPL-2.0 WITH Linux-syscall-note                        930
      
         and resulted in the second patch in this series.
      
       - if a file had some form of licensing information in it, and was one
         of the */uapi/* ones, it was denoted with the Linux-syscall-note if
         any GPL family license was found in the file or had no licensing in
         it (per prior point).  Results summary:
      
         SPDX license identifier                            # files
         ---------------------------------------------------|------
         GPL-2.0 WITH Linux-syscall-note                       270
         GPL-2.0+ WITH Linux-syscall-note                      169
         ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause)    21
         ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)    17
         LGPL-2.1+ WITH Linux-syscall-note                      15
         GPL-1.0+ WITH Linux-syscall-note                       14
         ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause)    5
         LGPL-2.0+ WITH Linux-syscall-note                       4
         LGPL-2.1 WITH Linux-syscall-note                        3
         ((GPL-2.0 WITH Linux-syscall-note) OR MIT)              3
         ((GPL-2.0 WITH Linux-syscall-note) AND MIT)             1
      
         and that resulted in the third patch in this series.
      
       - when the two scanners agreed on the detected license(s), that became
         the concluded license(s).
      
       - when there was disagreement between the two scanners (one detected a
         license but the other didn't, or they both detected different
         licenses) a manual inspection of the file occurred.
      
       - In most cases a manual inspection of the information in the file
         resulted in a clear resolution of the license that should apply (and
         which scanner probably needed to revisit its heuristics).
      
       - When it was not immediately clear, the license identifier was
         confirmed with lawyers working with the Linux Foundation.
      
       - If there was any question as to the appropriate license identifier,
         the file was flagged for further research and to be revisited later
         in time.
      
      In total, over 70 hours of logged manual review was done on the
      spreadsheet to determine the SPDX license identifiers to apply to the
      source files by Kate, Philippe, Thomas and, in some cases, confirmation
      by lawyers working with the Linux Foundation.
      
      Kate also obtained a third independent scan of the 4.13 code base from
      FOSSology, and compared selected files where the other two scanners
      disagreed against that SPDX file, to see if there was new insights.  The
      Windriver scanner is based on an older version of FOSSology in part, so
      they are related.
      
      Thomas did random spot checks in about 500 files from the spreadsheets
      for the uapi headers and agreed with SPDX license identifier in the
      files he inspected. For the non-uapi files Thomas did random spot checks
      in about 15000 files.
      
      In initial set of patches against 4.14-rc6, 3 files were found to have
      copy/paste license identifier errors, and have been fixed to reflect the
      correct identifier.
      
      Additionally Philippe spent 10 hours this week doing a detailed manual
      inspection and review of the 12,461 patched files from the initial patch
      version early this week with:
       - a full scancode scan run, collecting the matched texts, detected
         license ids and scores
       - reviewing anything where there was a license detected (about 500+
         files) to ensure that the applied SPDX license was correct
       - reviewing anything where there was no detection but the patch license
         was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
         SPDX license was correct
      
      This produced a worksheet with 20 files needing minor correction.  This
      worksheet was then exported into 3 different .csv files for the
      different types of files to be modified.
      
      These .csv files were then reviewed by Greg.  Thomas wrote a script to
      parse the csv files and add the proper SPDX tag to the file, in the
      format that the file expected.  This script was further refined by Greg
      based on the output to detect more types of files automatically and to
      distinguish between header and source .c files (which need different
      comment types.)  Finally Greg ran the script using the .csv files to
      generate the patches.
      
      Reviewed-by: default avatarKate Stewart <kstewart@linuxfoundation.org>
      Reviewed-by: default avatarPhilippe Ombredanne <pombredanne@nexb.com>
      Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b2441318
  26. Aug 22, 2017
  27. Aug 17, 2017
    • Stefan Agner's avatar
      lib/mpi: fix build with clang · dea632ca
      Stefan Agner authored
      
      Use just @ to denote comments which works with gcc and clang.
      Otherwise clang reports an escape sequence error:
        error: invalid % escape in inline assembly string
      
      Use %0-%3 as operand references, this avoids:
        error: invalid operand in inline asm: 'umull ${1:r}, ${0:r}, ${2:r}, ${3:r}'
      
      Also remove superfluous casts on output operands to avoid warnings
      such as:
        warning: invalid use of a cast in an inline asm context requiring an l-value
      
      Signed-off-by: default avatarStefan Agner <stefan@agner.ch>
      Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      dea632ca
  28. Nov 25, 2016
    • Andrey Ryabinin's avatar
      mpi: Fix NULL ptr dereference in mpi_powm() [ver #3] · f5527fff
      Andrey Ryabinin authored
      This fixes CVE-2016-8650.
      
      If mpi_powm() is given a zero exponent, it wants to immediately return
      either 1 or 0, depending on the modulus.  However, if the result was
      initalised with zero limb space, no limbs space is allocated and a
      NULL-pointer exception ensues.
      
      Fix this by allocating a minimal amount of limb space for the result when
      the 0-exponent case when the result is 1 and not touching the limb space
      when the result is 0.
      
      This affects the use of RSA keys and X.509 certificates that carry them.
      
      BUG: unable to handle kernel NULL pointer dereference at           (null)
      IP: [<ffffffff8138ce5d>] mpi_powm+0x32/0x7e6
      PGD 0
      Oops: 0002 [#1] SMP
      Modules linked in:
      CPU: 3 PID: 3014 Comm: keyctl Not tainted 4.9.0-rc6-fscache+ #278
      Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014
      task: ffff8804011944c0 task.stack: ffff880401294000
      RIP: 0010:[<ffffffff8138ce5d>]  [<ffffffff8138ce5d>] mpi_powm+0x32/0x7e6
      RSP: 0018:ffff880401297ad8  EFLAGS: 00010212
      RAX: 0000000000000000 RBX: ffff88040868bec0 RCX: ffff88040868bba0
      RDX: ffff88040868b260 RSI: ffff88040868bec0 RDI: ffff88040868bee0
      RBP: ffff880401297ba8 R08: 0000000000000000 R09: 0000000000000000
      R10: 0000000000000047 R11: ffffffff8183b210 R12: 0000000000000000
      R13: ffff8804087c7600 R14: 000000000000001f R15: ffff880401297c50
      FS:  00007f7a7918c700(0000) GS:ffff88041fb80000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 0000000000000000 CR3: 0000000401250000 CR4: 00000000001406e0
      Stack:
       ffff88040868bec0 0000000000000020 ffff880401297b00 ffffffff81376cd4
       0000000000000100 ffff880401297b10 ffffffff81376d12 ffff880401297b30
       ffffffff81376f37 0000000000000100 0000000000000000 ffff880401297ba8
      Call Trace:
       [<ffffffff81376cd4>] ? __sg_page_iter_next+0x43/0x66
       [<ffffffff81376d12>] ? sg_miter_get_next_page+0x1b/0x5d
       [<ffffffff81376f37>] ? sg_miter_next+0x17/0xbd
       [<ffffffff8138ba3a>] ? mpi_read_raw_from_sgl+0xf2/0x146
       [<ffffffff8132a95c>] rsa_verify+0x9d/0xee
       [<ffffffff8132acca>] ? pkcs1pad_sg_set_buf+0x2e/0xbb
       [<ffffffff8132af40>] pkcs1pad_verify+0xc0/0xe1
       [<ffffffff8133cb5e>] public_key_verify_signature+0x1b0/0x228
       [<ffffffff8133d974>] x509_check_for_self_signed+0xa1/0xc4
       [<ffffffff8133cdde>] x509_cert_parse+0x167/0x1a1
       [<ffffffff8133d609>] x509_key_preparse+0x21/0x1a1
       [<ffffffff8133c3d7>] asymmetric_key_preparse+0x34/0x61
       [<ffffffff812fc9f3>] key_create_or_update+0x145/0x399
       [<ffffffff812fe227>] SyS_add_key+0x154/0x19e
       [<ffffffff81001c2b>] do_syscall_64+0x80/0x191
       [<ffffffff816825e4>] entry_SYSCALL64_slow_path+0x25/0x25
      Code: 56 41 55 41 54 53 48 81 ec a8 00 00 00 44 8b 71 04 8b 42 04 4c 8b 67 18 45 85 f6 89 45 80 0f 84 b4 06 00 00 85 c0 75 2f 41 ff ce <49> c7 04 24 01 00 00 00 b0 01 75 0b 48 8b 41 18 48 83 38 01 0f
      RIP  [<ffffffff8138ce5d>] mpi_powm+0x32/0x7e6
       RSP <ffff880401297ad8>
      CR2: 0000000000000000
      ---[ end trace d82015255d4a5d8d ]---
      
      Basically, this is a backport of a libgcrypt patch:
      
      	http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=6e1adb05d290aeeb1c230c763970695f4a538526
      
      
      
      Fixes: cdec9cb5 ("crypto: GnuPG based MPI lib - source files (part 1)")
      Signed-off-by: default avatarAndrey Ryabinin <aryabinin@virtuozzo.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      cc: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
      cc: linux-ima-devel@lists.sourceforge.net
      cc: stable@vger.kernel.org
      Signed-off-by: default avatarJames Morris <james.l.morris@oracle.com>
      f5527fff
  29. Jul 29, 2016
  30. Jul 01, 2016
    • Herbert Xu's avatar
      lib/mpi: Do not do sg_virt · 127827b9
      Herbert Xu authored
      
      Currently the mpi SG helpers use sg_virt which is completely
      broken.  It happens to work with normal kernel memory but will
      fail with anything that is not linearly mapped.
      
      This patch fixes this by using the SG iterator helpers.
      
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      127827b9
    • Herbert Xu's avatar
      crypto: rsa - Generate fixed-length output · 9b45b7bb
      Herbert Xu authored
      
      Every implementation of RSA that we have naturally generates
      output with leading zeroes.  The one and only user of RSA,
      pkcs1pad wants to have those leading zeroes in place, in fact
      because they are currently absent it has to write those zeroes
      itself.
      
      So we shouldn't be stripping leading zeroes in the first place.
      In fact this patch makes rsa-generic produce output with fixed
      length so that pkcs1pad does not need to do any extra work.
      
      This patch also changes DH to use the new interface.
      
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      9b45b7bb
  31. May 31, 2016
    • Nicolai Stange's avatar
      lib/mpi: refactor mpi_read_from_buffer() in terms of mpi_read_raw_data() · 20b5b7f3
      Nicolai Stange authored
      
      mpi_read_from_buffer() and mpi_read_raw_data() do basically the same thing
      except that the former extracts the number of payload bits from the first
      two bytes of the input buffer.
      
      Besides that, the data copying logic is exactly the same.
      
      Replace the open coded buffer to MPI instance conversion by a call to
      mpi_read_raw_data().
      
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      20b5b7f3
    • Nicolai Stange's avatar
      lib/mpi: mpi_read_from_buffer(): sanitize short buffer printk · cdf24b42
      Nicolai Stange authored
      
      The first two bytes of the input buffer encode its expected length and
      mpi_read_from_buffer() prints a console message if the given buffer is too
      short.
      
      However, there are some oddities with how this message is printed:
      - It is printed at the default loglevel. This is different from the
        one used in the case that the first two bytes' value is unsupportedly
        large, i.e. KERN_INFO.
      - The format specifier '%d' is used for unsigned ints.
      - It prints the values of nread and *ret_nread. This is redundant since
        the former is always the latter + 1.
      
      Clean this up as follows:
      - Use pr_info() rather than printk() with no loglevel.
      - Use the format specifiers '%u' in place if '%d'.
      - Do not print the redundant 'nread' but the more helpful 'nbytes' value.
      
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      cdf24b42
    • Nicolai Stange's avatar
      lib/mpi: mpi_read_from_buffer(): return -EINVAL upon too short buffer · 7af791e0
      Nicolai Stange authored
      
      Currently, if the input buffer is shorter than the expected length as
      indicated by its first two bytes, an MPI instance of this expected length
      will be allocated and filled with as much data as is available. The rest
      will remain uninitialized.
      
      Instead of leaving this condition undetected, an error code should be
      reported to the caller.
      
      Since this situation indicates that the input buffer's first two bytes,
      encoding the number of expected bits, are garbled, -EINVAL is appropriate
      here.
      
      If the input buffer is shorter than indicated by its first two bytes,
      make mpi_read_from_buffer() return -EINVAL.
      Get rid of the 'nread' variable: with the new semantics, the total number
      of bytes read from the input buffer is known in advance.
      
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      7af791e0
    • Nicolai Stange's avatar
      lib/mpi: mpi_read_from_buffer(): return error code · 03cdfaad
      Nicolai Stange authored
      
      mpi_read_from_buffer() reads a MPI from a buffer into a newly allocated
      MPI instance. It expects the buffer's leading two bytes to contain the
      number of bits, followed by the actual payload.
      
      On failure, it returns NULL and updates the in/out argument ret_nread
      somewhat inconsistently:
      - If the given buffer is too short to contain the leading two bytes
        encoding the number of bits or their value is unsupported, then
        ret_nread will be cleared.
      - If the allocation of the resulting MPI instance fails, ret_nread is left
        as is.
      
      The only user of mpi_read_from_buffer(), digsig_verify_rsa(), simply checks
      for a return value of NULL and returns -ENOMEM if that happens.
      
      While this is all of cosmetic nature only, there is another error condition
      which currently isn't detectable by the caller of mpi_read_from_buffer():
      if the given buffer is too small to hold the number of bits as encoded in
      its first two bytes, the return value will be non-NULL and *ret_nread > 0.
      
      In preparation of communicating this condition to the caller, let
      mpi_read_from_buffer() return error values by means of the ERR_PTR()
      mechanism.
      
      Make the sole caller of mpi_read_from_buffer(), digsig_verify_rsa(),
      check the return value for IS_ERR() rather than == NULL. If IS_ERR() is
      true, return the associated error value rather than the fixed -ENOMEM.
      
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      03cdfaad
    • Nicolai Stange's avatar
      lib/mpi: mpi_read_raw_data(): fix nbits calculation · eef0df6a
      Nicolai Stange authored
      
      The number of bits, nbits, is calculated in mpi_read_raw_data() as follows:
      
        nbits = nbytes * 8;
      
      Afterwards, the number of leading zero bits of the first byte get
      subtracted:
      
        nbits -= count_leading_zeros(buffer[0]);
      
      However, count_leading_zeros() takes an unsigned long and thus,
      the u8 gets promoted to an unsigned long.
      
      Thus, the above doesn't subtract the number of leading zeros in the most
      significant nonzero input byte from nbits, but the number of leading
      zeros of the most significant nonzero input byte promoted to unsigned long,
      i.e. BITS_PER_LONG - 8 too many.
      
      Fix this by subtracting
      
        count_leading_zeros(...) - (BITS_PER_LONG - 8)
      
      from nbits only.
      
      Fixes: e1045992 ("MPILIB: Provide a function to read raw data into an
                           MPI")
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      eef0df6a
    • Nicolai Stange's avatar
      lib/mpi: mpi_read_raw_data(): purge redundant clearing of nbits · dfd90510
      Nicolai Stange authored
      
      In mpi_read_raw_data(), unsigned nbits is calculated as follows:
      
       nbits = nbytes * 8;
      
      and redundantly cleared later on if nbytes == 0:
      
        if (nbytes > 0)
          ...
        else
          nbits = 0;
      
      Purge this redundant clearing for the sake of clarity.
      
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      dfd90510
Loading