linux/include/crypto
Eric Biggers af3ff8045b crypto: hmac - require that the underlying hash algorithm is unkeyed
Because the HMAC template didn't check that its underlying hash
algorithm is unkeyed, trying to use "hmac(hmac(sha3-512-generic))"
through AF_ALG or through KEYCTL_DH_COMPUTE resulted in the inner HMAC
being used without having been keyed, resulting in sha3_update() being
called without sha3_init(), causing a stack buffer overflow.

This is a very old bug, but it seems to have only started causing real
problems when SHA-3 support was added (requires CONFIG_CRYPTO_SHA3)
because the innermost hash's state is ->import()ed from a zeroed buffer,
and it just so happens that other hash algorithms are fine with that,
but SHA-3 is not.  However, there could be arch or hardware-dependent
hash algorithms also affected; I couldn't test everything.

Fix the bug by introducing a function crypto_shash_alg_has_setkey()
which tests whether a shash algorithm is keyed.  Then update the HMAC
template to require that its underlying hash algorithm is unkeyed.

Here is a reproducer:

    #include <linux/if_alg.h>
    #include <sys/socket.h>

    int main()
    {
        int algfd;
        struct sockaddr_alg addr = {
            .salg_type = "hash",
            .salg_name = "hmac(hmac(sha3-512-generic))",
        };
        char key[4096] = { 0 };

        algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
        bind(algfd, (const struct sockaddr *)&addr, sizeof(addr));
        setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, sizeof(key));
    }

Here was the KASAN report from syzbot:

    BUG: KASAN: stack-out-of-bounds in memcpy include/linux/string.h:341  [inline]
    BUG: KASAN: stack-out-of-bounds in sha3_update+0xdf/0x2e0  crypto/sha3_generic.c:161
    Write of size 4096 at addr ffff8801cca07c40 by task syzkaller076574/3044

    CPU: 1 PID: 3044 Comm: syzkaller076574 Not tainted 4.14.0-mm1+ #25
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  Google 01/01/2011
    Call Trace:
      __dump_stack lib/dump_stack.c:17 [inline]
      dump_stack+0x194/0x257 lib/dump_stack.c:53
      print_address_description+0x73/0x250 mm/kasan/report.c:252
      kasan_report_error mm/kasan/report.c:351 [inline]
      kasan_report+0x25b/0x340 mm/kasan/report.c:409
      check_memory_region_inline mm/kasan/kasan.c:260 [inline]
      check_memory_region+0x137/0x190 mm/kasan/kasan.c:267
      memcpy+0x37/0x50 mm/kasan/kasan.c:303
      memcpy include/linux/string.h:341 [inline]
      sha3_update+0xdf/0x2e0 crypto/sha3_generic.c:161
      crypto_shash_update+0xcb/0x220 crypto/shash.c:109
      shash_finup_unaligned+0x2a/0x60 crypto/shash.c:151
      crypto_shash_finup+0xc4/0x120 crypto/shash.c:165
      hmac_finup+0x182/0x330 crypto/hmac.c:152
      crypto_shash_finup+0xc4/0x120 crypto/shash.c:165
      shash_digest_unaligned+0x9e/0xd0 crypto/shash.c:172
      crypto_shash_digest+0xc4/0x120 crypto/shash.c:186
      hmac_setkey+0x36a/0x690 crypto/hmac.c:66
      crypto_shash_setkey+0xad/0x190 crypto/shash.c:64
      shash_async_setkey+0x47/0x60 crypto/shash.c:207
      crypto_ahash_setkey+0xaf/0x180 crypto/ahash.c:200
      hash_setkey+0x40/0x90 crypto/algif_hash.c:446
      alg_setkey crypto/af_alg.c:221 [inline]
      alg_setsockopt+0x2a1/0x350 crypto/af_alg.c:254
      SYSC_setsockopt net/socket.c:1851 [inline]
      SyS_setsockopt+0x189/0x360 net/socket.c:1830
      entry_SYSCALL_64_fastpath+0x1f/0x96

Reported-by: syzbot <syzkaller@googlegroups.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-11-29 13:39:15 +11:00
..
internal crypto: hmac - require that the underlying hash algorithm is unkeyed 2017-11-29 13:39:15 +11:00
ablk_helper.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
acompress.h crypto: acomp - add driver-side scomp interface 2016-10-25 11:08:31 +08:00
aead.h crypto: doc - clarify AEAD memory structure 2016-12-13 16:38:06 -07:00
aes.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
akcipher.h crypto: akcipher - assume key is already set in maxsize 2017-06-10 12:04:29 +08:00
algapi.h crypto: algapi - make crypto_xor() take separate dst and src arguments 2017-08-04 09:27:15 +08:00
authenc.h crypto: authenc - Export key parsing helper function 2013-10-16 20:56:25 +08:00
b128ops.h [CRYPTO] lib: some common 128-bit block operations, nicely centralized 2006-12-06 18:38:55 -08:00
blowfish.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cast5.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cast6.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cast_common.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cbc.h crypto: cbc - Export CBC implementation 2016-11-28 21:23:21 +08:00
chacha20.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cryptd.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
crypto_wq.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ctr.h [CRYPTO] ctr: Refactor into ctr and rfc3686 2008-01-11 08:16:41 +11:00
des.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
dh.h crypto: dh - return unsigned value for crypto_dh_key_len() 2017-10-12 22:55:05 +08:00
drbg.h crypto: drbg - move to generic async completion 2017-11-03 22:11:19 +08:00
ecdh.h crypto: ecdh - return unsigned value for crypto_ecdh_key_len() 2017-10-12 22:55:00 +08:00
engine.h crypto: engine - replace pr_xxx by dev_xxx 2017-06-19 14:19:54 +08:00
gcm.h crypto: gcm - add GCM IV size constant 2017-09-22 17:43:08 +08:00
gf128mul.h crypto: gf128mul - The x8_ble multiplication functions 2017-11-03 21:50:43 +08:00
ghash.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
hash_info.h keys, trusted: select hash algorithm for TPM2 chips 2015-12-20 15:27:12 +02:00
hash.h crypto: doc - clarify return values for async hash methods 2017-09-22 17:43:03 +08:00
hmac.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
if_alg.h crypto: algif - move to generic async completion 2017-11-03 22:11:18 +08:00
kpp.h crypto: kpp - add get/set_flags helpers 2017-07-18 17:50:57 +08:00
lrw.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mcryptd.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
md5.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
null.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
padlock.h crypto: padlock - Move padlock.h into include/crypto 2011-01-07 14:52:00 +11:00
pcrypt.h crypto: pcrypt - Add pcrypt crypto parallelization wrapper 2010-01-07 15:57:19 +11:00
pkcs7.h PKCS#7: Make trust determination dependent on contents of trust keyring 2016-04-06 16:14:24 +01:00
poly1305.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
public_key.h KEYS: Keyring asymmetric key restrict method with chaining 2017-04-04 14:10:13 -07:00
rng.h crypto: doc - Fix typo in crypto-API.xml 2015-06-04 15:05:08 +08:00
scatterwalk.h crypto: scatterwalk - Inline start/map/done 2016-07-18 17:35:50 +08:00
serpent.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sha1_base.h crypto: sha1 - implement base layer for SHA-1 2015-04-10 21:39:39 +08:00
sha3.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sha256_base.h crypto: sha256 - implement base layer for SHA-256 2015-04-10 21:39:39 +08:00
sha512_base.h crypto: sha512 - implement base layer for SHA-512 2015-04-10 21:39:39 +08:00
sha.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
skcipher.h crypto: skcipher - introduce walksize attribute for SIMD algos 2016-12-30 19:52:47 +08:00
sm3_base.h crypto: sm3 - add OSCCA SM3 secure hash 2017-09-22 17:43:07 +08:00
sm3.h crypto: sm3 - add OSCCA SM3 secure hash 2017-09-22 17:43:07 +08:00
twofish.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
vmac.h crypto: vmac - Make VMAC work when blocks aren't aligned 2012-10-15 22:33:20 +08:00
xts.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00