From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8548333C0; Mon, 22 Jan 2024 00:23:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705882981; cv=none; b=USqOYWJx2P4j4K90Sf/eHgKeUOkJda3SBLhmASGcQekX3aszEouq6qdxW6V4dkHExk1LPz9sNYbPKOjj3Jg7xeOpbGklc6/2sh6ObdWFChw7lzNpbu6fsw/rzj2oDPdNVGhLf3HlcYv0/s42pf0TZbX0mKrs7SmCEm6H7ePoZzI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705882981; c=relaxed/simple; bh=BH8DWDwlQPyIgcG7nEKEMMv58AgI1J8gP1nTyg7ugIg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Dcxfx4exPW4/P78nBq3kroZwpyqwXlAsTPYamBicrDnHddtjCVwpnizb+H/N+y8iwZHhBZkkP4EcjUFgJzT7/DjPgh7xQDOgfUbLgZlsvaLL1Fve9wcGATrfTZc7IVrNstEEfoAN1rnzZUuMHiFv+JdCN/ztnZ7aQx7/t+leNzs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cCCjnk9Z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cCCjnk9Z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C2561C43390; Mon, 22 Jan 2024 00:22:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1705882980; bh=BH8DWDwlQPyIgcG7nEKEMMv58AgI1J8gP1nTyg7ugIg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cCCjnk9ZfbJTWtTAWW2Y96hsCzBFA54lyNCaJNemFRlEvtcjtg1lQP87eZa2oQZTF mjFXr+8jHPoh17UZB3DZsKZ33XW00ejN1/B8DqdWWEbzYLjUmaNSOQ2Aiht7AtLPXT UW4eji6/aV6fekm3SG172KpksMvL5JBPMKp9nplMhxqKPbgnUchMA1ZUO0hvcL4WM6 RXNw5g8f3rvEv6uo4DuNLlvlo1+7wwX8+VS//BdArdzsw/3eYtHk9Lvb/IUY9txC18 FLIYKm7AnrY4SvSae9VNXSHOahlG9pw7Q4yBKdHWQQWEvuV6xlaJXUXVUtw3ntuXUp eG9n+5G2eYsWA== From: Eric Biggers To: linux-crypto@vger.kernel.org, linux-riscv@lists.infradead.org Cc: linux-kernel@vger.kernel.org, Albert Ou , Andy Chiu , Ard Biesheuvel , =?UTF-8?q?Christoph=20M=C3=BCllner?= , Heiko Stuebner , Jerry Shih , Palmer Dabbelt , Paul Walmsley , Phoebe Chen , hongrong.hsu@sifive.com Subject: [PATCH v3 04/10] crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS} Date: Sun, 21 Jan 2024 16:19:15 -0800 Message-ID: <20240122002024.27477-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240122002024.27477-1-ebiggers@kernel.org> References: <20240122002024.27477-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-crypto@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Jerry Shih Add implementations of AES-ECB, AES-CBC, AES-CTR, and AES-XTS, as well as bare (single-block) AES, using the RISC-V vector crypto extensions. The assembly code is derived from OpenSSL code (openssl/openssl#21923) that was dual-licensed so that it could be reused in the kernel. Nevertheless, the assembly has been significantly reworked for integration with the kernel, for example by using regular .S files instead of the so-called perlasm, using the assembler instead of bare '.inst', greatly reducing code duplication, supporting AES-192, and making the code use the same AES key structure as the C code. Co-developed-by: Phoebe Chen Signed-off-by: Phoebe Chen Signed-off-by: Jerry Shih Co-developed-by: Eric Biggers Signed-off-by: Eric Biggers --- arch/riscv/crypto/Kconfig | 16 + arch/riscv/crypto/Makefile | 4 + arch/riscv/crypto/aes-macros.S | 156 +++++ arch/riscv/crypto/aes-riscv64-glue.c | 550 ++++++++++++++++++ .../crypto/aes-riscv64-zvkned-zvbb-zvkg.S | 312 ++++++++++ arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S | 146 +++++ arch/riscv/crypto/aes-riscv64-zvkned.S | 180 ++++++ 7 files changed, 1364 insertions(+) create mode 100644 arch/riscv/crypto/aes-macros.S create mode 100644 arch/riscv/crypto/aes-riscv64-glue.c create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned.S diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig index 10d60edc0110a..ebe805fa3f5f7 100644 --- a/arch/riscv/crypto/Kconfig +++ b/arch/riscv/crypto/Kconfig @@ -1,5 +1,21 @@ # SPDX-License-Identifier: GPL-2.0 menu "Accelerated Cryptographic Algorithms for CPU (riscv)" +config CRYPTO_AES_RISCV64 + tristate "Ciphers: AES, modes: ECB, CBC, CTR, XTS" + depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO + select CRYPTO_ALGAPI + select CRYPTO_LIB_AES + select CRYPTO_SKCIPHER + help + Block cipher: AES cipher algorithms + Length-preserving ciphers: AES with ECB, CBC, CTR, XTS + + Architecture: riscv64 using: + - Zvkned vector crypto extension + - Zvbb vector extension (XTS) + - Zvkb vector crypto extension (CTR) + - Zvkg vector crypto extension (XTS) + endmenu diff --git a/arch/riscv/crypto/Makefile b/arch/riscv/crypto/Makefile index a4e40e534e6a8..44922df7d182f 100644 --- a/arch/riscv/crypto/Makefile +++ b/arch/riscv/crypto/Makefile @@ -1 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o +aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o \ + aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o diff --git a/arch/riscv/crypto/aes-macros.S b/arch/riscv/crypto/aes-macros.S new file mode 100644 index 0000000000000..d1a258d04bc73 --- /dev/null +++ b/arch/riscv/crypto/aes-macros.S @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */ +// +// This file is dual-licensed, meaning that you can use it under your +// choice of either of the following two licenses: +// +// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You can obtain +// a copy in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html +// +// or +// +// Copyright (c) 2023, Christoph Müllner +// Copyright (c) 2023, Phoebe Chen +// Copyright (c) 2023, Jerry Shih +// Copyright 2024 Google LLC +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file contains macros that are shared by the other aes-*.S files. The +// generated code of these macros depends on the following RISC-V extensions: +// - RV64I +// - RISC-V Vector ('V') with VLEN >= 128 +// - RISC-V Vector AES block cipher extension ('Zvkned') + +// Loads the AES round keys from \keyp into vector registers and jumps to code +// specific to the length of the key. Specifically: +// - If AES-128, loads round keys into v1-v11 and jumps to \label128. +// - If AES-192, loads round keys into v1-v13 and jumps to \label192. +// - If AES-256, loads round keys into v1-v15 and continues onwards. +// +// Also sets vl=4 and vtype=e32,m1,ta,ma. Clobbers t0 and t1. +.macro aes_begin keyp, label128, label192 + lwu t0, 480(\keyp) // t0 = key length in bytes + li t1, 24 // t1 = key length for AES-192 + vsetivli zero, 4, e32, m1, ta, ma + vle32.v v1, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v2, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v3, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v4, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v5, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v6, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v7, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v8, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v9, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v10, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v11, (\keyp) + blt t0, t1, \label128 // If AES-128, goto label128. + addi \keyp, \keyp, 16 + vle32.v v12, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v13, (\keyp) + beq t0, t1, \label192 // If AES-192, goto label192. + // Else, it's AES-256. + addi \keyp, \keyp, 16 + vle32.v v14, (\keyp) + addi \keyp, \keyp, 16 + vle32.v v15, (\keyp) +.endm + +// Encrypts \data using zvkned instructions, using the round keys loaded into +// v1-v11 (for AES-128), v1-v13 (for AES-192), or v1-v15 (for AES-256). \keylen +// is the AES key length in bits. vl and vtype must already be set +// appropriately. Note that if vl > 4, multiple blocks are encrypted. +.macro aes_encrypt data, keylen + vaesz.vs \data, v1 + vaesem.vs \data, v2 + vaesem.vs \data, v3 + vaesem.vs \data, v4 + vaesem.vs \data, v5 + vaesem.vs \data, v6 + vaesem.vs \data, v7 + vaesem.vs \data, v8 + vaesem.vs \data, v9 + vaesem.vs \data, v10 +.if \keylen == 128 + vaesef.vs \data, v11 +.elseif \keylen == 192 + vaesem.vs \data, v11 + vaesem.vs \data, v12 + vaesef.vs \data, v13 +.else + vaesem.vs \data, v11 + vaesem.vs \data, v12 + vaesem.vs \data, v13 + vaesem.vs \data, v14 + vaesef.vs \data, v15 +.endif +.endm + +// Same as aes_encrypt, but decrypts instead of encrypts. +.macro aes_decrypt data, keylen +.if \keylen == 128 + vaesz.vs \data, v11 +.elseif \keylen == 192 + vaesz.vs \data, v13 + vaesdm.vs \data, v12 + vaesdm.vs \data, v11 +.else + vaesz.vs \data, v15 + vaesdm.vs \data, v14 + vaesdm.vs \data, v13 + vaesdm.vs \data, v12 + vaesdm.vs \data, v11 +.endif + vaesdm.vs \data, v10 + vaesdm.vs \data, v9 + vaesdm.vs \data, v8 + vaesdm.vs \data, v7 + vaesdm.vs \data, v6 + vaesdm.vs \data, v5 + vaesdm.vs \data, v4 + vaesdm.vs \data, v3 + vaesdm.vs \data, v2 + vaesdf.vs \data, v1 +.endm + +// Expands to aes_encrypt or aes_decrypt according to \enc, which is 1 or 0. +.macro aes_crypt data, enc, keylen +.if \enc + aes_encrypt \data, \keylen +.else + aes_decrypt \data, \keylen +.endif +.endm diff --git a/arch/riscv/crypto/aes-riscv64-glue.c b/arch/riscv/crypto/aes-riscv64-glue.c new file mode 100644 index 0000000000000..37bc6ef0be40e --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-glue.c @@ -0,0 +1,550 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * AES using the RISC-V vector crypto extensions. Includes the bare block + * cipher and the ECB, CBC, CTR, and XTS modes. + * + * Copyright (C) 2023 VRULL GmbH + * Author: Heiko Stuebner + * + * Copyright (C) 2023 SiFive, Inc. + * Author: Jerry Shih + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +asmlinkage void aes_encrypt_zvkned(const struct crypto_aes_ctx *key, + const u8 in[AES_BLOCK_SIZE], + u8 out[AES_BLOCK_SIZE]); +asmlinkage void aes_decrypt_zvkned(const struct crypto_aes_ctx *key, + const u8 in[AES_BLOCK_SIZE], + u8 out[AES_BLOCK_SIZE]); + +asmlinkage void aes_ecb_encrypt_zvkned(const struct crypto_aes_ctx *key, + const u8 *in, u8 *out, size_t len); +asmlinkage void aes_ecb_decrypt_zvkned(const struct crypto_aes_ctx *key, + const u8 *in, u8 *out, size_t len); + +asmlinkage void aes_cbc_encrypt_zvkned(const struct crypto_aes_ctx *key, + const u8 *in, u8 *out, size_t len, + u8 iv[AES_BLOCK_SIZE]); +asmlinkage void aes_cbc_decrypt_zvkned(const struct crypto_aes_ctx *key, + const u8 *in, u8 *out, size_t len, + u8 iv[AES_BLOCK_SIZE]); + +asmlinkage void aes_ctr32_crypt_zvkned_zvkb(const struct crypto_aes_ctx *key, + const u8 *in, u8 *out, size_t len, + u8 iv[AES_BLOCK_SIZE]); + +asmlinkage void aes_xts_encrypt_zvkned_zvbb_zvkg( + const struct crypto_aes_ctx *key, + const u8 *in, u8 *out, size_t len, + u8 tweak[AES_BLOCK_SIZE]); + +asmlinkage void aes_xts_decrypt_zvkned_zvbb_zvkg( + const struct crypto_aes_ctx *key, + const u8 *in, u8 *out, size_t len, + u8 tweak[AES_BLOCK_SIZE]); + +static int riscv64_aes_setkey(struct crypto_aes_ctx *ctx, + const u8 *key, unsigned int keylen) +{ + /* + * For now we just use the generic key expansion, for these reasons: + * + * - zvkned's key expansion instructions don't support AES-192. + * So, non-zvkned fallback code would be needed anyway. + * + * - Users of AES in Linux usually don't change keys frequently. + * So, key expansion isn't performance-critical. + * + * - For single-block AES exposed as a "cipher" algorithm, it's + * necessary to use struct crypto_aes_ctx and initialize its 'key_dec' + * field with the round keys for the Equivalent Inverse Cipher. This + * is because with "cipher", decryption can be requested from a + * context where the vector unit isn't usable, necessitating a + * fallback to aes_decrypt(). But, zvkned can only generate and use + * the normal round keys. Of course, it's preferable to not have + * special code just for "cipher", as e.g. XTS also uses a + * single-block AES encryption. It's simplest to just use + * struct crypto_aes_ctx and aes_expandkey() everywhere. + */ + return aes_expandkey(ctx, key, keylen); +} + +static int riscv64_aes_setkey_cipher(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + return riscv64_aes_setkey(ctx, key, keylen); +} + +static int riscv64_aes_setkey_skcipher(struct crypto_skcipher *tfm, + const u8 *key, unsigned int keylen) +{ + struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); + + return riscv64_aes_setkey(ctx, key, keylen); +} + +/* Bare AES, without a mode of operation */ + +static void riscv64_aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +{ + const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + if (crypto_simd_usable()) { + kernel_vector_begin(); + aes_encrypt_zvkned(ctx, src, dst); + kernel_vector_end(); + } else { + aes_encrypt(ctx, dst, src); + } +} + +static void riscv64_aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +{ + const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + if (crypto_simd_usable()) { + kernel_vector_begin(); + aes_decrypt_zvkned(ctx, src, dst); + kernel_vector_end(); + } else { + aes_decrypt(ctx, dst, src); + } +} + +/* AES-ECB */ + +static inline int riscv64_aes_ecb_crypt(struct skcipher_request *req, bool enc) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_walk walk; + unsigned int nbytes; + int err; + + err = skcipher_walk_virt(&walk, req, false); + while ((nbytes = walk.nbytes) != 0) { + kernel_vector_begin(); + if (enc) + aes_ecb_encrypt_zvkned(ctx, walk.src.virt.addr, + walk.dst.virt.addr, + nbytes & ~(AES_BLOCK_SIZE - 1)); + else + aes_ecb_decrypt_zvkned(ctx, walk.src.virt.addr, + walk.dst.virt.addr, + nbytes & ~(AES_BLOCK_SIZE - 1)); + kernel_vector_end(); + err = skcipher_walk_done(&walk, nbytes & (AES_BLOCK_SIZE - 1)); + } + + return err; +} + +static int riscv64_aes_ecb_encrypt(struct skcipher_request *req) +{ + return riscv64_aes_ecb_crypt(req, true); +} + +static int riscv64_aes_ecb_decrypt(struct skcipher_request *req) +{ + return riscv64_aes_ecb_crypt(req, false); +} + +/* AES-CBC */ + +static inline int riscv64_aes_cbc_crypt(struct skcipher_request *req, bool enc) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_walk walk; + unsigned int nbytes; + int err; + + err = skcipher_walk_virt(&walk, req, false); + while ((nbytes = walk.nbytes) != 0) { + kernel_vector_begin(); + if (enc) + aes_cbc_encrypt_zvkned(ctx, walk.src.virt.addr, + walk.dst.virt.addr, + nbytes & ~(AES_BLOCK_SIZE - 1), + walk.iv); + else + aes_cbc_decrypt_zvkned(ctx, walk.src.virt.addr, + walk.dst.virt.addr, + nbytes & ~(AES_BLOCK_SIZE - 1), + walk.iv); + kernel_vector_end(); + err = skcipher_walk_done(&walk, nbytes & (AES_BLOCK_SIZE - 1)); + } + + return err; +} + +static int riscv64_aes_cbc_encrypt(struct skcipher_request *req) +{ + return riscv64_aes_cbc_crypt(req, true); +} + +static int riscv64_aes_cbc_decrypt(struct skcipher_request *req) +{ + return riscv64_aes_cbc_crypt(req, false); +} + +/* AES-CTR */ + +static int riscv64_aes_ctr_crypt(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); + unsigned int nbytes, p1_nbytes; + struct skcipher_walk walk; + u32 ctr32, nblocks; + int err; + + /* Get the low 32-bit word of the 128-bit big endian counter. */ + ctr32 = get_unaligned_be32(req->iv + 12); + + err = skcipher_walk_virt(&walk, req, false); + while ((nbytes = walk.nbytes) != 0) { + if (nbytes < walk.total) { + /* Not the end yet, so keep the length block-aligned. */ + nbytes = round_down(nbytes, AES_BLOCK_SIZE); + nblocks = nbytes / AES_BLOCK_SIZE; + } else { + /* It's the end, so include any final partial block. */ + nblocks = DIV_ROUND_UP(nbytes, AES_BLOCK_SIZE); + } + ctr32 += nblocks; + + kernel_vector_begin(); + if (ctr32 >= nblocks) { + /* The low 32-bit word of the counter won't overflow. */ + aes_ctr32_crypt_zvkned_zvkb(ctx, walk.src.virt.addr, + walk.dst.virt.addr, nbytes, + req->iv); + } else { + /* + * The low 32-bit word of the counter will overflow. + * The assembly doesn't handle this case, so split the + * operation into two at the point where the overflow + * will occur. After the first part, add the carry bit. + */ + p1_nbytes = min_t(unsigned int, nbytes, + (nblocks - ctr32) * AES_BLOCK_SIZE); + aes_ctr32_crypt_zvkned_zvkb(ctx, walk.src.virt.addr, + walk.dst.virt.addr, + p1_nbytes, req->iv); + crypto_inc(req->iv, 12); + + if (ctr32) { + aes_ctr32_crypt_zvkned_zvkb( + ctx, + walk.src.virt.addr + p1_nbytes, + walk.dst.virt.addr + p1_nbytes, + nbytes - p1_nbytes, req->iv); + } + } + kernel_vector_end(); + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +/* AES-XTS */ + +struct riscv64_aes_xts_ctx { + struct crypto_aes_ctx ctx1; + struct crypto_aes_ctx ctx2; +}; + +static int riscv64_aes_xts_setkey(struct crypto_skcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct riscv64_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm); + + return xts_verify_key(tfm, key, keylen) ?: + riscv64_aes_setkey(&ctx->ctx1, key, keylen / 2) ?: + riscv64_aes_setkey(&ctx->ctx2, key + keylen / 2, keylen / 2); +} + +static int riscv64_aes_xts_crypt(struct skcipher_request *req, bool enc) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + const struct riscv64_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm); + int tail = req->cryptlen % AES_BLOCK_SIZE; + struct scatterlist sg_src[2], sg_dst[2]; + struct skcipher_request subreq; + struct scatterlist *src, *dst; + struct skcipher_walk walk; + int err; + + if (req->cryptlen < AES_BLOCK_SIZE) + return -EINVAL; + + /* Encrypt the IV with the tweak key to get the first tweak. */ + kernel_vector_begin(); + aes_encrypt_zvkned(&ctx->ctx2, req->iv, req->iv); + kernel_vector_end(); + + err = skcipher_walk_virt(&walk, req, false); + + /* + * If the message length isn't divisible by the AES block size and the + * full message isn't available in one step of the scatterlist walk, + * then separate off the last full block and the partial block. This + * ensures that they are processed in the same call to the assembly + * function, which is required for ciphertext stealing. + */ + if (unlikely(tail > 0 && walk.nbytes < walk.total)) { + skcipher_walk_abort(&walk); + + skcipher_request_set_tfm(&subreq, tfm); + skcipher_request_set_callback(&subreq, + skcipher_request_flags(req), + NULL, NULL); + skcipher_request_set_crypt(&subreq, req->src, req->dst, + req->cryptlen - tail - AES_BLOCK_SIZE, + req->iv); + req = &subreq; + err = skcipher_walk_virt(&walk, req, false); + } else { + tail = 0; + } + + while (walk.nbytes) { + unsigned int nbytes = walk.nbytes; + + if (nbytes < walk.total) + nbytes = round_down(nbytes, AES_BLOCK_SIZE); + + kernel_vector_begin(); + if (enc) + aes_xts_encrypt_zvkned_zvbb_zvkg( + &ctx->ctx1, walk.src.virt.addr, + walk.dst.virt.addr, nbytes, req->iv); + else + aes_xts_decrypt_zvkned_zvbb_zvkg( + &ctx->ctx1, walk.src.virt.addr, + walk.dst.virt.addr, nbytes, req->iv); + kernel_vector_end(); + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + if (err || likely(!tail)) + return err; + + /* Do ciphertext stealing with the last full block and partial block. */ + + dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); + if (req->dst != req->src) + dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); + + skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, + req->iv); + + err = skcipher_walk_virt(&walk, req, false); + if (err) + return err; + + kernel_vector_begin(); + if (enc) + aes_xts_encrypt_zvkned_zvbb_zvkg( + &ctx->ctx1, walk.src.virt.addr, + walk.dst.virt.addr, walk.nbytes, req->iv); + else + aes_xts_decrypt_zvkned_zvbb_zvkg( + &ctx->ctx1, walk.src.virt.addr, + walk.dst.virt.addr, walk.nbytes, req->iv); + kernel_vector_end(); + + return skcipher_walk_done(&walk, 0); +} + +static int riscv64_aes_xts_encrypt(struct skcipher_request *req) +{ + return riscv64_aes_xts_crypt(req, true); +} + +static int riscv64_aes_xts_decrypt(struct skcipher_request *req) +{ + return riscv64_aes_xts_crypt(req, false); +} + +/* Algorithm definitions */ + +static struct crypto_alg riscv64_zvkned_aes_cipher_alg = { + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct crypto_aes_ctx), + .cra_priority = 300, + .cra_name = "aes", + .cra_driver_name = "aes-riscv64-zvkned", + .cra_cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_setkey = riscv64_aes_setkey_cipher, + .cia_encrypt = riscv64_aes_encrypt, + .cia_decrypt = riscv64_aes_decrypt, + }, + .cra_module = THIS_MODULE, +}; + +static struct skcipher_alg riscv64_zvkned_aes_skcipher_algs[] = { + { + .setkey = riscv64_aes_setkey_skcipher, + .encrypt = riscv64_aes_ecb_encrypt, + .decrypt = riscv64_aes_ecb_decrypt, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .walksize = 8 * AES_BLOCK_SIZE, /* matches LMUL=8 */ + .base = { + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct crypto_aes_ctx), + .cra_priority = 300, + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-riscv64-zvkned", + .cra_module = THIS_MODULE, + }, + }, { + .setkey = riscv64_aes_setkey_skcipher, + .encrypt = riscv64_aes_cbc_encrypt, + .decrypt = riscv64_aes_cbc_decrypt, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .base = { + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct crypto_aes_ctx), + .cra_priority = 300, + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-riscv64-zvkned", + .cra_module = THIS_MODULE, + }, + } +}; + +static struct skcipher_alg riscv64_zvkned_zvkb_aes_skcipher_alg = { + .setkey = riscv64_aes_setkey_skcipher, + .encrypt = riscv64_aes_ctr_crypt, + .decrypt = riscv64_aes_ctr_crypt, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .chunksize = AES_BLOCK_SIZE, + .walksize = 4 * AES_BLOCK_SIZE, /* matches LMUL=4 */ + .base = { + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct crypto_aes_ctx), + .cra_priority = 300, + .cra_name = "ctr(aes)", + .cra_driver_name = "ctr-aes-riscv64-zvkned-zvkb", + .cra_module = THIS_MODULE, + }, +}; + +static struct skcipher_alg riscv64_zvkned_zvbb_zvkg_aes_skcipher_alg = { + .setkey = riscv64_aes_xts_setkey, + .encrypt = riscv64_aes_xts_encrypt, + .decrypt = riscv64_aes_xts_decrypt, + .min_keysize = 2 * AES_MIN_KEY_SIZE, + .max_keysize = 2 * AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .chunksize = AES_BLOCK_SIZE, + .walksize = 4 * AES_BLOCK_SIZE, /* matches LMUL=4 */ + .base = { + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct riscv64_aes_xts_ctx), + .cra_priority = 300, + .cra_name = "xts(aes)", + .cra_driver_name = "xts-aes-riscv64-zvkned-zvbb-zvkg", + .cra_module = THIS_MODULE, + }, +}; + +static inline bool riscv64_aes_xts_supported(void) +{ + return riscv_isa_extension_available(NULL, ZVBB) && + riscv_isa_extension_available(NULL, ZVKG) && + riscv_vector_vlen() < 2048 /* Implementation limitation */; +} + +static int __init riscv64_aes_mod_init(void) +{ + int err = -ENODEV; + + if (riscv_isa_extension_available(NULL, ZVKNED) && + riscv_vector_vlen() >= 128) { + err = crypto_register_alg(&riscv64_zvkned_aes_cipher_alg); + if (err) + return err; + + err = crypto_register_skciphers( + riscv64_zvkned_aes_skcipher_algs, + ARRAY_SIZE(riscv64_zvkned_aes_skcipher_algs)); + if (err) + goto unregister_zvkned_cipher_alg; + + if (riscv_isa_extension_available(NULL, ZVKB)) { + err = crypto_register_skcipher( + &riscv64_zvkned_zvkb_aes_skcipher_alg); + if (err) + goto unregister_zvkned_skcipher_algs; + } + + if (riscv64_aes_xts_supported()) { + err = crypto_register_skcipher( + &riscv64_zvkned_zvbb_zvkg_aes_skcipher_alg); + if (err) + goto unregister_zvkned_zvkb_skcipher_alg; + } + } + + return err; + +unregister_zvkned_zvkb_skcipher_alg: + if (riscv_isa_extension_available(NULL, ZVKB)) + crypto_unregister_skcipher(&riscv64_zvkned_zvkb_aes_skcipher_alg); +unregister_zvkned_skcipher_algs: + crypto_unregister_skciphers(riscv64_zvkned_aes_skcipher_algs, + ARRAY_SIZE(riscv64_zvkned_aes_skcipher_algs)); +unregister_zvkned_cipher_alg: + crypto_unregister_alg(&riscv64_zvkned_aes_cipher_alg); + return err; +} + +static void __exit riscv64_aes_mod_exit(void) +{ + if (riscv64_aes_xts_supported()) + crypto_unregister_skcipher(&riscv64_zvkned_zvbb_zvkg_aes_skcipher_alg); + if (riscv_isa_extension_available(NULL, ZVKB)) + crypto_unregister_skcipher(&riscv64_zvkned_zvkb_aes_skcipher_alg); + crypto_unregister_skciphers(riscv64_zvkned_aes_skcipher_algs, + ARRAY_SIZE(riscv64_zvkned_aes_skcipher_algs)); + crypto_unregister_alg(&riscv64_zvkned_aes_cipher_alg); +} + +module_init(riscv64_aes_mod_init); +module_exit(riscv64_aes_mod_exit); + +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS (RISC-V accelerated)"); +MODULE_AUTHOR("Jerry Shih "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CRYPTO("aes"); +MODULE_ALIAS_CRYPTO("ecb(aes)"); +MODULE_ALIAS_CRYPTO("cbc(aes)"); +MODULE_ALIAS_CRYPTO("ctr(aes)"); +MODULE_ALIAS_CRYPTO("xts(aes)"); diff --git a/arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S b/arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S new file mode 100644 index 0000000000000..146fc9cfb268d --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */ +// +// This file is dual-licensed, meaning that you can use it under your +// choice of either of the following two licenses: +// +// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You can obtain +// a copy in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html +// +// or +// +// Copyright (c) 2023, Jerry Shih +// Copyright 2024 Google LLC +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The generated code of this file depends on the following RISC-V extensions: +// - RV64I +// - RISC-V Vector ('V') with VLEN >= 128 && VLEN < 2048 +// - RISC-V Vector AES block cipher extension ('Zvkned') +// - RISC-V Vector Bit-manipulation extension ('Zvbb') +// - RISC-V Vector GCM/GMAC extension ('Zvkg') + +#include + +.text +.option arch, +zvkned, +zvbb, +zvkg + +#include "aes-macros.S" + +#define KEYP a0 +#define INP a1 +#define OUTP a2 +#define LEN a3 +#define TWEAKP a4 + +#define LEN32 a5 +#define TAIL_LEN a6 +#define VL a7 +#define VLMAX t4 + +// v1-v15 contain the AES round keys, but they are used for temporaries before +// the AES round keys have been loaded. +#define TWEAKS v16 // LMUL=4 (most of the time) +#define TWEAKS_BREV v20 // LMUL=4 (most of the time) +#define MULTS_BREV v24 // LMUL=4 (most of the time) +#define TMP0 v28 +#define TMP1 v29 +#define TMP2 v30 +#define TMP3 v31 + +// xts_init initializes the following values: +// +// TWEAKS: N 128-bit tweaks T*(x^i) for i in 0..(N - 1) +// TWEAKS_BREV: same as TWEAKS, but bit-reversed +// MULTS_BREV: N 128-bit values x^N, bit-reversed. Only if N > 1. +// +// N is the maximum number of blocks that will be processed per loop iteration, +// computed using vsetvli. +// +// The field convention used by XTS is the same as that of GHASH, but with the +// bits reversed within each byte. The zvkg extension provides the vgmul +// instruction which does multiplication in this field. Therefore, for tweak +// computation we use vgmul to do multiplications in parallel, instead of +// serially multiplying by x using shifting+xoring. Note that for this to work, +// the inputs and outputs to vgmul must be bit-reversed (we do it with vbrev8). +.macro xts_init + + // Load the first tweak T. + vsetivli zero, 4, e32, m1, ta, ma + vle32.v TWEAKS, (TWEAKP) + + // If there's only one block (or no blocks at all), then skip the tweak + // sequence computation because (at most) T itself is needed. + li t0, 16 + ble LEN, t0, .Linit_single_block\@ + + // Save a copy of T bit-reversed in v12. + vbrev8.v v12, TWEAKS + + // + // Generate x^i for i in 0..(N - 1), i.e. 128-bit values 1 << i assuming + // that N <= 128. Though, this code actually requires N < 64 (or + // equivalently VLEN < 2048) due to the use of 64-bit intermediate + // values here and in the x^N computation later. + // + vsetvli VL, LEN32, e32, m4, ta, ma + srli t0, VL, 2 // t0 = N (num blocks) + // Generate two sequences, each with N 32-bit values: + // v0=[1, 1, 1, ...] and v1=[0, 1, 2, ...]. + vsetvli zero, t0, e32, m1, ta, ma + vmv.v.i v0, 1 + vid.v v1 + // Use vzext to zero-extend the sequences to 64 bits. Reinterpret them + // as two sequences, each with 2*N 32-bit values: + // v2=[1, 0, 1, 0, 1, 0, ...] and v4=[0, 0, 1, 0, 2, 0, ...]. + vsetvli zero, t0, e64, m2, ta, ma + vzext.vf2 v2, v0 + vzext.vf2 v4, v1 + slli t1, t0, 1 // t1 = 2*N + vsetvli zero, t1, e32, m2, ta, ma + // Use vwsll to compute [1<<0, 0<<0, 1<<1, 0<<0, 1<<2, 0<<0, ...], + // widening to 64 bits per element. When reinterpreted as N 128-bit + // values, this is the needed sequence of 128-bit values 1 << i (x^i). + vwsll.vv v8, v2, v4 + + // Copy the bit-reversed T to all N elements of TWEAKS_BREV, then + // multiply by x^i. This gives the sequence T*(x^i), bit-reversed. + vsetvli zero, LEN32, e32, m4, ta, ma + vmv.v.i TWEAKS_BREV, 0 + vaesz.vs TWEAKS_BREV, v12 + vbrev8.v v8, v8 + vgmul.vv TWEAKS_BREV, v8 + + // Save a copy of the sequence T*(x^i) with the bit reversal undone. + vbrev8.v TWEAKS, TWEAKS_BREV + + // Generate N copies of x^N, i.e. 128-bit values 1 << N, bit-reversed. + li t1, 1 + sll t1, t1, t0 // t1 = 1 << N + vsetivli zero, 2, e64, m1, ta, ma + vmv.v.i v0, 0 + vsetivli zero, 1, e64, m1, tu, ma + vmv.v.x v0, t1 + vbrev8.v v0, v0 + vsetvli zero, LEN32, e32, m4, ta, ma + vmv.v.i MULTS_BREV, 0 + vaesz.vs MULTS_BREV, v0 + + j .Linit_done\@ + +.Linit_single_block\@: + vbrev8.v TWEAKS_BREV, TWEAKS +.Linit_done\@: +.endm + +// Set the first 128 bits of MULTS_BREV to 0x40, i.e. 'x' bit-reversed. This is +// the multiplier required to advance the tweak by one. +.macro load_x + li t0, 0x40 + vsetivli zero, 4, e32, m1, ta, ma + vmv.v.i MULTS_BREV, 0 + vsetivli zero, 1, e8, m1, tu, ma + vmv.v.x MULTS_BREV, t0 +.endm + +.macro __aes_xts_crypt enc, keylen + // With 16 < len <= 31, there's no main loop, just ciphertext stealing. + beqz LEN32, .Lcts_without_main_loop\@ + + vsetvli VLMAX, zero, e32, m4, ta, ma +1: + vsetvli VL, LEN32, e32, m4, ta, ma +2: + // Encrypt or decrypt VL/4 blocks. + vle32.v TMP0, (INP) + vxor.vv TMP0, TMP0, TWEAKS + aes_crypt TMP0, \enc, \keylen + vxor.vv TMP0, TMP0, TWEAKS + vse32.v TMP0, (OUTP) + + // Update the pointers and the remaining length. + slli t0, VL, 2 + add INP, INP, t0 + add OUTP, OUTP, t0 + sub LEN32, LEN32, VL + + // Check whether more blocks remain. + beqz LEN32, .Lmain_loop_done\@ + + // Compute the next sequence of tweaks by multiplying the previous + // sequence by x^N. Store the result in both bit-reversed order and + // regular order (i.e. with the bit reversal undone). + vgmul.vv TWEAKS_BREV, MULTS_BREV + vbrev8.v TWEAKS, TWEAKS_BREV + + // Since we compute the tweak multipliers x^N in advance, we require + // that each iteration process the same length except possibly the last. + // This conflicts slightly with the behavior allowed by RISC-V Vector + // Extension, where CPUs can select a lower length for both of the last + // two iterations. E.g., vl might take the sequence of values + // [16, 16, 16, 12, 12], whereas we need [16, 16, 16, 16, 8] so that we + // can use x^4 again instead of computing x^3. Therefore, we explicitly + // keep the vl at VLMAX if there is at least VLMAX remaining. + bge LEN32, VLMAX, 2b + j 1b + +.Lmain_loop_done\@: + load_x + + // Compute the next tweak. + addi t0, VL, -4 + vsetivli zero, 4, e32, m4, ta, ma + vslidedown.vx TWEAKS_BREV, TWEAKS_BREV, t0 // Extract last tweak + vsetivli zero, 4, e32, m1, ta, ma + vgmul.vv TWEAKS_BREV, MULTS_BREV // Advance to next tweak + + bnez TAIL_LEN, .Lcts\@ + + // Update *TWEAKP to contain the next tweak. + vbrev8.v TWEAKS, TWEAKS_BREV + vse32.v TWEAKS, (TWEAKP) + ret + +.Lcts_without_main_loop\@: + load_x +.Lcts\@: + // TWEAKS_BREV now contains the next tweak. Compute the one after that. + vsetivli zero, 4, e32, m1, ta, ma + vmv.v.v TMP0, TWEAKS_BREV + vgmul.vv TMP0, MULTS_BREV + // Undo the bit reversal of the next two tweaks and store them in TMP1 + // and TMP2, such that TMP1 is the first needed and TMP2 the second. +.if \enc + vbrev8.v TMP1, TWEAKS_BREV + vbrev8.v TMP2, TMP0 +.else + vbrev8.v TMP1, TMP0 + vbrev8.v TMP2, TWEAKS_BREV +.endif + + // Encrypt/decrypt the last full block. + vle32.v TMP0, (INP) + vxor.vv TMP0, TMP0, TMP1 + aes_crypt TMP0, \enc, \keylen + vxor.vv TMP0, TMP0, TMP1 + + // Swap the first TAIL_LEN bytes of the above result with the tail. + // Note that to support in-place encryption/decryption, the load from + // the input tail must happen before the store to the output tail. + addi t0, INP, 16 + addi t1, OUTP, 16 + vmv.v.v TMP3, TMP0 + vsetvli zero, TAIL_LEN, e8, m1, tu, ma + vle8.v TMP0, (t0) + vse8.v TMP3, (t1) + + // Encrypt/decrypt again and store the last full block. + vsetivli zero, 4, e32, m1, ta, ma + vxor.vv TMP0, TMP0, TMP2 + aes_crypt TMP0, \enc, \keylen + vxor.vv TMP0, TMP0, TMP2 + vse32.v TMP0, (OUTP) + + ret +.endm + +.macro aes_xts_crypt enc + + // Check whether the length is a multiple of the AES block size. + andi TAIL_LEN, LEN, 15 + beqz TAIL_LEN, 1f + + // The length isn't a multiple of the AES block size, so ciphertext + // stealing will be required. Ciphertext stealing involves special + // handling of the partial block and the last full block, so subtract + // the length of both from the length to be processed in the main loop. + sub LEN, LEN, TAIL_LEN + addi LEN, LEN, -16 +1: + srli LEN32, LEN, 2 + // LEN and LEN32 now contain the total length of the blocks that will be + // processed in the main loop, in bytes and 32-bit words respectively. + + xts_init + aes_begin KEYP, 128f, 192f + __aes_xts_crypt \enc, 256 +128: + __aes_xts_crypt \enc, 128 +192: + __aes_xts_crypt \enc, 192 +.endm + +// void aes_xts_encrypt_zvkned_zvbb_zvkg(const struct crypto_aes_ctx *key, +// const u8 *in, u8 *out, size_t len, +// u8 tweak[16]); +// +// |key| is the data key. |tweak| contains the next tweak; the encryption of +// the original IV with the tweak key was already done. This function supports +// incremental computation, but |len| must always be >= 16 (AES_BLOCK_SIZE), and +// |len| must be a multiple of 16 except on the last call. If |len| is a +// multiple of 16, then this function updates |tweak| to contain the next tweak. +SYM_FUNC_START(aes_xts_encrypt_zvkned_zvbb_zvkg) + aes_xts_crypt 1 +SYM_FUNC_END(aes_xts_encrypt_zvkned_zvbb_zvkg) + +// Same prototype and calling convention as the encryption function +SYM_FUNC_START(aes_xts_decrypt_zvkned_zvbb_zvkg) + aes_xts_crypt 0 +SYM_FUNC_END(aes_xts_decrypt_zvkned_zvbb_zvkg) diff --git a/arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S b/arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S new file mode 100644 index 0000000000000..9962d45005870 --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */ +// +// This file is dual-licensed, meaning that you can use it under your +// choice of either of the following two licenses: +// +// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You can obtain +// a copy in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html +// +// or +// +// Copyright (c) 2023, Jerry Shih +// Copyright 2024 Google LLC +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The generated code of this file depends on the following RISC-V extensions: +// - RV64I +// - RISC-V Vector ('V') with VLEN >= 128 +// - RISC-V Vector AES block cipher extension ('Zvkned') +// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb') + +#include + +.text +.option arch, +zvkned, +zvkb + +#include "aes-macros.S" + +#define KEYP a0 +#define INP a1 +#define OUTP a2 +#define LEN a3 +#define IVP a4 + +#define LEN32 a5 +#define VL_E32 a6 +#define VL_BLOCKS a7 + +.macro aes_ctr32_crypt keylen + // LEN32 = number of blocks, rounded up, in 32-bit words. + addi t0, LEN, 15 + srli t0, t0, 4 + slli LEN32, t0, 2 + + // Create a mask that selects the last 32-bit word of each 128-bit + // block. This is the word that contains the (big-endian) counter. + li t0, 0x88 + vsetvli t1, zero, e8, m1, ta, ma + vmv.v.x v0, t0 + + // Load the IV into v31. The last 32-bit word contains the counter. + vsetivli zero, 4, e32, m1, ta, ma + vle32.v v31, (IVP) + + // Convert the big-endian counter into little-endian. + vsetivli zero, 4, e32, m1, ta, mu + vrev8.v v31, v31, v0.t + + // Splat the IV to v16 (with LMUL=4). The number of copies is the + // maximum number of blocks that will be processed per iteration. + vsetvli zero, LEN32, e32, m4, ta, ma + vmv.v.i v16, 0 + vaesz.vs v16, v31 + + // v20 = [x, x, x, 0, x, x, x, 1, ...] + viota.m v20, v0, v0.t + // v16 = [IV0, IV1, IV2, counter+0, IV0, IV1, IV2, counter+1, ...] + vsetvli VL_E32, LEN32, e32, m4, ta, mu + vadd.vv v16, v16, v20, v0.t + + j 2f +1: + // Set the number of blocks to process in this iteration. vl=VL_E32 is + // the length in 32-bit words, i.e. 4 times the number of blocks. + vsetvli VL_E32, LEN32, e32, m4, ta, mu + + // Increment the counters by the number of blocks processed in the + // previous iteration. + vadd.vx v16, v16, VL_BLOCKS, v0.t +2: + // Prepare the AES inputs into v24. + vmv.v.v v24, v16 + vrev8.v v24, v24, v0.t // Convert counters back to big-endian. + + // Encrypt the AES inputs to create the next portion of the keystream. + aes_encrypt v24, \keylen + + // XOR the data with the keystream. + vsetvli t0, LEN, e8, m4, ta, ma + vle8.v v20, (INP) + vxor.vv v20, v20, v24 + vse8.v v20, (OUTP) + + // Advance the pointers and update the remaining length. + add INP, INP, t0 + add OUTP, OUTP, t0 + sub LEN, LEN, t0 + sub LEN32, LEN32, VL_E32 + srli VL_BLOCKS, VL_E32, 2 + + // Repeat if more data remains. + bnez LEN, 1b + + // Update *IVP to contain the next counter. + vsetivli zero, 4, e32, m1, ta, mu + vadd.vx v16, v16, VL_BLOCKS, v0.t + vrev8.v v16, v16, v0.t // Convert counters back to big-endian. + vse32.v v16, (IVP) + + ret +.endm + +// void aes_ctr32_crypt_zvkned_zvkb(const struct crypto_aes_ctx *key, +// const u8 *in, u8 *out, size_t len, +// u8 iv[16]); +SYM_FUNC_START(aes_ctr32_crypt_zvkned_zvkb) + aes_begin KEYP, 128f, 192f + aes_ctr32_crypt 256 +128: + aes_ctr32_crypt 128 +192: + aes_ctr32_crypt 192 +SYM_FUNC_END(aes_ctr32_crypt_zvkned_zvkb) diff --git a/arch/riscv/crypto/aes-riscv64-zvkned.S b/arch/riscv/crypto/aes-riscv64-zvkned.S new file mode 100644 index 0000000000000..78d4e1186c074 --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-zvkned.S @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */ +// +// This file is dual-licensed, meaning that you can use it under your +// choice of either of the following two licenses: +// +// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You can obtain +// a copy in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html +// +// or +// +// Copyright (c) 2023, Christoph Müllner +// Copyright (c) 2023, Phoebe Chen +// Copyright (c) 2023, Jerry Shih +// Copyright 2024 Google LLC +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The generated code of this file depends on the following RISC-V extensions: +// - RV64I +// - RISC-V Vector ('V') with VLEN >= 128 +// - RISC-V Vector AES block cipher extension ('Zvkned') + +#include + +.text +.option arch, +zvkned + +#include "aes-macros.S" + +#define KEYP a0 +#define INP a1 +#define OUTP a2 +#define LEN a3 +#define IVP a4 + +.macro __aes_crypt_zvkned enc, keylen + vle32.v v16, (INP) + aes_crypt v16, \enc, \keylen + vse32.v v16, (OUTP) + ret +.endm + +.macro aes_crypt_zvkned enc + aes_begin KEYP, 128f, 192f + __aes_crypt_zvkned \enc, 256 +128: + __aes_crypt_zvkned \enc, 128 +192: + __aes_crypt_zvkned \enc, 192 +.endm + +// void aes_encrypt_zvkned(const struct crypto_aes_ctx *key, +// const u8 in[16], u8 out[16]); +SYM_FUNC_START(aes_encrypt_zvkned) + aes_crypt_zvkned 1 +SYM_FUNC_END(aes_encrypt_zvkned) + +// Same prototype and calling convention as the encryption function +SYM_FUNC_START(aes_decrypt_zvkned) + aes_crypt_zvkned 0 +SYM_FUNC_END(aes_decrypt_zvkned) + +.macro __aes_ecb_crypt enc, keylen + srli t0, LEN, 2 + // t0 is the remaining length in 32-bit words. It's a multiple of 4. +1: + vsetvli t1, t0, e32, m8, ta, ma + sub t0, t0, t1 // Subtract number of words processed + slli t1, t1, 2 // Words to bytes + vle32.v v16, (INP) + aes_crypt v16, \enc, \keylen + vse32.v v16, (OUTP) + add INP, INP, t1 + add OUTP, OUTP, t1 + bnez t0, 1b + + ret +.endm + +.macro aes_ecb_crypt enc + aes_begin KEYP, 128f, 192f + __aes_ecb_crypt \enc, 256 +128: + __aes_ecb_crypt \enc, 128 +192: + __aes_ecb_crypt \enc, 192 +.endm + +// void aes_ecb_encrypt_zvkned(const struct crypto_aes_ctx *key, +// const u8 *in, u8 *out, size_t len); +// +// |len| must be nonzero and a multiple of 16 (AES_BLOCK_SIZE). +SYM_FUNC_START(aes_ecb_encrypt_zvkned) + aes_ecb_crypt 1 +SYM_FUNC_END(aes_ecb_encrypt_zvkned) + +// Same prototype and calling convention as the encryption function +SYM_FUNC_START(aes_ecb_decrypt_zvkned) + aes_ecb_crypt 0 +SYM_FUNC_END(aes_ecb_decrypt_zvkned) + +.macro aes_cbc_encrypt keylen + vle32.v v16, (IVP) // Load IV +1: + vle32.v v17, (INP) // Load plaintext block + vxor.vv v16, v16, v17 // XOR with IV or prev ciphertext block + aes_encrypt v16, \keylen // Encrypt + vse32.v v16, (OUTP) // Store ciphertext block + addi INP, INP, 16 + addi OUTP, OUTP, 16 + addi LEN, LEN, -16 + bnez LEN, 1b + + vse32.v v16, (IVP) // Store next IV + ret +.endm + +.macro aes_cbc_decrypt keylen + vle32.v v16, (IVP) // Load IV +1: + vle32.v v17, (INP) // Load ciphertext block + vmv.v.v v18, v17 // Save ciphertext block + aes_decrypt v17, \keylen // Decrypt + vxor.vv v17, v17, v16 // XOR with IV or prev ciphertext block + vse32.v v17, (OUTP) // Store plaintext block + vmv.v.v v16, v18 // Next "IV" is prev ciphertext block + addi INP, INP, 16 + addi OUTP, OUTP, 16 + addi LEN, LEN, -16 + bnez LEN, 1b + + vse32.v v16, (IVP) // Store next IV + ret +.endm + +// void aes_cbc_encrypt_zvkned(const struct crypto_aes_ctx *key, +// const u8 *in, u8 *out, size_t len, u8 iv[16]); +// +// |len| must be nonzero and a multiple of 16 (AES_BLOCK_SIZE). +SYM_FUNC_START(aes_cbc_encrypt_zvkned) + aes_begin KEYP, 128f, 192f + aes_cbc_encrypt 256 +128: + aes_cbc_encrypt 128 +192: + aes_cbc_encrypt 192 +SYM_FUNC_END(aes_cbc_encrypt_zvkned) + +// Same prototype and calling convention as the encryption function +SYM_FUNC_START(aes_cbc_decrypt_zvkned) + aes_begin KEYP, 128f, 192f + aes_cbc_decrypt 256 +128: + aes_cbc_decrypt 128 +192: + aes_cbc_decrypt 192 +SYM_FUNC_END(aes_cbc_decrypt_zvkned) -- 2.43.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 93537C47DDB for ; Mon, 22 Jan 2024 00:23:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zA7JhQ9ECC/d19LPrfUjtU6DJN7IkFAK9uPJClZvOTg=; b=H7S50JHfL5l5Ry CZc5wpU9h02IMdTATJ/msDn42xQtrfztIGH0BEjq8SlDrwmA5x3K6iIJgmSoZbbNR9UQRiO1q3ssM BstUX8VdoGHV/ItnXhETGz8oLENpCOLW3QLzJLbhXYDYdSOGSbHUa+o1reTzt3ktc62FqiZf7r9ms FBRSBQBuIH6PFa875HCOs7Bzbe/00B64gJsKa5n8MgQDAOk4PSvDytBHAH6zfb7hpLT9EabRRfS5y kY5inNnB/OicS74x0wiNE5RqaIcHPT7uqlJFj7b1II8Le51hboPqU1fXcOkBNiQQPgJZ1zfqzr90a bM3DDpHKxMDAU6vh3BPg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1rRi5l-00AFow-0t; Mon, 22 Jan 2024 00:23:09 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1rRi5d-00AFmW-1C for linux-riscv@lists.infradead.org; Mon, 22 Jan 2024 00:23:06 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id B339D61018; Mon, 22 Jan 2024 00:23:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C2561C43390; Mon, 22 Jan 2024 00:22:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1705882980; bh=BH8DWDwlQPyIgcG7nEKEMMv58AgI1J8gP1nTyg7ugIg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cCCjnk9ZfbJTWtTAWW2Y96hsCzBFA54lyNCaJNemFRlEvtcjtg1lQP87eZa2oQZTF mjFXr+8jHPoh17UZB3DZsKZ33XW00ejN1/B8DqdWWEbzYLjUmaNSOQ2Aiht7AtLPXT UW4eji6/aV6fekm3SG172KpksMvL5JBPMKp9nplMhxqKPbgnUchMA1ZUO0hvcL4WM6 RXNw5g8f3rvEv6uo4DuNLlvlo1+7wwX8+VS//BdArdzsw/3eYtHk9Lvb/IUY9txC18 FLIYKm7AnrY4SvSae9VNXSHOahlG9pw7Q4yBKdHWQQWEvuV6xlaJXUXVUtw3ntuXUp eG9n+5G2eYsWA== From: Eric Biggers To: linux-crypto@vger.kernel.org, linux-riscv@lists.infradead.org Cc: linux-kernel@vger.kernel.org, Albert Ou , Andy Chiu , Ard Biesheuvel , =?UTF-8?q?Christoph=20M=C3=BCllner?= , Heiko Stuebner , Jerry Shih , Palmer Dabbelt , Paul Walmsley , Phoebe Chen , hongrong.hsu@sifive.com Subject: [PATCH v3 04/10] crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS} Date: Sun, 21 Jan 2024 16:19:15 -0800 Message-ID: <20240122002024.27477-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240122002024.27477-1-ebiggers@kernel.org> References: <20240122002024.27477-1-ebiggers@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240121_162301_548697_F1F6109B X-CRM114-Status: GOOD ( 31.57 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org RnJvbTogSmVycnkgU2hpaCA8amVycnkuc2hpaEBzaWZpdmUuY29tPgoKQWRkIGltcGxlbWVudGF0 aW9ucyBvZiBBRVMtRUNCLCBBRVMtQ0JDLCBBRVMtQ1RSLCBhbmQgQUVTLVhUUywgYXMgd2VsbAph cyBiYXJlIChzaW5nbGUtYmxvY2spIEFFUywgdXNpbmcgdGhlIFJJU0MtViB2ZWN0b3IgY3J5cHRv IGV4dGVuc2lvbnMuClRoZSBhc3NlbWJseSBjb2RlIGlzIGRlcml2ZWQgZnJvbSBPcGVuU1NMIGNv ZGUgKG9wZW5zc2wvb3BlbnNzbCMyMTkyMykKdGhhdCB3YXMgZHVhbC1saWNlbnNlZCBzbyB0aGF0 IGl0IGNvdWxkIGJlIHJldXNlZCBpbiB0aGUga2VybmVsLgpOZXZlcnRoZWxlc3MsIHRoZSBhc3Nl bWJseSBoYXMgYmVlbiBzaWduaWZpY2FudGx5IHJld29ya2VkIGZvcgppbnRlZ3JhdGlvbiB3aXRo IHRoZSBrZXJuZWwsIGZvciBleGFtcGxlIGJ5IHVzaW5nIHJlZ3VsYXIgLlMgZmlsZXMKaW5zdGVh ZCBvZiB0aGUgc28tY2FsbGVkIHBlcmxhc20sIHVzaW5nIHRoZSBhc3NlbWJsZXIgaW5zdGVhZCBv ZiBiYXJlCicuaW5zdCcsIGdyZWF0bHkgcmVkdWNpbmcgY29kZSBkdXBsaWNhdGlvbiwgc3VwcG9y dGluZyBBRVMtMTkyLCBhbmQKbWFraW5nIHRoZSBjb2RlIHVzZSB0aGUgc2FtZSBBRVMga2V5IHN0 cnVjdHVyZSBhcyB0aGUgQyBjb2RlLgoKQ28tZGV2ZWxvcGVkLWJ5OiBQaG9lYmUgQ2hlbiA8cGhv ZWJlLmNoZW5Ac2lmaXZlLmNvbT4KU2lnbmVkLW9mZi1ieTogUGhvZWJlIENoZW4gPHBob2ViZS5j aGVuQHNpZml2ZS5jb20+ClNpZ25lZC1vZmYtYnk6IEplcnJ5IFNoaWggPGplcnJ5LnNoaWhAc2lm aXZlLmNvbT4KQ28tZGV2ZWxvcGVkLWJ5OiBFcmljIEJpZ2dlcnMgPGViaWdnZXJzQGdvb2dsZS5j b20+ClNpZ25lZC1vZmYtYnk6IEVyaWMgQmlnZ2VycyA8ZWJpZ2dlcnNAZ29vZ2xlLmNvbT4KLS0t CiBhcmNoL3Jpc2N2L2NyeXB0by9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgfCAgMTYgKwog YXJjaC9yaXNjdi9jcnlwdG8vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgIHwgICA0ICsKIGFy Y2gvcmlzY3YvY3J5cHRvL2Flcy1tYWNyb3MuUyAgICAgICAgICAgICAgICB8IDE1NiArKysrKwog YXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtZ2x1ZS5jICAgICAgICAgIHwgNTUwICsrKysr KysrKysrKysrKysrKwogLi4uL2NyeXB0by9hZXMtcmlzY3Y2NC16dmtuZWQtenZiYi16dmtnLlMg ICAgIHwgMzEyICsrKysrKysrKysKIGFyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25l ZC16dmtiLlMgICB8IDE0NiArKysrKwogYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZr bmVkLlMgICAgICAgIHwgMTgwICsrKysrKwogNyBmaWxlcyBjaGFuZ2VkLCAxMzY0IGluc2VydGlv bnMoKykKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtbWFjcm9zLlMK IGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlzY3Y2NC1nbHVlLmMK IGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlzY3Y2NC16dmtuZWQt enZiYi16dmtnLlMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlz Y3Y2NC16dmtuZWQtenZrYi5TCiBjcmVhdGUgbW9kZSAxMDA2NDQgYXJjaC9yaXNjdi9jcnlwdG8v YWVzLXJpc2N2NjQtenZrbmVkLlMKCmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2NyeXB0by9LY29u ZmlnIGIvYXJjaC9yaXNjdi9jcnlwdG8vS2NvbmZpZwppbmRleCAxMGQ2MGVkYzAxMTBhLi5lYmU4 MDVmYTNmNWY3IDEwMDY0NAotLS0gYS9hcmNoL3Jpc2N2L2NyeXB0by9LY29uZmlnCisrKyBiL2Fy Y2gvcmlzY3YvY3J5cHRvL0tjb25maWcKQEAgLTEsNSArMSwyMSBAQAogIyBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogR1BMLTIuMAogCiBtZW51ICJBY2NlbGVyYXRlZCBDcnlwdG9ncmFwaGljIEFs Z29yaXRobXMgZm9yIENQVSAocmlzY3YpIgogCitjb25maWcgQ1JZUFRPX0FFU19SSVNDVjY0CisJ dHJpc3RhdGUgIkNpcGhlcnM6IEFFUywgbW9kZXM6IEVDQiwgQ0JDLCBDVFIsIFhUUyIKKwlkZXBl bmRzIG9uIDY0QklUICYmIFJJU0NWX0lTQV9WICYmIFRPT0xDSEFJTl9IQVNfVkVDVE9SX0NSWVBU TworCXNlbGVjdCBDUllQVE9fQUxHQVBJCisJc2VsZWN0IENSWVBUT19MSUJfQUVTCisJc2VsZWN0 IENSWVBUT19TS0NJUEhFUgorCWhlbHAKKwkgIEJsb2NrIGNpcGhlcjogQUVTIGNpcGhlciBhbGdv cml0aG1zCisJICBMZW5ndGgtcHJlc2VydmluZyBjaXBoZXJzOiBBRVMgd2l0aCBFQ0IsIENCQywg Q1RSLCBYVFMKKworCSAgQXJjaGl0ZWN0dXJlOiByaXNjdjY0IHVzaW5nOgorCSAgLSBadmtuZWQg dmVjdG9yIGNyeXB0byBleHRlbnNpb24KKwkgIC0gWnZiYiB2ZWN0b3IgZXh0ZW5zaW9uIChYVFMp CisJICAtIFp2a2IgdmVjdG9yIGNyeXB0byBleHRlbnNpb24gKENUUikKKwkgIC0gWnZrZyB2ZWN0 b3IgY3J5cHRvIGV4dGVuc2lvbiAoWFRTKQorCiBlbmRtZW51CmRpZmYgLS1naXQgYS9hcmNoL3Jp c2N2L2NyeXB0by9NYWtlZmlsZSBiL2FyY2gvcmlzY3YvY3J5cHRvL01ha2VmaWxlCmluZGV4IGE0 ZTQwZTUzNGU2YTguLjQ0OTIyZGY3ZDE4MmYgMTAwNjQ0Ci0tLSBhL2FyY2gvcmlzY3YvY3J5cHRv L01ha2VmaWxlCisrKyBiL2FyY2gvcmlzY3YvY3J5cHRvL01ha2VmaWxlCkBAIC0xICsxLDUgQEAK ICMgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQorCitvYmotJChDT05GSUdf Q1JZUFRPX0FFU19SSVNDVjY0KSArPSBhZXMtcmlzY3Y2NC5vCithZXMtcmlzY3Y2NC15IDo9IGFl cy1yaXNjdjY0LWdsdWUubyBhZXMtcmlzY3Y2NC16dmtuZWQubyBcCisJCSBhZXMtcmlzY3Y2NC16 dmtuZWQtenZiYi16dmtnLm8gYWVzLXJpc2N2NjQtenZrbmVkLXp2a2IubwpkaWZmIC0tZ2l0IGEv YXJjaC9yaXNjdi9jcnlwdG8vYWVzLW1hY3Jvcy5TIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLW1h Y3Jvcy5TCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMDAuLmQxYTI1OGQw NGJjNzMKLS0tIC9kZXYvbnVsbAorKysgYi9hcmNoL3Jpc2N2L2NyeXB0by9hZXMtbWFjcm9zLlMK QEAgLTAsMCArMSwxNTYgQEAKKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4w IE9SIEJTRC0yLUNsYXVzZSAqLworLy8KKy8vIFRoaXMgZmlsZSBpcyBkdWFsLWxpY2Vuc2VkLCBt ZWFuaW5nIHRoYXQgeW91IGNhbiB1c2UgaXQgdW5kZXIgeW91cgorLy8gY2hvaWNlIG9mIGVpdGhl ciBvZiB0aGUgZm9sbG93aW5nIHR3byBsaWNlbnNlczoKKy8vCisvLyBDb3B5cmlnaHQgMjAyMyBU aGUgT3BlblNTTCBQcm9qZWN0IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisvLworLy8g TGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIDIuMCAodGhlICJMaWNlbnNlIikuIFlv dSBjYW4gb2J0YWluCisvLyBhIGNvcHkgaW4gdGhlIGZpbGUgTElDRU5TRSBpbiB0aGUgc291cmNl IGRpc3RyaWJ1dGlvbiBvciBhdAorLy8gaHR0cHM6Ly93d3cub3BlbnNzbC5vcmcvc291cmNlL2xp Y2Vuc2UuaHRtbAorLy8KKy8vIG9yCisvLworLy8gQ29weXJpZ2h0IChjKSAyMDIzLCBDaHJpc3Rv cGggTcO8bGxuZXIgPGNocmlzdG9waC5tdWVsbG5lckB2cnVsbC5ldT4KKy8vIENvcHlyaWdodCAo YykgMjAyMywgUGhvZWJlIENoZW4gPHBob2ViZS5jaGVuQHNpZml2ZS5jb20+CisvLyBDb3B5cmln aHQgKGMpIDIwMjMsIEplcnJ5IFNoaWggPGplcnJ5LnNoaWhAc2lmaXZlLmNvbT4KKy8vIENvcHly aWdodCAyMDI0IEdvb2dsZSBMTEMKKy8vIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVk aXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3 aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUg Zm9sbG93aW5nIGNvbmRpdGlvbnMKKy8vIGFyZSBtZXQ6CisvLyAxLiBSZWRpc3RyaWJ1dGlvbnMg b2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gICAgbm90 aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVy LgorLy8gMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRo ZSBhYm92ZSBjb3B5cmlnaHQKKy8vICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMg YW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKKy8vICAgIGRvY3VtZW50YXRpb24g YW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisv LworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMg QU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBX QVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVE IFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJU SUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZ UklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1Qs IElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFV RU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VS RU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBE QVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VE IEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1Qs IFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBP VEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBT T0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFH RS4KKworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIG1hY3JvcyB0aGF0IGFyZSBzaGFyZWQgYnkgdGhl IG90aGVyIGFlcy0qLlMgZmlsZXMuICBUaGUKKy8vIGdlbmVyYXRlZCBjb2RlIG9mIHRoZXNlIG1h Y3JvcyBkZXBlbmRzIG9uIHRoZSBmb2xsb3dpbmcgUklTQy1WIGV4dGVuc2lvbnM6CisvLyAtIFJW NjRJCisvLyAtIFJJU0MtViBWZWN0b3IgKCdWJykgd2l0aCBWTEVOID49IDEyOAorLy8gLSBSSVND LVYgVmVjdG9yIEFFUyBibG9jayBjaXBoZXIgZXh0ZW5zaW9uICgnWnZrbmVkJykKKworLy8gTG9h ZHMgdGhlIEFFUyByb3VuZCBrZXlzIGZyb20gXGtleXAgaW50byB2ZWN0b3IgcmVnaXN0ZXJzIGFu ZCBqdW1wcyB0byBjb2RlCisvLyBzcGVjaWZpYyB0byB0aGUgbGVuZ3RoIG9mIHRoZSBrZXkuICBT cGVjaWZpY2FsbHk6CisvLyAgIC0gSWYgQUVTLTEyOCwgbG9hZHMgcm91bmQga2V5cyBpbnRvIHYx LXYxMSBhbmQganVtcHMgdG8gXGxhYmVsMTI4LgorLy8gICAtIElmIEFFUy0xOTIsIGxvYWRzIHJv dW5kIGtleXMgaW50byB2MS12MTMgYW5kIGp1bXBzIHRvIFxsYWJlbDE5Mi4KKy8vICAgLSBJZiBB RVMtMjU2LCBsb2FkcyByb3VuZCBrZXlzIGludG8gdjEtdjE1IGFuZCBjb250aW51ZXMgb253YXJk cy4KKy8vCisvLyBBbHNvIHNldHMgdmw9NCBhbmQgdnR5cGU9ZTMyLG0xLHRhLG1hLiAgQ2xvYmJl cnMgdDAgYW5kIHQxLgorLm1hY3JvCWFlc19iZWdpbglrZXlwLCBsYWJlbDEyOCwgbGFiZWwxOTIK Kwlsd3UJCXQwLCA0ODAoXGtleXApCS8vIHQwID0ga2V5IGxlbmd0aCBpbiBieXRlcworCWxpCQl0 MSwgMjQJCS8vIHQxID0ga2V5IGxlbmd0aCBmb3IgQUVTLTE5MgorCXZzZXRpdmxpCXplcm8sIDQs IGUzMiwgbTEsIHRhLCBtYQorCXZsZTMyLnYJCXYxLCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxr ZXlwLCAxNgorCXZsZTMyLnYJCXYyLCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgor CXZsZTMyLnYJCXYzLCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJ CXY0LCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXY1LCAoXGtl eXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXY2LCAoXGtleXApCisJYWRk aQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXY3LCAoXGtleXApCisJYWRkaQkJXGtleXAs IFxrZXlwLCAxNgorCXZsZTMyLnYJCXY4LCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAx NgorCXZsZTMyLnYJCXY5LCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMy LnYJCXYxMCwgKFxrZXlwKQorCWFkZGkJCVxrZXlwLCBca2V5cCwgMTYKKwl2bGUzMi52CQl2MTEs IChca2V5cCkKKwlibHQJCXQwLCB0MSwgXGxhYmVsMTI4CS8vIElmIEFFUy0xMjgsIGdvdG8gbGFi ZWwxMjguCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXYxMiwgKFxrZXlwKQor CWFkZGkJCVxrZXlwLCBca2V5cCwgMTYKKwl2bGUzMi52CQl2MTMsIChca2V5cCkKKwliZXEJCXQw LCB0MSwgXGxhYmVsMTkyCS8vIElmIEFFUy0xOTIsIGdvdG8gbGFiZWwxOTIuCisJLy8gRWxzZSwg aXQncyBBRVMtMjU2LgorCWFkZGkJCVxrZXlwLCBca2V5cCwgMTYKKwl2bGUzMi52CQl2MTQsIChc a2V5cCkKKwlhZGRpCQlca2V5cCwgXGtleXAsIDE2CisJdmxlMzIudgkJdjE1LCAoXGtleXApCisu ZW5kbQorCisvLyBFbmNyeXB0cyBcZGF0YSB1c2luZyB6dmtuZWQgaW5zdHJ1Y3Rpb25zLCB1c2lu ZyB0aGUgcm91bmQga2V5cyBsb2FkZWQgaW50bworLy8gdjEtdjExIChmb3IgQUVTLTEyOCksIHYx LXYxMyAoZm9yIEFFUy0xOTIpLCBvciB2MS12MTUgKGZvciBBRVMtMjU2KS4gIFxrZXlsZW4KKy8v IGlzIHRoZSBBRVMga2V5IGxlbmd0aCBpbiBiaXRzLiAgdmwgYW5kIHZ0eXBlIG11c3QgYWxyZWFk eSBiZSBzZXQKKy8vIGFwcHJvcHJpYXRlbHkuICBOb3RlIHRoYXQgaWYgdmwgPiA0LCBtdWx0aXBs ZSBibG9ja3MgYXJlIGVuY3J5cHRlZC4KKy5tYWNybwlhZXNfZW5jcnlwdAlkYXRhLCBrZXlsZW4K Kwl2YWVzei52cwlcZGF0YSwgdjEKKwl2YWVzZW0udnMJXGRhdGEsIHYyCisJdmFlc2VtLnZzCVxk YXRhLCB2MworCXZhZXNlbS52cwlcZGF0YSwgdjQKKwl2YWVzZW0udnMJXGRhdGEsIHY1CisJdmFl c2VtLnZzCVxkYXRhLCB2NgorCXZhZXNlbS52cwlcZGF0YSwgdjcKKwl2YWVzZW0udnMJXGRhdGEs IHY4CisJdmFlc2VtLnZzCVxkYXRhLCB2OQorCXZhZXNlbS52cwlcZGF0YSwgdjEwCisuaWYgXGtl eWxlbiA9PSAxMjgKKwl2YWVzZWYudnMJXGRhdGEsIHYxMQorLmVsc2VpZiBca2V5bGVuID09IDE5 MgorCXZhZXNlbS52cwlcZGF0YSwgdjExCisJdmFlc2VtLnZzCVxkYXRhLCB2MTIKKwl2YWVzZWYu dnMJXGRhdGEsIHYxMworLmVsc2UKKwl2YWVzZW0udnMJXGRhdGEsIHYxMQorCXZhZXNlbS52cwlc ZGF0YSwgdjEyCisJdmFlc2VtLnZzCVxkYXRhLCB2MTMKKwl2YWVzZW0udnMJXGRhdGEsIHYxNAor CXZhZXNlZi52cwlcZGF0YSwgdjE1CisuZW5kaWYKKy5lbmRtCisKKy8vIFNhbWUgYXMgYWVzX2Vu Y3J5cHQsIGJ1dCBkZWNyeXB0cyBpbnN0ZWFkIG9mIGVuY3J5cHRzLgorLm1hY3JvCWFlc19kZWNy eXB0CWRhdGEsIGtleWxlbgorLmlmIFxrZXlsZW4gPT0gMTI4CisJdmFlc3oudnMJXGRhdGEsIHYx MQorLmVsc2VpZiBca2V5bGVuID09IDE5MgorCXZhZXN6LnZzCVxkYXRhLCB2MTMKKwl2YWVzZG0u dnMJXGRhdGEsIHYxMgorCXZhZXNkbS52cwlcZGF0YSwgdjExCisuZWxzZQorCXZhZXN6LnZzCVxk YXRhLCB2MTUKKwl2YWVzZG0udnMJXGRhdGEsIHYxNAorCXZhZXNkbS52cwlcZGF0YSwgdjEzCisJ dmFlc2RtLnZzCVxkYXRhLCB2MTIKKwl2YWVzZG0udnMJXGRhdGEsIHYxMQorLmVuZGlmCisJdmFl c2RtLnZzCVxkYXRhLCB2MTAKKwl2YWVzZG0udnMJXGRhdGEsIHY5CisJdmFlc2RtLnZzCVxkYXRh LCB2OAorCXZhZXNkbS52cwlcZGF0YSwgdjcKKwl2YWVzZG0udnMJXGRhdGEsIHY2CisJdmFlc2Rt LnZzCVxkYXRhLCB2NQorCXZhZXNkbS52cwlcZGF0YSwgdjQKKwl2YWVzZG0udnMJXGRhdGEsIHYz CisJdmFlc2RtLnZzCVxkYXRhLCB2MgorCXZhZXNkZi52cwlcZGF0YSwgdjEKKy5lbmRtCisKKy8v IEV4cGFuZHMgdG8gYWVzX2VuY3J5cHQgb3IgYWVzX2RlY3J5cHQgYWNjb3JkaW5nIHRvIFxlbmMs IHdoaWNoIGlzIDEgb3IgMC4KKy5tYWNybwlhZXNfY3J5cHQJZGF0YSwgZW5jLCBrZXlsZW4KKy5p ZiBcZW5jCisJYWVzX2VuY3J5cHQJXGRhdGEsIFxrZXlsZW4KKy5lbHNlCisJYWVzX2RlY3J5cHQJ XGRhdGEsIFxrZXlsZW4KKy5lbmRpZgorLmVuZG0KZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3YvY3J5 cHRvL2Flcy1yaXNjdjY0LWdsdWUuYyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LWds dWUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAwLi4zN2JjNmVmMGJl NDBlCi0tLSAvZGV2L251bGwKKysrIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtZ2x1 ZS5jCkBAIC0wLDAgKzEsNTUwIEBACisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIu MC1vbmx5CisvKgorICogQUVTIHVzaW5nIHRoZSBSSVNDLVYgdmVjdG9yIGNyeXB0byBleHRlbnNp b25zLiAgSW5jbHVkZXMgdGhlIGJhcmUgYmxvY2sKKyAqIGNpcGhlciBhbmQgdGhlIEVDQiwgQ0JD LCBDVFIsIGFuZCBYVFMgbW9kZXMuCisgKgorICogQ29weXJpZ2h0IChDKSAyMDIzIFZSVUxMIEdt YkgKKyAqIEF1dGhvcjogSGVpa28gU3R1ZWJuZXIgPGhlaWtvLnN0dWVibmVyQHZydWxsLmV1Pgor ICoKKyAqIENvcHlyaWdodCAoQykgMjAyMyBTaUZpdmUsIEluYy4KKyAqIEF1dGhvcjogSmVycnkg U2hpaCA8amVycnkuc2hpaEBzaWZpdmUuY29tPgorICovCisKKyNpbmNsdWRlIDxhc20vc2ltZC5o PgorI2luY2x1ZGUgPGFzbS92ZWN0b3IuaD4KKyNpbmNsdWRlIDxjcnlwdG8vYWVzLmg+CisjaW5j bHVkZSA8Y3J5cHRvL2ludGVybmFsL2NpcGhlci5oPgorI2luY2x1ZGUgPGNyeXB0by9pbnRlcm5h bC9zaW1kLmg+CisjaW5jbHVkZSA8Y3J5cHRvL2ludGVybmFsL3NrY2lwaGVyLmg+CisjaW5jbHVk ZSA8Y3J5cHRvL3NjYXR0ZXJ3YWxrLmg+CisjaW5jbHVkZSA8Y3J5cHRvL3h0cy5oPgorI2luY2x1 ZGUgPGxpbnV4L2xpbmthZ2UuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKworYXNtbGlu a2FnZSB2b2lkIGFlc19lbmNyeXB0X3p2a25lZChjb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHgg KmtleSwKKwkJCQkgICBjb25zdCB1OCBpbltBRVNfQkxPQ0tfU0laRV0sCisJCQkJICAgdTggb3V0 W0FFU19CTE9DS19TSVpFXSk7Cithc21saW5rYWdlIHZvaWQgYWVzX2RlY3J5cHRfenZrbmVkKGNv bnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqa2V5LAorCQkJCSAgIGNvbnN0IHU4IGluW0FFU19C TE9DS19TSVpFXSwKKwkJCQkgICB1OCBvdXRbQUVTX0JMT0NLX1NJWkVdKTsKKworYXNtbGlua2Fn ZSB2b2lkIGFlc19lY2JfZW5jcnlwdF96dmtuZWQoY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4 ICprZXksCisJCQkJICAgICAgIGNvbnN0IHU4ICppbiwgdTggKm91dCwgc2l6ZV90IGxlbik7Cith c21saW5rYWdlIHZvaWQgYWVzX2VjYl9kZWNyeXB0X3p2a25lZChjb25zdCBzdHJ1Y3QgY3J5cHRv X2Flc19jdHggKmtleSwKKwkJCQkgICAgICAgY29uc3QgdTggKmluLCB1OCAqb3V0LCBzaXplX3Qg bGVuKTsKKworYXNtbGlua2FnZSB2b2lkIGFlc19jYmNfZW5jcnlwdF96dmtuZWQoY29uc3Qgc3Ry dWN0IGNyeXB0b19hZXNfY3R4ICprZXksCisJCQkJICAgICAgIGNvbnN0IHU4ICppbiwgdTggKm91 dCwgc2l6ZV90IGxlbiwKKwkJCQkgICAgICAgdTggaXZbQUVTX0JMT0NLX1NJWkVdKTsKK2FzbWxp bmthZ2Ugdm9pZCBhZXNfY2JjX2RlY3J5cHRfenZrbmVkKGNvbnN0IHN0cnVjdCBjcnlwdG9fYWVz X2N0eCAqa2V5LAorCQkJCSAgICAgICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNpemVfdCBsZW4s CisJCQkJICAgICAgIHU4IGl2W0FFU19CTE9DS19TSVpFXSk7CisKK2FzbWxpbmthZ2Ugdm9pZCBh ZXNfY3RyMzJfY3J5cHRfenZrbmVkX3p2a2IoY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4ICpr ZXksCisJCQkJCSAgICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNpemVfdCBsZW4sCisJCQkJCSAg ICB1OCBpdltBRVNfQkxPQ0tfU0laRV0pOworCithc21saW5rYWdlIHZvaWQgYWVzX3h0c19lbmNy eXB0X3p2a25lZF96dmJiX3p2a2coCisJCQljb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHggKmtl eSwKKwkJCWNvbnN0IHU4ICppbiwgdTggKm91dCwgc2l6ZV90IGxlbiwKKwkJCXU4IHR3ZWFrW0FF U19CTE9DS19TSVpFXSk7CisKK2FzbWxpbmthZ2Ugdm9pZCBhZXNfeHRzX2RlY3J5cHRfenZrbmVk X3p2YmJfenZrZygKKwkJCWNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqa2V5LAorCQkJY29u c3QgdTggKmluLCB1OCAqb3V0LCBzaXplX3QgbGVuLAorCQkJdTggdHdlYWtbQUVTX0JMT0NLX1NJ WkVdKTsKKworc3RhdGljIGludCByaXNjdjY0X2Flc19zZXRrZXkoc3RydWN0IGNyeXB0b19hZXNf Y3R4ICpjdHgsCisJCQkgICAgICBjb25zdCB1OCAqa2V5LCB1bnNpZ25lZCBpbnQga2V5bGVuKQor eworCS8qCisJICogRm9yIG5vdyB3ZSBqdXN0IHVzZSB0aGUgZ2VuZXJpYyBrZXkgZXhwYW5zaW9u LCBmb3IgdGhlc2UgcmVhc29uczoKKwkgKgorCSAqIC0genZrbmVkJ3Mga2V5IGV4cGFuc2lvbiBp bnN0cnVjdGlvbnMgZG9uJ3Qgc3VwcG9ydCBBRVMtMTkyLgorCSAqICAgU28sIG5vbi16dmtuZWQg ZmFsbGJhY2sgY29kZSB3b3VsZCBiZSBuZWVkZWQgYW55d2F5LgorCSAqCisJICogLSBVc2VycyBv ZiBBRVMgaW4gTGludXggdXN1YWxseSBkb24ndCBjaGFuZ2Uga2V5cyBmcmVxdWVudGx5LgorCSAq ICAgU28sIGtleSBleHBhbnNpb24gaXNuJ3QgcGVyZm9ybWFuY2UtY3JpdGljYWwuCisJICoKKwkg KiAtIEZvciBzaW5nbGUtYmxvY2sgQUVTIGV4cG9zZWQgYXMgYSAiY2lwaGVyIiBhbGdvcml0aG0s IGl0J3MKKwkgKiAgIG5lY2Vzc2FyeSB0byB1c2Ugc3RydWN0IGNyeXB0b19hZXNfY3R4IGFuZCBp bml0aWFsaXplIGl0cyAna2V5X2RlYycKKwkgKiAgIGZpZWxkIHdpdGggdGhlIHJvdW5kIGtleXMg Zm9yIHRoZSBFcXVpdmFsZW50IEludmVyc2UgQ2lwaGVyLiAgVGhpcworCSAqICAgaXMgYmVjYXVz ZSB3aXRoICJjaXBoZXIiLCBkZWNyeXB0aW9uIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSBhCisJICog ICBjb250ZXh0IHdoZXJlIHRoZSB2ZWN0b3IgdW5pdCBpc24ndCB1c2FibGUsIG5lY2Vzc2l0YXRp bmcgYQorCSAqICAgZmFsbGJhY2sgdG8gYWVzX2RlY3J5cHQoKS4gIEJ1dCwgenZrbmVkIGNhbiBv bmx5IGdlbmVyYXRlIGFuZCB1c2UKKwkgKiAgIHRoZSBub3JtYWwgcm91bmQga2V5cy4gIE9mIGNv dXJzZSwgaXQncyBwcmVmZXJhYmxlIHRvIG5vdCBoYXZlCisJICogICBzcGVjaWFsIGNvZGUganVz dCBmb3IgImNpcGhlciIsIGFzIGUuZy4gWFRTIGFsc28gdXNlcyBhCisJICogICBzaW5nbGUtYmxv Y2sgQUVTIGVuY3J5cHRpb24uICBJdCdzIHNpbXBsZXN0IHRvIGp1c3QgdXNlCisJICogICBzdHJ1 Y3QgY3J5cHRvX2Flc19jdHggYW5kIGFlc19leHBhbmRrZXkoKSBldmVyeXdoZXJlLgorCSAqLwor CXJldHVybiBhZXNfZXhwYW5ka2V5KGN0eCwga2V5LCBrZXlsZW4pOworfQorCitzdGF0aWMgaW50 IHJpc2N2NjRfYWVzX3NldGtleV9jaXBoZXIoc3RydWN0IGNyeXB0b190Zm0gKnRmbSwKKwkJCQkg ICAgIGNvbnN0IHU4ICprZXksIHVuc2lnbmVkIGludCBrZXlsZW4pCit7CisJc3RydWN0IGNyeXB0 b19hZXNfY3R4ICpjdHggPSBjcnlwdG9fdGZtX2N0eCh0Zm0pOworCisJcmV0dXJuIHJpc2N2NjRf YWVzX3NldGtleShjdHgsIGtleSwga2V5bGVuKTsKK30KKworc3RhdGljIGludCByaXNjdjY0X2Fl c19zZXRrZXlfc2tjaXBoZXIoc3RydWN0IGNyeXB0b19za2NpcGhlciAqdGZtLAorCQkJCSAgICAg ICBjb25zdCB1OCAqa2V5LCB1bnNpZ25lZCBpbnQga2V5bGVuKQoreworCXN0cnVjdCBjcnlwdG9f YWVzX2N0eCAqY3R4ID0gY3J5cHRvX3NrY2lwaGVyX2N0eCh0Zm0pOworCisJcmV0dXJuIHJpc2N2 NjRfYWVzX3NldGtleShjdHgsIGtleSwga2V5bGVuKTsKK30KKworLyogQmFyZSBBRVMsIHdpdGhv dXQgYSBtb2RlIG9mIG9wZXJhdGlvbiAqLworCitzdGF0aWMgdm9pZCByaXNjdjY0X2Flc19lbmNy eXB0KHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0sIHU4ICpkc3QsIGNvbnN0IHU4ICpzcmMpCit7CisJ Y29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4ICpjdHggPSBjcnlwdG9fdGZtX2N0eCh0Zm0pOwor CisJaWYgKGNyeXB0b19zaW1kX3VzYWJsZSgpKSB7CisJCWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsK KwkJYWVzX2VuY3J5cHRfenZrbmVkKGN0eCwgc3JjLCBkc3QpOworCQlrZXJuZWxfdmVjdG9yX2Vu ZCgpOworCX0gZWxzZSB7CisJCWFlc19lbmNyeXB0KGN0eCwgZHN0LCBzcmMpOworCX0KK30KKwor c3RhdGljIHZvaWQgcmlzY3Y2NF9hZXNfZGVjcnlwdChzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtLCB1 OCAqZHN0LCBjb25zdCB1OCAqc3JjKQoreworCWNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAq Y3R4ID0gY3J5cHRvX3RmbV9jdHgodGZtKTsKKworCWlmIChjcnlwdG9fc2ltZF91c2FibGUoKSkg eworCQlrZXJuZWxfdmVjdG9yX2JlZ2luKCk7CisJCWFlc19kZWNyeXB0X3p2a25lZChjdHgsIHNy YywgZHN0KTsKKwkJa2VybmVsX3ZlY3Rvcl9lbmQoKTsKKwl9IGVsc2UgeworCQlhZXNfZGVjcnlw dChjdHgsIGRzdCwgc3JjKTsKKwl9Cit9CisKKy8qIEFFUy1FQ0IgKi8KKworc3RhdGljIGlubGlu ZSBpbnQgcmlzY3Y2NF9hZXNfZWNiX2NyeXB0KHN0cnVjdCBza2NpcGhlcl9yZXF1ZXN0ICpyZXEs IGJvb2wgZW5jKQoreworCXN0cnVjdCBjcnlwdG9fc2tjaXBoZXIgKnRmbSA9IGNyeXB0b19za2Np cGhlcl9yZXF0Zm0ocmVxKTsKKwljb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHggKmN0eCA9IGNy eXB0b19za2NpcGhlcl9jdHgodGZtKTsKKwlzdHJ1Y3Qgc2tjaXBoZXJfd2FsayB3YWxrOworCXVu c2lnbmVkIGludCBuYnl0ZXM7CisJaW50IGVycjsKKworCWVyciA9IHNrY2lwaGVyX3dhbGtfdmly dCgmd2FsaywgcmVxLCBmYWxzZSk7CisJd2hpbGUgKChuYnl0ZXMgPSB3YWxrLm5ieXRlcykgIT0g MCkgeworCQlrZXJuZWxfdmVjdG9yX2JlZ2luKCk7CisJCWlmIChlbmMpCisJCQlhZXNfZWNiX2Vu Y3J5cHRfenZrbmVkKGN0eCwgd2Fsay5zcmMudmlydC5hZGRyLAorCQkJCQkgICAgICAgd2Fsay5k c3QudmlydC5hZGRyLAorCQkJCQkgICAgICAgbmJ5dGVzICYgfihBRVNfQkxPQ0tfU0laRSAtIDEp KTsKKwkJZWxzZQorCQkJYWVzX2VjYl9kZWNyeXB0X3p2a25lZChjdHgsIHdhbGsuc3JjLnZpcnQu YWRkciwKKwkJCQkJICAgICAgIHdhbGsuZHN0LnZpcnQuYWRkciwKKwkJCQkJICAgICAgIG5ieXRl cyAmIH4oQUVTX0JMT0NLX1NJWkUgLSAxKSk7CisJCWtlcm5lbF92ZWN0b3JfZW5kKCk7CisJCWVy ciA9IHNrY2lwaGVyX3dhbGtfZG9uZSgmd2FsaywgbmJ5dGVzICYgKEFFU19CTE9DS19TSVpFIC0g MSkpOworCX0KKworCXJldHVybiBlcnI7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfZWNi X2VuY3J5cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2 NF9hZXNfZWNiX2NyeXB0KHJlcSwgdHJ1ZSk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNf ZWNiX2RlY3J5cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlz Y3Y2NF9hZXNfZWNiX2NyeXB0KHJlcSwgZmFsc2UpOworfQorCisvKiBBRVMtQ0JDICovCisKK3N0 YXRpYyBpbmxpbmUgaW50IHJpc2N2NjRfYWVzX2NiY19jcnlwdChzdHJ1Y3Qgc2tjaXBoZXJfcmVx dWVzdCAqcmVxLCBib29sIGVuYykKK3sKKwlzdHJ1Y3QgY3J5cHRvX3NrY2lwaGVyICp0Zm0gPSBj cnlwdG9fc2tjaXBoZXJfcmVxdGZtKHJlcSk7CisJY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4 ICpjdHggPSBjcnlwdG9fc2tjaXBoZXJfY3R4KHRmbSk7CisJc3RydWN0IHNrY2lwaGVyX3dhbGsg d2FsazsKKwl1bnNpZ25lZCBpbnQgbmJ5dGVzOworCWludCBlcnI7CisKKwllcnIgPSBza2NpcGhl cl93YWxrX3ZpcnQoJndhbGssIHJlcSwgZmFsc2UpOworCXdoaWxlICgobmJ5dGVzID0gd2Fsay5u Ynl0ZXMpICE9IDApIHsKKwkJa2VybmVsX3ZlY3Rvcl9iZWdpbigpOworCQlpZiAoZW5jKQorCQkJ YWVzX2NiY19lbmNyeXB0X3p2a25lZChjdHgsIHdhbGsuc3JjLnZpcnQuYWRkciwKKwkJCQkJICAg ICAgIHdhbGsuZHN0LnZpcnQuYWRkciwKKwkJCQkJICAgICAgIG5ieXRlcyAmIH4oQUVTX0JMT0NL X1NJWkUgLSAxKSwKKwkJCQkJICAgICAgIHdhbGsuaXYpOworCQllbHNlCisJCQlhZXNfY2JjX2Rl Y3J5cHRfenZrbmVkKGN0eCwgd2Fsay5zcmMudmlydC5hZGRyLAorCQkJCQkgICAgICAgd2Fsay5k c3QudmlydC5hZGRyLAorCQkJCQkgICAgICAgbmJ5dGVzICYgfihBRVNfQkxPQ0tfU0laRSAtIDEp LAorCQkJCQkgICAgICAgd2Fsay5pdik7CisJCWtlcm5lbF92ZWN0b3JfZW5kKCk7CisJCWVyciA9 IHNrY2lwaGVyX3dhbGtfZG9uZSgmd2FsaywgbmJ5dGVzICYgKEFFU19CTE9DS19TSVpFIC0gMSkp OworCX0KKworCXJldHVybiBlcnI7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfY2JjX2Vu Y3J5cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9h ZXNfY2JjX2NyeXB0KHJlcSwgdHJ1ZSk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfY2Jj X2RlY3J5cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2 NF9hZXNfY2JjX2NyeXB0KHJlcSwgZmFsc2UpOworfQorCisvKiBBRVMtQ1RSICovCisKK3N0YXRp YyBpbnQgcmlzY3Y2NF9hZXNfY3RyX2NyeXB0KHN0cnVjdCBza2NpcGhlcl9yZXF1ZXN0ICpyZXEp Cit7CisJc3RydWN0IGNyeXB0b19za2NpcGhlciAqdGZtID0gY3J5cHRvX3NrY2lwaGVyX3JlcXRm bShyZXEpOworCWNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqY3R4ID0gY3J5cHRvX3NrY2lw aGVyX2N0eCh0Zm0pOworCXVuc2lnbmVkIGludCBuYnl0ZXMsIHAxX25ieXRlczsKKwlzdHJ1Y3Qg c2tjaXBoZXJfd2FsayB3YWxrOworCXUzMiBjdHIzMiwgbmJsb2NrczsKKwlpbnQgZXJyOworCisJ LyogR2V0IHRoZSBsb3cgMzItYml0IHdvcmQgb2YgdGhlIDEyOC1iaXQgYmlnIGVuZGlhbiBjb3Vu dGVyLiAqLworCWN0cjMyID0gZ2V0X3VuYWxpZ25lZF9iZTMyKHJlcS0+aXYgKyAxMik7CisKKwll cnIgPSBza2NpcGhlcl93YWxrX3ZpcnQoJndhbGssIHJlcSwgZmFsc2UpOworCXdoaWxlICgobmJ5 dGVzID0gd2Fsay5uYnl0ZXMpICE9IDApIHsKKwkJaWYgKG5ieXRlcyA8IHdhbGsudG90YWwpIHsK KwkJCS8qIE5vdCB0aGUgZW5kIHlldCwgc28ga2VlcCB0aGUgbGVuZ3RoIGJsb2NrLWFsaWduZWQu ICovCisJCQluYnl0ZXMgPSByb3VuZF9kb3duKG5ieXRlcywgQUVTX0JMT0NLX1NJWkUpOworCQkJ bmJsb2NrcyA9IG5ieXRlcyAvIEFFU19CTE9DS19TSVpFOworCQl9IGVsc2UgeworCQkJLyogSXQn cyB0aGUgZW5kLCBzbyBpbmNsdWRlIGFueSBmaW5hbCBwYXJ0aWFsIGJsb2NrLiAqLworCQkJbmJs b2NrcyA9IERJVl9ST1VORF9VUChuYnl0ZXMsIEFFU19CTE9DS19TSVpFKTsKKwkJfQorCQljdHIz MiArPSBuYmxvY2tzOworCisJCWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsKKwkJaWYgKGN0cjMyID49 IG5ibG9ja3MpIHsKKwkJCS8qIFRoZSBsb3cgMzItYml0IHdvcmQgb2YgdGhlIGNvdW50ZXIgd29u J3Qgb3ZlcmZsb3cuICovCisJCQlhZXNfY3RyMzJfY3J5cHRfenZrbmVkX3p2a2IoY3R4LCB3YWxr LnNyYy52aXJ0LmFkZHIsCisJCQkJCQkgICAgd2Fsay5kc3QudmlydC5hZGRyLCBuYnl0ZXMsCisJ CQkJCQkgICAgcmVxLT5pdik7CisJCX0gZWxzZSB7CisJCQkvKgorCQkJICogVGhlIGxvdyAzMi1i aXQgd29yZCBvZiB0aGUgY291bnRlciB3aWxsIG92ZXJmbG93LgorCQkJICogVGhlIGFzc2VtYmx5 IGRvZXNuJ3QgaGFuZGxlIHRoaXMgY2FzZSwgc28gc3BsaXQgdGhlCisJCQkgKiBvcGVyYXRpb24g aW50byB0d28gYXQgdGhlIHBvaW50IHdoZXJlIHRoZSBvdmVyZmxvdworCQkJICogd2lsbCBvY2N1 ci4gIEFmdGVyIHRoZSBmaXJzdCBwYXJ0LCBhZGQgdGhlIGNhcnJ5IGJpdC4KKwkJCSAqLworCQkJ cDFfbmJ5dGVzID0gbWluX3QodW5zaWduZWQgaW50LCBuYnl0ZXMsCisJCQkJCSAgKG5ibG9ja3Mg LSBjdHIzMikgKiBBRVNfQkxPQ0tfU0laRSk7CisJCQlhZXNfY3RyMzJfY3J5cHRfenZrbmVkX3p2 a2IoY3R4LCB3YWxrLnNyYy52aXJ0LmFkZHIsCisJCQkJCQkgICAgd2Fsay5kc3QudmlydC5hZGRy LAorCQkJCQkJICAgIHAxX25ieXRlcywgcmVxLT5pdik7CisJCQljcnlwdG9faW5jKHJlcS0+aXYs IDEyKTsKKworCQkJaWYgKGN0cjMyKSB7CisJCQkJYWVzX2N0cjMyX2NyeXB0X3p2a25lZF96dmti KAorCQkJCQljdHgsCisJCQkJCXdhbGsuc3JjLnZpcnQuYWRkciArIHAxX25ieXRlcywKKwkJCQkJ d2Fsay5kc3QudmlydC5hZGRyICsgcDFfbmJ5dGVzLAorCQkJCQluYnl0ZXMgLSBwMV9uYnl0ZXMs IHJlcS0+aXYpOworCQkJfQorCQl9CisJCWtlcm5lbF92ZWN0b3JfZW5kKCk7CisKKwkJZXJyID0g c2tjaXBoZXJfd2Fsa19kb25lKCZ3YWxrLCB3YWxrLm5ieXRlcyAtIG5ieXRlcyk7CisJfQorCisJ cmV0dXJuIGVycjsKK30KKworLyogQUVTLVhUUyAqLworCitzdHJ1Y3QgcmlzY3Y2NF9hZXNfeHRz X2N0eCB7CisJc3RydWN0IGNyeXB0b19hZXNfY3R4IGN0eDE7CisJc3RydWN0IGNyeXB0b19hZXNf Y3R4IGN0eDI7Cit9OworCitzdGF0aWMgaW50IHJpc2N2NjRfYWVzX3h0c19zZXRrZXkoc3RydWN0 IGNyeXB0b19za2NpcGhlciAqdGZtLCBjb25zdCB1OCAqa2V5LAorCQkJCSAgdW5zaWduZWQgaW50 IGtleWxlbikKK3sKKwlzdHJ1Y3QgcmlzY3Y2NF9hZXNfeHRzX2N0eCAqY3R4ID0gY3J5cHRvX3Nr Y2lwaGVyX2N0eCh0Zm0pOworCisJcmV0dXJuIHh0c192ZXJpZnlfa2V5KHRmbSwga2V5LCBrZXls ZW4pID86CisJICAgICAgIHJpc2N2NjRfYWVzX3NldGtleSgmY3R4LT5jdHgxLCBrZXksIGtleWxl biAvIDIpID86CisJICAgICAgIHJpc2N2NjRfYWVzX3NldGtleSgmY3R4LT5jdHgyLCBrZXkgKyBr ZXlsZW4gLyAyLCBrZXlsZW4gLyAyKTsKK30KKworc3RhdGljIGludCByaXNjdjY0X2Flc194dHNf Y3J5cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSwgYm9vbCBlbmMpCit7CisJc3RydWN0 IGNyeXB0b19za2NpcGhlciAqdGZtID0gY3J5cHRvX3NrY2lwaGVyX3JlcXRmbShyZXEpOworCWNv bnN0IHN0cnVjdCByaXNjdjY0X2Flc194dHNfY3R4ICpjdHggPSBjcnlwdG9fc2tjaXBoZXJfY3R4 KHRmbSk7CisJaW50IHRhaWwgPSByZXEtPmNyeXB0bGVuICUgQUVTX0JMT0NLX1NJWkU7CisJc3Ry dWN0IHNjYXR0ZXJsaXN0IHNnX3NyY1syXSwgc2dfZHN0WzJdOworCXN0cnVjdCBza2NpcGhlcl9y ZXF1ZXN0IHN1YnJlcTsKKwlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNyYywgKmRzdDsKKwlzdHJ1Y3Qg c2tjaXBoZXJfd2FsayB3YWxrOworCWludCBlcnI7CisKKwlpZiAocmVxLT5jcnlwdGxlbiA8IEFF U19CTE9DS19TSVpFKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCS8qIEVuY3J5cHQgdGhlIElWIHdp dGggdGhlIHR3ZWFrIGtleSB0byBnZXQgdGhlIGZpcnN0IHR3ZWFrLiAqLworCWtlcm5lbF92ZWN0 b3JfYmVnaW4oKTsKKwlhZXNfZW5jcnlwdF96dmtuZWQoJmN0eC0+Y3R4MiwgcmVxLT5pdiwgcmVx LT5pdik7CisJa2VybmVsX3ZlY3Rvcl9lbmQoKTsKKworCWVyciA9IHNrY2lwaGVyX3dhbGtfdmly dCgmd2FsaywgcmVxLCBmYWxzZSk7CisKKwkvKgorCSAqIElmIHRoZSBtZXNzYWdlIGxlbmd0aCBp c24ndCBkaXZpc2libGUgYnkgdGhlIEFFUyBibG9jayBzaXplIGFuZCB0aGUKKwkgKiBmdWxsIG1l c3NhZ2UgaXNuJ3QgYXZhaWxhYmxlIGluIG9uZSBzdGVwIG9mIHRoZSBzY2F0dGVybGlzdCB3YWxr LAorCSAqIHRoZW4gc2VwYXJhdGUgb2ZmIHRoZSBsYXN0IGZ1bGwgYmxvY2sgYW5kIHRoZSBwYXJ0 aWFsIGJsb2NrLiAgVGhpcworCSAqIGVuc3VyZXMgdGhhdCB0aGV5IGFyZSBwcm9jZXNzZWQgaW4g dGhlIHNhbWUgY2FsbCB0byB0aGUgYXNzZW1ibHkKKwkgKiBmdW5jdGlvbiwgd2hpY2ggaXMgcmVx dWlyZWQgZm9yIGNpcGhlcnRleHQgc3RlYWxpbmcuCisJICovCisJaWYgKHVubGlrZWx5KHRhaWwg PiAwICYmIHdhbGsubmJ5dGVzIDwgd2Fsay50b3RhbCkpIHsKKwkJc2tjaXBoZXJfd2Fsa19hYm9y dCgmd2Fsayk7CisKKwkJc2tjaXBoZXJfcmVxdWVzdF9zZXRfdGZtKCZzdWJyZXEsIHRmbSk7CisJ CXNrY2lwaGVyX3JlcXVlc3Rfc2V0X2NhbGxiYWNrKCZzdWJyZXEsCisJCQkJCSAgICAgIHNrY2lw aGVyX3JlcXVlc3RfZmxhZ3MocmVxKSwKKwkJCQkJICAgICAgTlVMTCwgTlVMTCk7CisJCXNrY2lw aGVyX3JlcXVlc3Rfc2V0X2NyeXB0KCZzdWJyZXEsIHJlcS0+c3JjLCByZXEtPmRzdCwKKwkJCQkJ ICAgcmVxLT5jcnlwdGxlbiAtIHRhaWwgLSBBRVNfQkxPQ0tfU0laRSwKKwkJCQkJICAgcmVxLT5p dik7CisJCXJlcSA9ICZzdWJyZXE7CisJCWVyciA9IHNrY2lwaGVyX3dhbGtfdmlydCgmd2Fsaywg cmVxLCBmYWxzZSk7CisJfSBlbHNlIHsKKwkJdGFpbCA9IDA7CisJfQorCisJd2hpbGUgKHdhbGsu bmJ5dGVzKSB7CisJCXVuc2lnbmVkIGludCBuYnl0ZXMgPSB3YWxrLm5ieXRlczsKKworCQlpZiAo bmJ5dGVzIDwgd2Fsay50b3RhbCkKKwkJCW5ieXRlcyA9IHJvdW5kX2Rvd24obmJ5dGVzLCBBRVNf QkxPQ0tfU0laRSk7CisKKwkJa2VybmVsX3ZlY3Rvcl9iZWdpbigpOworCQlpZiAoZW5jKQorCQkJ YWVzX3h0c19lbmNyeXB0X3p2a25lZF96dmJiX3p2a2coCisJCQkJJmN0eC0+Y3R4MSwgd2Fsay5z cmMudmlydC5hZGRyLAorCQkJCXdhbGsuZHN0LnZpcnQuYWRkciwgbmJ5dGVzLCByZXEtPml2KTsK KwkJZWxzZQorCQkJYWVzX3h0c19kZWNyeXB0X3p2a25lZF96dmJiX3p2a2coCisJCQkJJmN0eC0+ Y3R4MSwgd2Fsay5zcmMudmlydC5hZGRyLAorCQkJCXdhbGsuZHN0LnZpcnQuYWRkciwgbmJ5dGVz LCByZXEtPml2KTsKKwkJa2VybmVsX3ZlY3Rvcl9lbmQoKTsKKwkJZXJyID0gc2tjaXBoZXJfd2Fs a19kb25lKCZ3YWxrLCB3YWxrLm5ieXRlcyAtIG5ieXRlcyk7CisJfQorCisJaWYgKGVyciB8fCBs aWtlbHkoIXRhaWwpKQorCQlyZXR1cm4gZXJyOworCisJLyogRG8gY2lwaGVydGV4dCBzdGVhbGlu ZyB3aXRoIHRoZSBsYXN0IGZ1bGwgYmxvY2sgYW5kIHBhcnRpYWwgYmxvY2suICovCisKKwlkc3Qg PSBzcmMgPSBzY2F0dGVyd2Fsa19mZndkKHNnX3NyYywgcmVxLT5zcmMsIHJlcS0+Y3J5cHRsZW4p OworCWlmIChyZXEtPmRzdCAhPSByZXEtPnNyYykKKwkJZHN0ID0gc2NhdHRlcndhbGtfZmZ3ZChz Z19kc3QsIHJlcS0+ZHN0LCByZXEtPmNyeXB0bGVuKTsKKworCXNrY2lwaGVyX3JlcXVlc3Rfc2V0 X2NyeXB0KHJlcSwgc3JjLCBkc3QsIEFFU19CTE9DS19TSVpFICsgdGFpbCwKKwkJCQkgICByZXEt Pml2KTsKKworCWVyciA9IHNrY2lwaGVyX3dhbGtfdmlydCgmd2FsaywgcmVxLCBmYWxzZSk7CisJ aWYgKGVycikKKwkJcmV0dXJuIGVycjsKKworCWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsKKwlpZiAo ZW5jKQorCQlhZXNfeHRzX2VuY3J5cHRfenZrbmVkX3p2YmJfenZrZygKKwkJCSZjdHgtPmN0eDEs IHdhbGsuc3JjLnZpcnQuYWRkciwKKwkJCXdhbGsuZHN0LnZpcnQuYWRkciwgd2Fsay5uYnl0ZXMs IHJlcS0+aXYpOworCWVsc2UKKwkJYWVzX3h0c19kZWNyeXB0X3p2a25lZF96dmJiX3p2a2coCisJ CQkmY3R4LT5jdHgxLCB3YWxrLnNyYy52aXJ0LmFkZHIsCisJCQl3YWxrLmRzdC52aXJ0LmFkZHIs IHdhbGsubmJ5dGVzLCByZXEtPml2KTsKKwlrZXJuZWxfdmVjdG9yX2VuZCgpOworCisJcmV0dXJu IHNrY2lwaGVyX3dhbGtfZG9uZSgmd2FsaywgMCk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9h ZXNfeHRzX2VuY3J5cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4g cmlzY3Y2NF9hZXNfeHRzX2NyeXB0KHJlcSwgdHJ1ZSk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2 NF9hZXNfeHRzX2RlY3J5cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1 cm4gcmlzY3Y2NF9hZXNfeHRzX2NyeXB0KHJlcSwgZmFsc2UpOworfQorCisvKiBBbGdvcml0aG0g ZGVmaW5pdGlvbnMgKi8KKworc3RhdGljIHN0cnVjdCBjcnlwdG9fYWxnIHJpc2N2NjRfenZrbmVk X2Flc19jaXBoZXJfYWxnID0geworCS5jcmFfZmxhZ3MgPSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVS LAorCS5jcmFfYmxvY2tzaXplID0gQUVTX0JMT0NLX1NJWkUsCisJLmNyYV9jdHhzaXplID0gc2l6 ZW9mKHN0cnVjdCBjcnlwdG9fYWVzX2N0eCksCisJLmNyYV9wcmlvcml0eSA9IDMwMCwKKwkuY3Jh X25hbWUgPSAiYWVzIiwKKwkuY3JhX2RyaXZlcl9uYW1lID0gImFlcy1yaXNjdjY0LXp2a25lZCIs CisJLmNyYV9jaXBoZXIgPSB7CisJCS5jaWFfbWluX2tleXNpemUgPSBBRVNfTUlOX0tFWV9TSVpF LAorCQkuY2lhX21heF9rZXlzaXplID0gQUVTX01BWF9LRVlfU0laRSwKKwkJLmNpYV9zZXRrZXkg PSByaXNjdjY0X2Flc19zZXRrZXlfY2lwaGVyLAorCQkuY2lhX2VuY3J5cHQgPSByaXNjdjY0X2Fl c19lbmNyeXB0LAorCQkuY2lhX2RlY3J5cHQgPSByaXNjdjY0X2Flc19kZWNyeXB0LAorCX0sCisJ LmNyYV9tb2R1bGUgPSBUSElTX01PRFVMRSwKK307CisKK3N0YXRpYyBzdHJ1Y3Qgc2tjaXBoZXJf YWxnIHJpc2N2NjRfenZrbmVkX2Flc19za2NpcGhlcl9hbGdzW10gPSB7CisJeworCQkuc2V0a2V5 ID0gcmlzY3Y2NF9hZXNfc2V0a2V5X3NrY2lwaGVyLAorCQkuZW5jcnlwdCA9IHJpc2N2NjRfYWVz X2VjYl9lbmNyeXB0LAorCQkuZGVjcnlwdCA9IHJpc2N2NjRfYWVzX2VjYl9kZWNyeXB0LAorCQku bWluX2tleXNpemUgPSBBRVNfTUlOX0tFWV9TSVpFLAorCQkubWF4X2tleXNpemUgPSBBRVNfTUFY X0tFWV9TSVpFLAorCQkud2Fsa3NpemUgPSA4ICogQUVTX0JMT0NLX1NJWkUsIC8qIG1hdGNoZXMg TE1VTD04ICovCisJCS5iYXNlID0geworCQkJLmNyYV9ibG9ja3NpemUgPSBBRVNfQkxPQ0tfU0la RSwKKwkJCS5jcmFfY3R4c2l6ZSA9IHNpemVvZihzdHJ1Y3QgY3J5cHRvX2Flc19jdHgpLAorCQkJ LmNyYV9wcmlvcml0eSA9IDMwMCwKKwkJCS5jcmFfbmFtZSA9ICJlY2IoYWVzKSIsCisJCQkuY3Jh X2RyaXZlcl9uYW1lID0gImVjYi1hZXMtcmlzY3Y2NC16dmtuZWQiLAorCQkJLmNyYV9tb2R1bGUg PSBUSElTX01PRFVMRSwKKwkJfSwKKwl9LCB7CisJCS5zZXRrZXkgPSByaXNjdjY0X2Flc19zZXRr ZXlfc2tjaXBoZXIsCisJCS5lbmNyeXB0ID0gcmlzY3Y2NF9hZXNfY2JjX2VuY3J5cHQsCisJCS5k ZWNyeXB0ID0gcmlzY3Y2NF9hZXNfY2JjX2RlY3J5cHQsCisJCS5taW5fa2V5c2l6ZSA9IEFFU19N SU5fS0VZX1NJWkUsCisJCS5tYXhfa2V5c2l6ZSA9IEFFU19NQVhfS0VZX1NJWkUsCisJCS5pdnNp emUgPSBBRVNfQkxPQ0tfU0laRSwKKwkJLmJhc2UgPSB7CisJCQkuY3JhX2Jsb2Nrc2l6ZSA9IEFF U19CTE9DS19TSVpFLAorCQkJLmNyYV9jdHhzaXplID0gc2l6ZW9mKHN0cnVjdCBjcnlwdG9fYWVz X2N0eCksCisJCQkuY3JhX3ByaW9yaXR5ID0gMzAwLAorCQkJLmNyYV9uYW1lID0gImNiYyhhZXMp IiwKKwkJCS5jcmFfZHJpdmVyX25hbWUgPSAiY2JjLWFlcy1yaXNjdjY0LXp2a25lZCIsCisJCQku Y3JhX21vZHVsZSA9IFRISVNfTU9EVUxFLAorCQl9LAorCX0KK307CisKK3N0YXRpYyBzdHJ1Y3Qg c2tjaXBoZXJfYWxnIHJpc2N2NjRfenZrbmVkX3p2a2JfYWVzX3NrY2lwaGVyX2FsZyA9IHsKKwku c2V0a2V5ID0gcmlzY3Y2NF9hZXNfc2V0a2V5X3NrY2lwaGVyLAorCS5lbmNyeXB0ID0gcmlzY3Y2 NF9hZXNfY3RyX2NyeXB0LAorCS5kZWNyeXB0ID0gcmlzY3Y2NF9hZXNfY3RyX2NyeXB0LAorCS5t aW5fa2V5c2l6ZSA9IEFFU19NSU5fS0VZX1NJWkUsCisJLm1heF9rZXlzaXplID0gQUVTX01BWF9L RVlfU0laRSwKKwkuaXZzaXplID0gQUVTX0JMT0NLX1NJWkUsCisJLmNodW5rc2l6ZSA9IEFFU19C TE9DS19TSVpFLAorCS53YWxrc2l6ZSA9IDQgKiBBRVNfQkxPQ0tfU0laRSwgLyogbWF0Y2hlcyBM TVVMPTQgKi8KKwkuYmFzZSA9IHsKKwkJLmNyYV9ibG9ja3NpemUgPSAxLAorCQkuY3JhX2N0eHNp emUgPSBzaXplb2Yoc3RydWN0IGNyeXB0b19hZXNfY3R4KSwKKwkJLmNyYV9wcmlvcml0eSA9IDMw MCwKKwkJLmNyYV9uYW1lID0gImN0cihhZXMpIiwKKwkJLmNyYV9kcml2ZXJfbmFtZSA9ICJjdHIt YWVzLXJpc2N2NjQtenZrbmVkLXp2a2IiLAorCQkuY3JhX21vZHVsZSA9IFRISVNfTU9EVUxFLAor CX0sCit9OworCitzdGF0aWMgc3RydWN0IHNrY2lwaGVyX2FsZyByaXNjdjY0X3p2a25lZF96dmJi X3p2a2dfYWVzX3NrY2lwaGVyX2FsZyA9IHsKKwkuc2V0a2V5ID0gcmlzY3Y2NF9hZXNfeHRzX3Nl dGtleSwKKwkuZW5jcnlwdCA9IHJpc2N2NjRfYWVzX3h0c19lbmNyeXB0LAorCS5kZWNyeXB0ID0g cmlzY3Y2NF9hZXNfeHRzX2RlY3J5cHQsCisJLm1pbl9rZXlzaXplID0gMiAqIEFFU19NSU5fS0VZ X1NJWkUsCisJLm1heF9rZXlzaXplID0gMiAqIEFFU19NQVhfS0VZX1NJWkUsCisJLml2c2l6ZSA9 IEFFU19CTE9DS19TSVpFLAorCS5jaHVua3NpemUgPSBBRVNfQkxPQ0tfU0laRSwKKwkud2Fsa3Np emUgPSA0ICogQUVTX0JMT0NLX1NJWkUsIC8qIG1hdGNoZXMgTE1VTD00ICovCisJLmJhc2UgPSB7 CisJCS5jcmFfYmxvY2tzaXplID0gQUVTX0JMT0NLX1NJWkUsCisJCS5jcmFfY3R4c2l6ZSA9IHNp emVvZihzdHJ1Y3QgcmlzY3Y2NF9hZXNfeHRzX2N0eCksCisJCS5jcmFfcHJpb3JpdHkgPSAzMDAs CisJCS5jcmFfbmFtZSA9ICJ4dHMoYWVzKSIsCisJCS5jcmFfZHJpdmVyX25hbWUgPSAieHRzLWFl cy1yaXNjdjY0LXp2a25lZC16dmJiLXp2a2ciLAorCQkuY3JhX21vZHVsZSA9IFRISVNfTU9EVUxF LAorCX0sCit9OworCitzdGF0aWMgaW5saW5lIGJvb2wgcmlzY3Y2NF9hZXNfeHRzX3N1cHBvcnRl ZCh2b2lkKQoreworCXJldHVybiByaXNjdl9pc2FfZXh0ZW5zaW9uX2F2YWlsYWJsZShOVUxMLCBa VkJCKSAmJgorCSAgICAgICByaXNjdl9pc2FfZXh0ZW5zaW9uX2F2YWlsYWJsZShOVUxMLCBaVktH KSAmJgorCSAgICAgICByaXNjdl92ZWN0b3JfdmxlbigpIDwgMjA0OCAvKiBJbXBsZW1lbnRhdGlv biBsaW1pdGF0aW9uICovOworfQorCitzdGF0aWMgaW50IF9faW5pdCByaXNjdjY0X2Flc19tb2Rf aW5pdCh2b2lkKQoreworCWludCBlcnIgPSAtRU5PREVWOworCisJaWYgKHJpc2N2X2lzYV9leHRl bnNpb25fYXZhaWxhYmxlKE5VTEwsIFpWS05FRCkgJiYKKwkgICAgcmlzY3ZfdmVjdG9yX3ZsZW4o KSA+PSAxMjgpIHsKKwkJZXJyID0gY3J5cHRvX3JlZ2lzdGVyX2FsZygmcmlzY3Y2NF96dmtuZWRf YWVzX2NpcGhlcl9hbGcpOworCQlpZiAoZXJyKQorCQkJcmV0dXJuIGVycjsKKworCQllcnIgPSBj cnlwdG9fcmVnaXN0ZXJfc2tjaXBoZXJzKAorCQkJcmlzY3Y2NF96dmtuZWRfYWVzX3NrY2lwaGVy X2FsZ3MsCisJCQlBUlJBWV9TSVpFKHJpc2N2NjRfenZrbmVkX2Flc19za2NpcGhlcl9hbGdzKSk7 CisJCWlmIChlcnIpCisJCQlnb3RvIHVucmVnaXN0ZXJfenZrbmVkX2NpcGhlcl9hbGc7CisKKwkJ aWYgKHJpc2N2X2lzYV9leHRlbnNpb25fYXZhaWxhYmxlKE5VTEwsIFpWS0IpKSB7CisJCQllcnIg PSBjcnlwdG9fcmVnaXN0ZXJfc2tjaXBoZXIoCisJCQkJJnJpc2N2NjRfenZrbmVkX3p2a2JfYWVz X3NrY2lwaGVyX2FsZyk7CisJCQlpZiAoZXJyKQorCQkJCWdvdG8gdW5yZWdpc3Rlcl96dmtuZWRf c2tjaXBoZXJfYWxnczsKKwkJfQorCisJCWlmIChyaXNjdjY0X2Flc194dHNfc3VwcG9ydGVkKCkp IHsKKwkJCWVyciA9IGNyeXB0b19yZWdpc3Rlcl9za2NpcGhlcigKKwkJCQkmcmlzY3Y2NF96dmtu ZWRfenZiYl96dmtnX2Flc19za2NpcGhlcl9hbGcpOworCQkJaWYgKGVycikKKwkJCQlnb3RvIHVu cmVnaXN0ZXJfenZrbmVkX3p2a2Jfc2tjaXBoZXJfYWxnOworCQl9CisJfQorCisJcmV0dXJuIGVy cjsKKwordW5yZWdpc3Rlcl96dmtuZWRfenZrYl9za2NpcGhlcl9hbGc6CisJaWYgKHJpc2N2X2lz YV9leHRlbnNpb25fYXZhaWxhYmxlKE5VTEwsIFpWS0IpKQorCQljcnlwdG9fdW5yZWdpc3Rlcl9z a2NpcGhlcigmcmlzY3Y2NF96dmtuZWRfenZrYl9hZXNfc2tjaXBoZXJfYWxnKTsKK3VucmVnaXN0 ZXJfenZrbmVkX3NrY2lwaGVyX2FsZ3M6CisJY3J5cHRvX3VucmVnaXN0ZXJfc2tjaXBoZXJzKHJp c2N2NjRfenZrbmVkX2Flc19za2NpcGhlcl9hbGdzLAorCQkJCSAgICBBUlJBWV9TSVpFKHJpc2N2 NjRfenZrbmVkX2Flc19za2NpcGhlcl9hbGdzKSk7Cit1bnJlZ2lzdGVyX3p2a25lZF9jaXBoZXJf YWxnOgorCWNyeXB0b191bnJlZ2lzdGVyX2FsZygmcmlzY3Y2NF96dmtuZWRfYWVzX2NpcGhlcl9h bGcpOworCXJldHVybiBlcnI7Cit9CisKK3N0YXRpYyB2b2lkIF9fZXhpdCByaXNjdjY0X2Flc19t b2RfZXhpdCh2b2lkKQoreworCWlmIChyaXNjdjY0X2Flc194dHNfc3VwcG9ydGVkKCkpCisJCWNy eXB0b191bnJlZ2lzdGVyX3NrY2lwaGVyKCZyaXNjdjY0X3p2a25lZF96dmJiX3p2a2dfYWVzX3Nr Y2lwaGVyX2FsZyk7CisJaWYgKHJpc2N2X2lzYV9leHRlbnNpb25fYXZhaWxhYmxlKE5VTEwsIFpW S0IpKQorCQljcnlwdG9fdW5yZWdpc3Rlcl9za2NpcGhlcigmcmlzY3Y2NF96dmtuZWRfenZrYl9h ZXNfc2tjaXBoZXJfYWxnKTsKKwljcnlwdG9fdW5yZWdpc3Rlcl9za2NpcGhlcnMocmlzY3Y2NF96 dmtuZWRfYWVzX3NrY2lwaGVyX2FsZ3MsCisJCQkJICAgIEFSUkFZX1NJWkUocmlzY3Y2NF96dmtu ZWRfYWVzX3NrY2lwaGVyX2FsZ3MpKTsKKwljcnlwdG9fdW5yZWdpc3Rlcl9hbGcoJnJpc2N2NjRf enZrbmVkX2Flc19jaXBoZXJfYWxnKTsKK30KKworbW9kdWxlX2luaXQocmlzY3Y2NF9hZXNfbW9k X2luaXQpOworbW9kdWxlX2V4aXQocmlzY3Y2NF9hZXNfbW9kX2V4aXQpOworCitNT0RVTEVfREVT Q1JJUFRJT04oIkFFUy1FQ0IvQ0JDL0NUUi9YVFMgKFJJU0MtViBhY2NlbGVyYXRlZCkiKTsKK01P RFVMRV9BVVRIT1IoIkplcnJ5IFNoaWggPGplcnJ5LnNoaWhAc2lmaXZlLmNvbT4iKTsKK01PRFVM RV9MSUNFTlNFKCJHUEwiKTsKK01PRFVMRV9BTElBU19DUllQVE8oImFlcyIpOworTU9EVUxFX0FM SUFTX0NSWVBUTygiZWNiKGFlcykiKTsKK01PRFVMRV9BTElBU19DUllQVE8oImNiYyhhZXMpIik7 CitNT0RVTEVfQUxJQVNfQ1JZUFRPKCJjdHIoYWVzKSIpOworTU9EVUxFX0FMSUFTX0NSWVBUTygi eHRzKGFlcykiKTsKZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2 a25lZC16dmJiLXp2a2cuUyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC16 dmJiLXp2a2cuUwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAwLi4xNDZm YzljZmIyNjhkCi0tLSAvZGV2L251bGwKKysrIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2 NjQtenZrbmVkLXp2YmItenZrZy5TCkBAIC0wLDAgKzEsMzEyIEBACisvKiBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogQXBhY2hlLTIuMCBPUiBCU0QtMi1DbGF1c2UgKi8KKy8vCisvLyBUaGlzIGZp bGUgaXMgZHVhbC1saWNlbnNlZCwgbWVhbmluZyB0aGF0IHlvdSBjYW4gdXNlIGl0IHVuZGVyIHlv dXIKKy8vIGNob2ljZSBvZiBlaXRoZXIgb2YgdGhlIGZvbGxvd2luZyB0d28gbGljZW5zZXM6Cisv LworLy8gQ29weXJpZ2h0IDIwMjMgVGhlIE9wZW5TU0wgUHJvamVjdCBBdXRob3JzLiBBbGwgUmln aHRzIFJlc2VydmVkLgorLy8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSAy LjAgKHRoZSAiTGljZW5zZSIpLiBZb3UgY2FuIG9idGFpbgorLy8gYSBjb3B5IGluIHRoZSBmaWxl IExJQ0VOU0UgaW4gdGhlIHNvdXJjZSBkaXN0cmlidXRpb24gb3IgYXQKKy8vIGh0dHBzOi8vd3d3 Lm9wZW5zc2wub3JnL3NvdXJjZS9saWNlbnNlLmh0bWwKKy8vCisvLyBvcgorLy8KKy8vIENvcHly aWdodCAoYykgMjAyMywgSmVycnkgU2hpaCA8amVycnkuc2hpaEBzaWZpdmUuY29tPgorLy8gQ29w eXJpZ2h0IDIwMjQgR29vZ2xlIExMQworLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vCisvLyBS ZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9y IHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRo ZSBmb2xsb3dpbmcgY29uZGl0aW9ucworLy8gYXJlIG1ldDoKKy8vIDEuIFJlZGlzdHJpYnV0aW9u cyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyAgICBu b3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWlt ZXIuCisvLyAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2Ug dGhlIGFib3ZlIGNvcHlyaWdodAorLy8gICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9u cyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQorLy8gICAgZG9jdW1lbnRhdGlv biBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4K Ky8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVS UyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVE IFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJ RUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBB UlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENP UFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVD VCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNF UVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9D VVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8v IERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVT RUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFD VCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9S IE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElT IFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFN QUdFLgorCisvLyBUaGUgZ2VuZXJhdGVkIGNvZGUgb2YgdGhpcyBmaWxlIGRlcGVuZHMgb24gdGhl IGZvbGxvd2luZyBSSVNDLVYgZXh0ZW5zaW9uczoKKy8vIC0gUlY2NEkKKy8vIC0gUklTQy1WIFZl Y3RvciAoJ1YnKSB3aXRoIFZMRU4gPj0gMTI4ICYmIFZMRU4gPCAyMDQ4CisvLyAtIFJJU0MtViBW ZWN0b3IgQUVTIGJsb2NrIGNpcGhlciBleHRlbnNpb24gKCdadmtuZWQnKQorLy8gLSBSSVNDLVYg VmVjdG9yIEJpdC1tYW5pcHVsYXRpb24gZXh0ZW5zaW9uICgnWnZiYicpCisvLyAtIFJJU0MtViBW ZWN0b3IgR0NNL0dNQUMgZXh0ZW5zaW9uICgnWnZrZycpCisKKyNpbmNsdWRlIDxsaW51eC9saW5r YWdlLmg+CisKKy50ZXh0Cisub3B0aW9uIGFyY2gsICt6dmtuZWQsICt6dmJiLCArenZrZworCisj aW5jbHVkZSAiYWVzLW1hY3Jvcy5TIgorCisjZGVmaW5lIEtFWVAJCWEwCisjZGVmaW5lIElOUAkJ YTEKKyNkZWZpbmUgT1VUUAkJYTIKKyNkZWZpbmUgTEVOCQlhMworI2RlZmluZSBUV0VBS1AJCWE0 CisKKyNkZWZpbmUgTEVOMzIJCWE1CisjZGVmaW5lIFRBSUxfTEVOCWE2CisjZGVmaW5lIFZMCQlh NworI2RlZmluZSBWTE1BWAkJdDQKKworLy8gdjEtdjE1IGNvbnRhaW4gdGhlIEFFUyByb3VuZCBr ZXlzLCBidXQgdGhleSBhcmUgdXNlZCBmb3IgdGVtcG9yYXJpZXMgYmVmb3JlCisvLyB0aGUgQUVT IHJvdW5kIGtleXMgaGF2ZSBiZWVuIGxvYWRlZC4KKyNkZWZpbmUgVFdFQUtTCQl2MTYJLy8gTE1V TD00IChtb3N0IG9mIHRoZSB0aW1lKQorI2RlZmluZSBUV0VBS1NfQlJFVgl2MjAJLy8gTE1VTD00 IChtb3N0IG9mIHRoZSB0aW1lKQorI2RlZmluZSBNVUxUU19CUkVWCXYyNAkvLyBMTVVMPTQgKG1v c3Qgb2YgdGhlIHRpbWUpCisjZGVmaW5lIFRNUDAJCXYyOAorI2RlZmluZSBUTVAxCQl2MjkKKyNk ZWZpbmUgVE1QMgkJdjMwCisjZGVmaW5lIFRNUDMJCXYzMQorCisvLyB4dHNfaW5pdCBpbml0aWFs aXplcyB0aGUgZm9sbG93aW5nIHZhbHVlczoKKy8vCisvLwlUV0VBS1M6IE4gMTI4LWJpdCB0d2Vh a3MgVCooeF5pKSBmb3IgaSBpbiAwLi4oTiAtIDEpCisvLwlUV0VBS1NfQlJFVjogc2FtZSBhcyBU V0VBS1MsIGJ1dCBiaXQtcmV2ZXJzZWQKKy8vCU1VTFRTX0JSRVY6IE4gMTI4LWJpdCB2YWx1ZXMg eF5OLCBiaXQtcmV2ZXJzZWQuICBPbmx5IGlmIE4gPiAxLgorLy8KKy8vIE4gaXMgdGhlIG1heGlt dW0gbnVtYmVyIG9mIGJsb2NrcyB0aGF0IHdpbGwgYmUgcHJvY2Vzc2VkIHBlciBsb29wIGl0ZXJh dGlvbiwKKy8vIGNvbXB1dGVkIHVzaW5nIHZzZXR2bGkuCisvLworLy8gVGhlIGZpZWxkIGNvbnZl bnRpb24gdXNlZCBieSBYVFMgaXMgdGhlIHNhbWUgYXMgdGhhdCBvZiBHSEFTSCwgYnV0IHdpdGgg dGhlCisvLyBiaXRzIHJldmVyc2VkIHdpdGhpbiBlYWNoIGJ5dGUuICBUaGUgenZrZyBleHRlbnNp b24gcHJvdmlkZXMgdGhlIHZnbXVsCisvLyBpbnN0cnVjdGlvbiB3aGljaCBkb2VzIG11bHRpcGxp Y2F0aW9uIGluIHRoaXMgZmllbGQuICBUaGVyZWZvcmUsIGZvciB0d2VhaworLy8gY29tcHV0YXRp b24gd2UgdXNlIHZnbXVsIHRvIGRvIG11bHRpcGxpY2F0aW9ucyBpbiBwYXJhbGxlbCwgaW5zdGVh ZCBvZgorLy8gc2VyaWFsbHkgbXVsdGlwbHlpbmcgYnkgeCB1c2luZyBzaGlmdGluZyt4b3Jpbmcu ICBOb3RlIHRoYXQgZm9yIHRoaXMgdG8gd29yaywKKy8vIHRoZSBpbnB1dHMgYW5kIG91dHB1dHMg dG8gdmdtdWwgbXVzdCBiZSBiaXQtcmV2ZXJzZWQgKHdlIGRvIGl0IHdpdGggdmJyZXY4KS4KKy5t YWNybwl4dHNfaW5pdAorCisJLy8gTG9hZCB0aGUgZmlyc3QgdHdlYWsgVC4KKwl2c2V0aXZsaQl6 ZXJvLCA0LCBlMzIsIG0xLCB0YSwgbWEKKwl2bGUzMi52CQlUV0VBS1MsIChUV0VBS1ApCisKKwkv LyBJZiB0aGVyZSdzIG9ubHkgb25lIGJsb2NrIChvciBubyBibG9ja3MgYXQgYWxsKSwgdGhlbiBz a2lwIHRoZSB0d2VhaworCS8vIHNlcXVlbmNlIGNvbXB1dGF0aW9uIGJlY2F1c2UgKGF0IG1vc3Qp IFQgaXRzZWxmIGlzIG5lZWRlZC4KKwlsaQkJdDAsIDE2CisJYmxlCQlMRU4sIHQwLCAuTGluaXRf c2luZ2xlX2Jsb2NrXEAKKworCS8vIFNhdmUgYSBjb3B5IG9mIFQgYml0LXJldmVyc2VkIGluIHYx Mi4KKwl2YnJldjgudgl2MTIsIFRXRUFLUworCisJLy8KKwkvLyBHZW5lcmF0ZSB4XmkgZm9yIGkg aW4gMC4uKE4gLSAxKSwgaS5lLiAxMjgtYml0IHZhbHVlcyAxIDw8IGkgYXNzdW1pbmcKKwkvLyB0 aGF0IE4gPD0gMTI4LiAgVGhvdWdoLCB0aGlzIGNvZGUgYWN0dWFsbHkgcmVxdWlyZXMgTiA8IDY0 IChvcgorCS8vIGVxdWl2YWxlbnRseSBWTEVOIDwgMjA0OCkgZHVlIHRvIHRoZSB1c2Ugb2YgNjQt Yml0IGludGVybWVkaWF0ZQorCS8vIHZhbHVlcyBoZXJlIGFuZCBpbiB0aGUgeF5OIGNvbXB1dGF0 aW9uIGxhdGVyLgorCS8vCisJdnNldHZsaQkJVkwsIExFTjMyLCBlMzIsIG00LCB0YSwgbWEKKwlz cmxpCQl0MCwgVkwsIDIJLy8gdDAgPSBOIChudW0gYmxvY2tzKQorCS8vIEdlbmVyYXRlIHR3byBz ZXF1ZW5jZXMsIGVhY2ggd2l0aCBOIDMyLWJpdCB2YWx1ZXM6CisJLy8gdjA9WzEsIDEsIDEsIC4u Ll0gYW5kIHYxPVswLCAxLCAyLCAuLi5dLgorCXZzZXR2bGkJCXplcm8sIHQwLCBlMzIsIG0xLCB0 YSwgbWEKKwl2bXYudi5pCQl2MCwgMQorCXZpZC52CQl2MQorCS8vIFVzZSB2emV4dCB0byB6ZXJv LWV4dGVuZCB0aGUgc2VxdWVuY2VzIHRvIDY0IGJpdHMuICBSZWludGVycHJldCB0aGVtCisJLy8g YXMgdHdvIHNlcXVlbmNlcywgZWFjaCB3aXRoIDIqTiAzMi1iaXQgdmFsdWVzOgorCS8vIHYyPVsx LCAwLCAxLCAwLCAxLCAwLCAuLi5dIGFuZCB2ND1bMCwgMCwgMSwgMCwgMiwgMCwgLi4uXS4KKwl2 c2V0dmxpCQl6ZXJvLCB0MCwgZTY0LCBtMiwgdGEsIG1hCisJdnpleHQudmYyCXYyLCB2MAorCXZ6 ZXh0LnZmMgl2NCwgdjEKKwlzbGxpCQl0MSwgdDAsIDEJLy8gdDEgPSAyKk4KKwl2c2V0dmxpCQl6 ZXJvLCB0MSwgZTMyLCBtMiwgdGEsIG1hCisJLy8gVXNlIHZ3c2xsIHRvIGNvbXB1dGUgWzE8PDAs IDA8PDAsIDE8PDEsIDA8PDAsIDE8PDIsIDA8PDAsIC4uLl0sCisJLy8gd2lkZW5pbmcgdG8gNjQg Yml0cyBwZXIgZWxlbWVudC4gIFdoZW4gcmVpbnRlcnByZXRlZCBhcyBOIDEyOC1iaXQKKwkvLyB2 YWx1ZXMsIHRoaXMgaXMgdGhlIG5lZWRlZCBzZXF1ZW5jZSBvZiAxMjgtYml0IHZhbHVlcyAxIDw8 IGkgKHheaSkuCisJdndzbGwudnYJdjgsIHYyLCB2NAorCisJLy8gQ29weSB0aGUgYml0LXJldmVy c2VkIFQgdG8gYWxsIE4gZWxlbWVudHMgb2YgVFdFQUtTX0JSRVYsIHRoZW4KKwkvLyBtdWx0aXBs eSBieSB4XmkuICBUaGlzIGdpdmVzIHRoZSBzZXF1ZW5jZSBUKih4XmkpLCBiaXQtcmV2ZXJzZWQu CisJdnNldHZsaQkJemVybywgTEVOMzIsIGUzMiwgbTQsIHRhLCBtYQorCXZtdi52LmkJCVRXRUFL U19CUkVWLCAwCisJdmFlc3oudnMJVFdFQUtTX0JSRVYsIHYxMgorCXZicmV2OC52CXY4LCB2OAor CXZnbXVsLnZ2CVRXRUFLU19CUkVWLCB2OAorCisJLy8gU2F2ZSBhIGNvcHkgb2YgdGhlIHNlcXVl bmNlIFQqKHheaSkgd2l0aCB0aGUgYml0IHJldmVyc2FsIHVuZG9uZS4KKwl2YnJldjgudglUV0VB S1MsIFRXRUFLU19CUkVWCisKKwkvLyBHZW5lcmF0ZSBOIGNvcGllcyBvZiB4Xk4sIGkuZS4gMTI4 LWJpdCB2YWx1ZXMgMSA8PCBOLCBiaXQtcmV2ZXJzZWQuCisJbGkJCXQxLCAxCisJc2xsCQl0MSwg dDEsIHQwCS8vIHQxID0gMSA8PCBOCisJdnNldGl2bGkJemVybywgMiwgZTY0LCBtMSwgdGEsIG1h CisJdm12LnYuaQkJdjAsIDAKKwl2c2V0aXZsaQl6ZXJvLCAxLCBlNjQsIG0xLCB0dSwgbWEKKwl2 bXYudi54CQl2MCwgdDEKKwl2YnJldjgudgl2MCwgdjAKKwl2c2V0dmxpCQl6ZXJvLCBMRU4zMiwg ZTMyLCBtNCwgdGEsIG1hCisJdm12LnYuaQkJTVVMVFNfQlJFViwgMAorCXZhZXN6LnZzCU1VTFRT X0JSRVYsIHYwCisKKwlqCQkuTGluaXRfZG9uZVxACisKKy5MaW5pdF9zaW5nbGVfYmxvY2tcQDoK Kwl2YnJldjgudglUV0VBS1NfQlJFViwgVFdFQUtTCisuTGluaXRfZG9uZVxAOgorLmVuZG0KKwor Ly8gU2V0IHRoZSBmaXJzdCAxMjggYml0cyBvZiBNVUxUU19CUkVWIHRvIDB4NDAsIGkuZS4gJ3gn IGJpdC1yZXZlcnNlZC4gIFRoaXMgaXMKKy8vIHRoZSBtdWx0aXBsaWVyIHJlcXVpcmVkIHRvIGFk dmFuY2UgdGhlIHR3ZWFrIGJ5IG9uZS4KKy5tYWNybwlsb2FkX3gKKwlsaQkJdDAsIDB4NDAKKwl2 c2V0aXZsaQl6ZXJvLCA0LCBlMzIsIG0xLCB0YSwgbWEKKwl2bXYudi5pCQlNVUxUU19CUkVWLCAw CisJdnNldGl2bGkJemVybywgMSwgZTgsIG0xLCB0dSwgbWEKKwl2bXYudi54CQlNVUxUU19CUkVW LCB0MAorLmVuZG0KKworLm1hY3JvCV9fYWVzX3h0c19jcnlwdAllbmMsIGtleWxlbgorCS8vIFdp dGggMTYgPCBsZW4gPD0gMzEsIHRoZXJlJ3Mgbm8gbWFpbiBsb29wLCBqdXN0IGNpcGhlcnRleHQg c3RlYWxpbmcuCisJYmVxegkJTEVOMzIsIC5MY3RzX3dpdGhvdXRfbWFpbl9sb29wXEAKKworCXZz ZXR2bGkJCVZMTUFYLCB6ZXJvLCBlMzIsIG00LCB0YSwgbWEKKzE6CisJdnNldHZsaQkJVkwsIExF TjMyLCBlMzIsIG00LCB0YSwgbWEKKzI6CisJLy8gRW5jcnlwdCBvciBkZWNyeXB0IFZMLzQgYmxv Y2tzLgorCXZsZTMyLnYJCVRNUDAsIChJTlApCisJdnhvci52dgkJVE1QMCwgVE1QMCwgVFdFQUtT CisJYWVzX2NyeXB0CVRNUDAsIFxlbmMsIFxrZXlsZW4KKwl2eG9yLnZ2CQlUTVAwLCBUTVAwLCBU V0VBS1MKKwl2c2UzMi52CQlUTVAwLCAoT1VUUCkKKworCS8vIFVwZGF0ZSB0aGUgcG9pbnRlcnMg YW5kIHRoZSByZW1haW5pbmcgbGVuZ3RoLgorCXNsbGkJCXQwLCBWTCwgMgorCWFkZAkJSU5QLCBJ TlAsIHQwCisJYWRkCQlPVVRQLCBPVVRQLCB0MAorCXN1YgkJTEVOMzIsIExFTjMyLCBWTAorCisJ Ly8gQ2hlY2sgd2hldGhlciBtb3JlIGJsb2NrcyByZW1haW4uCisJYmVxegkJTEVOMzIsIC5MbWFp bl9sb29wX2RvbmVcQAorCisJLy8gQ29tcHV0ZSB0aGUgbmV4dCBzZXF1ZW5jZSBvZiB0d2Vha3Mg YnkgbXVsdGlwbHlpbmcgdGhlIHByZXZpb3VzCisJLy8gc2VxdWVuY2UgYnkgeF5OLiAgU3RvcmUg dGhlIHJlc3VsdCBpbiBib3RoIGJpdC1yZXZlcnNlZCBvcmRlciBhbmQKKwkvLyByZWd1bGFyIG9y ZGVyIChpLmUuIHdpdGggdGhlIGJpdCByZXZlcnNhbCB1bmRvbmUpLgorCXZnbXVsLnZ2CVRXRUFL U19CUkVWLCBNVUxUU19CUkVWCisJdmJyZXY4LnYJVFdFQUtTLCBUV0VBS1NfQlJFVgorCisJLy8g U2luY2Ugd2UgY29tcHV0ZSB0aGUgdHdlYWsgbXVsdGlwbGllcnMgeF5OIGluIGFkdmFuY2UsIHdl IHJlcXVpcmUKKwkvLyB0aGF0IGVhY2ggaXRlcmF0aW9uIHByb2Nlc3MgdGhlIHNhbWUgbGVuZ3Ro IGV4Y2VwdCBwb3NzaWJseSB0aGUgbGFzdC4KKwkvLyBUaGlzIGNvbmZsaWN0cyBzbGlnaHRseSB3 aXRoIHRoZSBiZWhhdmlvciBhbGxvd2VkIGJ5IFJJU0MtViBWZWN0b3IKKwkvLyBFeHRlbnNpb24s IHdoZXJlIENQVXMgY2FuIHNlbGVjdCBhIGxvd2VyIGxlbmd0aCBmb3IgYm90aCBvZiB0aGUgbGFz dAorCS8vIHR3byBpdGVyYXRpb25zLiAgRS5nLiwgdmwgbWlnaHQgdGFrZSB0aGUgc2VxdWVuY2Ug b2YgdmFsdWVzCisJLy8gWzE2LCAxNiwgMTYsIDEyLCAxMl0sIHdoZXJlYXMgd2UgbmVlZCBbMTYs IDE2LCAxNiwgMTYsIDhdIHNvIHRoYXQgd2UKKwkvLyBjYW4gdXNlIHheNCBhZ2FpbiBpbnN0ZWFk IG9mIGNvbXB1dGluZyB4XjMuICBUaGVyZWZvcmUsIHdlIGV4cGxpY2l0bHkKKwkvLyBrZWVwIHRo ZSB2bCBhdCBWTE1BWCBpZiB0aGVyZSBpcyBhdCBsZWFzdCBWTE1BWCByZW1haW5pbmcuCisJYmdl CQlMRU4zMiwgVkxNQVgsIDJiCisJagkJMWIKKworLkxtYWluX2xvb3BfZG9uZVxAOgorCWxvYWRf eAorCisJLy8gQ29tcHV0ZSB0aGUgbmV4dCB0d2Vhay4KKwlhZGRpCQl0MCwgVkwsIC00CisJdnNl dGl2bGkJemVybywgNCwgZTMyLCBtNCwgdGEsIG1hCisJdnNsaWRlZG93bi52eAlUV0VBS1NfQlJF ViwgVFdFQUtTX0JSRVYsIHQwCS8vIEV4dHJhY3QgbGFzdCB0d2VhaworCXZzZXRpdmxpCXplcm8s IDQsIGUzMiwgbTEsIHRhLCBtYQorCXZnbXVsLnZ2CVRXRUFLU19CUkVWLCBNVUxUU19CUkVWCQkv LyBBZHZhbmNlIHRvIG5leHQgdHdlYWsKKworCWJuZXoJCVRBSUxfTEVOLCAuTGN0c1xACisKKwkv LyBVcGRhdGUgKlRXRUFLUCB0byBjb250YWluIHRoZSBuZXh0IHR3ZWFrLgorCXZicmV2OC52CVRX RUFLUywgVFdFQUtTX0JSRVYKKwl2c2UzMi52CQlUV0VBS1MsIChUV0VBS1ApCisJcmV0CisKKy5M Y3RzX3dpdGhvdXRfbWFpbl9sb29wXEA6CisJbG9hZF94CisuTGN0c1xAOgorCS8vIFRXRUFLU19C UkVWIG5vdyBjb250YWlucyB0aGUgbmV4dCB0d2Vhay4gIENvbXB1dGUgdGhlIG9uZSBhZnRlciB0 aGF0LgorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwgbTEsIHRhLCBtYQorCXZtdi52LnYJCVRNUDAs IFRXRUFLU19CUkVWCisJdmdtdWwudnYJVE1QMCwgTVVMVFNfQlJFVgorCS8vIFVuZG8gdGhlIGJp dCByZXZlcnNhbCBvZiB0aGUgbmV4dCB0d28gdHdlYWtzIGFuZCBzdG9yZSB0aGVtIGluIFRNUDEK KwkvLyBhbmQgVE1QMiwgc3VjaCB0aGF0IFRNUDEgaXMgdGhlIGZpcnN0IG5lZWRlZCBhbmQgVE1Q MiB0aGUgc2Vjb25kLgorLmlmIFxlbmMKKwl2YnJldjgudglUTVAxLCBUV0VBS1NfQlJFVgorCXZi cmV2OC52CVRNUDIsIFRNUDAKKy5lbHNlCisJdmJyZXY4LnYJVE1QMSwgVE1QMAorCXZicmV2OC52 CVRNUDIsIFRXRUFLU19CUkVWCisuZW5kaWYKKworCS8vIEVuY3J5cHQvZGVjcnlwdCB0aGUgbGFz dCBmdWxsIGJsb2NrLgorCXZsZTMyLnYJCVRNUDAsIChJTlApCisJdnhvci52dgkJVE1QMCwgVE1Q MCwgVE1QMQorCWFlc19jcnlwdAlUTVAwLCBcZW5jLCBca2V5bGVuCisJdnhvci52dgkJVE1QMCwg VE1QMCwgVE1QMQorCisJLy8gU3dhcCB0aGUgZmlyc3QgVEFJTF9MRU4gYnl0ZXMgb2YgdGhlIGFi b3ZlIHJlc3VsdCB3aXRoIHRoZSB0YWlsLgorCS8vIE5vdGUgdGhhdCB0byBzdXBwb3J0IGluLXBs YWNlIGVuY3J5cHRpb24vZGVjcnlwdGlvbiwgdGhlIGxvYWQgZnJvbQorCS8vIHRoZSBpbnB1dCB0 YWlsIG11c3QgaGFwcGVuIGJlZm9yZSB0aGUgc3RvcmUgdG8gdGhlIG91dHB1dCB0YWlsLgorCWFk ZGkJCXQwLCBJTlAsIDE2CisJYWRkaQkJdDEsIE9VVFAsIDE2CisJdm12LnYudgkJVE1QMywgVE1Q MAorCXZzZXR2bGkJCXplcm8sIFRBSUxfTEVOLCBlOCwgbTEsIHR1LCBtYQorCXZsZTgudgkJVE1Q MCwgKHQwKQorCXZzZTgudgkJVE1QMywgKHQxKQorCisJLy8gRW5jcnlwdC9kZWNyeXB0IGFnYWlu IGFuZCBzdG9yZSB0aGUgbGFzdCBmdWxsIGJsb2NrLgorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwg bTEsIHRhLCBtYQorCXZ4b3IudnYJCVRNUDAsIFRNUDAsIFRNUDIKKwlhZXNfY3J5cHQJVE1QMCwg XGVuYywgXGtleWxlbgorCXZ4b3IudnYJCVRNUDAsIFRNUDAsIFRNUDIKKwl2c2UzMi52CQlUTVAw LCAoT1VUUCkKKworCXJldAorLmVuZG0KKworLm1hY3JvCWFlc194dHNfY3J5cHQJZW5jCisKKwkv LyBDaGVjayB3aGV0aGVyIHRoZSBsZW5ndGggaXMgYSBtdWx0aXBsZSBvZiB0aGUgQUVTIGJsb2Nr IHNpemUuCisJYW5kaQkJVEFJTF9MRU4sIExFTiwgMTUKKwliZXF6CQlUQUlMX0xFTiwgMWYKKwor CS8vIFRoZSBsZW5ndGggaXNuJ3QgYSBtdWx0aXBsZSBvZiB0aGUgQUVTIGJsb2NrIHNpemUsIHNv IGNpcGhlcnRleHQKKwkvLyBzdGVhbGluZyB3aWxsIGJlIHJlcXVpcmVkLiAgQ2lwaGVydGV4dCBz dGVhbGluZyBpbnZvbHZlcyBzcGVjaWFsCisJLy8gaGFuZGxpbmcgb2YgdGhlIHBhcnRpYWwgYmxv Y2sgYW5kIHRoZSBsYXN0IGZ1bGwgYmxvY2ssIHNvIHN1YnRyYWN0CisJLy8gdGhlIGxlbmd0aCBv ZiBib3RoIGZyb20gdGhlIGxlbmd0aCB0byBiZSBwcm9jZXNzZWQgaW4gdGhlIG1haW4gbG9vcC4K KwlzdWIJCUxFTiwgTEVOLCBUQUlMX0xFTgorCWFkZGkJCUxFTiwgTEVOLCAtMTYKKzE6CisJc3Js aQkJTEVOMzIsIExFTiwgMgorCS8vIExFTiBhbmQgTEVOMzIgbm93IGNvbnRhaW4gdGhlIHRvdGFs IGxlbmd0aCBvZiB0aGUgYmxvY2tzIHRoYXQgd2lsbCBiZQorCS8vIHByb2Nlc3NlZCBpbiB0aGUg bWFpbiBsb29wLCBpbiBieXRlcyBhbmQgMzItYml0IHdvcmRzIHJlc3BlY3RpdmVseS4KKworCXh0 c19pbml0CisJYWVzX2JlZ2luCUtFWVAsIDEyOGYsIDE5MmYKKwlfX2Flc194dHNfY3J5cHQJXGVu YywgMjU2CisxMjg6CisJX19hZXNfeHRzX2NyeXB0CVxlbmMsIDEyOAorMTkyOgorCV9fYWVzX3h0 c19jcnlwdAlcZW5jLCAxOTIKKy5lbmRtCisKKy8vIHZvaWQgYWVzX3h0c19lbmNyeXB0X3p2a25l ZF96dmJiX3p2a2coY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4ICprZXksCisvLwkJCQkJIGNv bnN0IHU4ICppbiwgdTggKm91dCwgc2l6ZV90IGxlbiwKKy8vCQkJCQkgdTggdHdlYWtbMTZdKTsK Ky8vCisvLyB8a2V5fCBpcyB0aGUgZGF0YSBrZXkuICB8dHdlYWt8IGNvbnRhaW5zIHRoZSBuZXh0 IHR3ZWFrOyB0aGUgZW5jcnlwdGlvbiBvZgorLy8gdGhlIG9yaWdpbmFsIElWIHdpdGggdGhlIHR3 ZWFrIGtleSB3YXMgYWxyZWFkeSBkb25lLiAgVGhpcyBmdW5jdGlvbiBzdXBwb3J0cworLy8gaW5j cmVtZW50YWwgY29tcHV0YXRpb24sIGJ1dCB8bGVufCBtdXN0IGFsd2F5cyBiZSA+PSAxNiAoQUVT X0JMT0NLX1NJWkUpLCBhbmQKKy8vIHxsZW58IG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNiBleGNl cHQgb24gdGhlIGxhc3QgY2FsbC4gIElmIHxsZW58IGlzIGEKKy8vIG11bHRpcGxlIG9mIDE2LCB0 aGVuIHRoaXMgZnVuY3Rpb24gdXBkYXRlcyB8dHdlYWt8IHRvIGNvbnRhaW4gdGhlIG5leHQgdHdl YWsuCitTWU1fRlVOQ19TVEFSVChhZXNfeHRzX2VuY3J5cHRfenZrbmVkX3p2YmJfenZrZykKKwlh ZXNfeHRzX2NyeXB0CTEKK1NZTV9GVU5DX0VORChhZXNfeHRzX2VuY3J5cHRfenZrbmVkX3p2YmJf enZrZykKKworLy8gU2FtZSBwcm90b3R5cGUgYW5kIGNhbGxpbmcgY29udmVudGlvbiBhcyB0aGUg ZW5jcnlwdGlvbiBmdW5jdGlvbgorU1lNX0ZVTkNfU1RBUlQoYWVzX3h0c19kZWNyeXB0X3p2a25l ZF96dmJiX3p2a2cpCisJYWVzX3h0c19jcnlwdAkwCitTWU1fRlVOQ19FTkQoYWVzX3h0c19kZWNy eXB0X3p2a25lZF96dmJiX3p2a2cpCmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2NyeXB0by9hZXMt cmlzY3Y2NC16dmtuZWQtenZrYi5TIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZr bmVkLXp2a2IuUwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAwLi45OTYy ZDQ1MDA1ODcwCi0tLSAvZGV2L251bGwKKysrIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2 NjQtenZrbmVkLXp2a2IuUwpAQCAtMCwwICsxLDE0NiBAQAorLyogU1BEWC1MaWNlbnNlLUlkZW50 aWZpZXI6IEFwYWNoZS0yLjAgT1IgQlNELTItQ2xhdXNlICovCisvLworLy8gVGhpcyBmaWxlIGlz IGR1YWwtbGljZW5zZWQsIG1lYW5pbmcgdGhhdCB5b3UgY2FuIHVzZSBpdCB1bmRlciB5b3VyCisv LyBjaG9pY2Ugb2YgZWl0aGVyIG9mIHRoZSBmb2xsb3dpbmcgdHdvIGxpY2Vuc2VzOgorLy8KKy8v IENvcHlyaWdodCAyMDIzIFRoZSBPcGVuU1NMIFByb2plY3QgQXV0aG9ycy4gQWxsIFJpZ2h0cyBS ZXNlcnZlZC4KKy8vCisvLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgMi4wICh0 aGUgIkxpY2Vuc2UiKS4gWW91IGNhbiBvYnRhaW4KKy8vIGEgY29weSBpbiB0aGUgZmlsZSBMSUNF TlNFIGluIHRoZSBzb3VyY2UgZGlzdHJpYnV0aW9uIG9yIGF0CisvLyBodHRwczovL3d3dy5vcGVu c3NsLm9yZy9zb3VyY2UvbGljZW5zZS5odG1sCisvLworLy8gb3IKKy8vCisvLyBDb3B5cmlnaHQg KGMpIDIwMjMsIEplcnJ5IFNoaWggPGplcnJ5LnNoaWhAc2lmaXZlLmNvbT4KKy8vIENvcHlyaWdo dCAyMDI0IEdvb2dsZSBMTEMKKy8vIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVkaXN0 cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRo b3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9s bG93aW5nIGNvbmRpdGlvbnMKKy8vIGFyZSBtZXQ6CisvLyAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Yg c291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gICAgbm90aWNl LCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgor Ly8gMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBh Ym92ZSBjb3B5cmlnaHQKKy8vICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5k IHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKKy8vICAgIGRvY3VtZW50YXRpb24gYW5k L29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisvLwor Ly8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5E IENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJS QU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdB UlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNV TEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklH SFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElO RElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5U SUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1F TlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRB LCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFO RCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNU UklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhF UldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZU V0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4K KworLy8gVGhlIGdlbmVyYXRlZCBjb2RlIG9mIHRoaXMgZmlsZSBkZXBlbmRzIG9uIHRoZSBmb2xs b3dpbmcgUklTQy1WIGV4dGVuc2lvbnM6CisvLyAtIFJWNjRJCisvLyAtIFJJU0MtViBWZWN0b3Ig KCdWJykgd2l0aCBWTEVOID49IDEyOAorLy8gLSBSSVNDLVYgVmVjdG9yIEFFUyBibG9jayBjaXBo ZXIgZXh0ZW5zaW9uICgnWnZrbmVkJykKKy8vIC0gUklTQy1WIFZlY3RvciBDcnlwdG9ncmFwaHkg Qml0LW1hbmlwdWxhdGlvbiBleHRlbnNpb24gKCdadmtiJykKKworI2luY2x1ZGUgPGxpbnV4L2xp bmthZ2UuaD4KKworLnRleHQKKy5vcHRpb24gYXJjaCwgK3p2a25lZCwgK3p2a2IKKworI2luY2x1 ZGUgImFlcy1tYWNyb3MuUyIKKworI2RlZmluZSBLRVlQCQlhMAorI2RlZmluZSBJTlAJCWExCisj ZGVmaW5lIE9VVFAJCWEyCisjZGVmaW5lIExFTgkJYTMKKyNkZWZpbmUgSVZQCQlhNAorCisjZGVm aW5lIExFTjMyCQlhNQorI2RlZmluZSBWTF9FMzIJCWE2CisjZGVmaW5lIFZMX0JMT0NLUwlhNwor CisubWFjcm8JYWVzX2N0cjMyX2NyeXB0CWtleWxlbgorCS8vIExFTjMyID0gbnVtYmVyIG9mIGJs b2Nrcywgcm91bmRlZCB1cCwgaW4gMzItYml0IHdvcmRzLgorCWFkZGkJCXQwLCBMRU4sIDE1CisJ c3JsaQkJdDAsIHQwLCA0CisJc2xsaQkJTEVOMzIsIHQwLCAyCisKKwkvLyBDcmVhdGUgYSBtYXNr IHRoYXQgc2VsZWN0cyB0aGUgbGFzdCAzMi1iaXQgd29yZCBvZiBlYWNoIDEyOC1iaXQKKwkvLyBi bG9jay4gIFRoaXMgaXMgdGhlIHdvcmQgdGhhdCBjb250YWlucyB0aGUgKGJpZy1lbmRpYW4pIGNv dW50ZXIuCisJbGkJCXQwLCAweDg4CisJdnNldHZsaQkJdDEsIHplcm8sIGU4LCBtMSwgdGEsIG1h CisJdm12LnYueAkJdjAsIHQwCisKKwkvLyBMb2FkIHRoZSBJViBpbnRvIHYzMS4gIFRoZSBsYXN0 IDMyLWJpdCB3b3JkIGNvbnRhaW5zIHRoZSBjb3VudGVyLgorCXZzZXRpdmxpCXplcm8sIDQsIGUz MiwgbTEsIHRhLCBtYQorCXZsZTMyLnYJCXYzMSwgKElWUCkKKworCS8vIENvbnZlcnQgdGhlIGJp Zy1lbmRpYW4gY291bnRlciBpbnRvIGxpdHRsZS1lbmRpYW4uCisJdnNldGl2bGkJemVybywgNCwg ZTMyLCBtMSwgdGEsIG11CisJdnJldjgudgkJdjMxLCB2MzEsIHYwLnQKKworCS8vIFNwbGF0IHRo ZSBJViB0byB2MTYgKHdpdGggTE1VTD00KS4gIFRoZSBudW1iZXIgb2YgY29waWVzIGlzIHRoZQor CS8vIG1heGltdW0gbnVtYmVyIG9mIGJsb2NrcyB0aGF0IHdpbGwgYmUgcHJvY2Vzc2VkIHBlciBp dGVyYXRpb24uCisJdnNldHZsaQkJemVybywgTEVOMzIsIGUzMiwgbTQsIHRhLCBtYQorCXZtdi52 LmkJCXYxNiwgMAorCXZhZXN6LnZzCXYxNiwgdjMxCisKKwkvLyB2MjAgPSBbeCwgeCwgeCwgMCwg eCwgeCwgeCwgMSwgLi4uXQorCXZpb3RhLm0JCXYyMCwgdjAsIHYwLnQKKwkvLyB2MTYgPSBbSVYw LCBJVjEsIElWMiwgY291bnRlciswLCBJVjAsIElWMSwgSVYyLCBjb3VudGVyKzEsIC4uLl0KKwl2 c2V0dmxpCQlWTF9FMzIsIExFTjMyLCBlMzIsIG00LCB0YSwgbXUKKwl2YWRkLnZ2CQl2MTYsIHYx NiwgdjIwLCB2MC50CisKKwlqIDJmCisxOgorCS8vIFNldCB0aGUgbnVtYmVyIG9mIGJsb2NrcyB0 byBwcm9jZXNzIGluIHRoaXMgaXRlcmF0aW9uLiAgdmw9VkxfRTMyIGlzCisJLy8gdGhlIGxlbmd0 aCBpbiAzMi1iaXQgd29yZHMsIGkuZS4gNCB0aW1lcyB0aGUgbnVtYmVyIG9mIGJsb2Nrcy4KKwl2 c2V0dmxpCQlWTF9FMzIsIExFTjMyLCBlMzIsIG00LCB0YSwgbXUKKworCS8vIEluY3JlbWVudCB0 aGUgY291bnRlcnMgYnkgdGhlIG51bWJlciBvZiBibG9ja3MgcHJvY2Vzc2VkIGluIHRoZQorCS8v IHByZXZpb3VzIGl0ZXJhdGlvbi4KKwl2YWRkLnZ4CQl2MTYsIHYxNiwgVkxfQkxPQ0tTLCB2MC50 CisyOgorCS8vIFByZXBhcmUgdGhlIEFFUyBpbnB1dHMgaW50byB2MjQuCisJdm12LnYudgkJdjI0 LCB2MTYKKwl2cmV2OC52CQl2MjQsIHYyNCwgdjAudAkvLyBDb252ZXJ0IGNvdW50ZXJzIGJhY2sg dG8gYmlnLWVuZGlhbi4KKworCS8vIEVuY3J5cHQgdGhlIEFFUyBpbnB1dHMgdG8gY3JlYXRlIHRo ZSBuZXh0IHBvcnRpb24gb2YgdGhlIGtleXN0cmVhbS4KKwlhZXNfZW5jcnlwdAl2MjQsIFxrZXls ZW4KKworCS8vIFhPUiB0aGUgZGF0YSB3aXRoIHRoZSBrZXlzdHJlYW0uCisJdnNldHZsaQkJdDAs IExFTiwgZTgsIG00LCB0YSwgbWEKKwl2bGU4LnYJCXYyMCwgKElOUCkKKwl2eG9yLnZ2CQl2MjAs IHYyMCwgdjI0CisJdnNlOC52CQl2MjAsIChPVVRQKQorCisJLy8gQWR2YW5jZSB0aGUgcG9pbnRl cnMgYW5kIHVwZGF0ZSB0aGUgcmVtYWluaW5nIGxlbmd0aC4KKwlhZGQJCUlOUCwgSU5QLCB0MAor CWFkZAkJT1VUUCwgT1VUUCwgdDAKKwlzdWIJCUxFTiwgTEVOLCB0MAorCXN1YgkJTEVOMzIsIExF TjMyLCBWTF9FMzIKKwlzcmxpCQlWTF9CTE9DS1MsIFZMX0UzMiwgMgorCisJLy8gUmVwZWF0IGlm IG1vcmUgZGF0YSByZW1haW5zLgorCWJuZXoJCUxFTiwgMWIKKworCS8vIFVwZGF0ZSAqSVZQIHRv IGNvbnRhaW4gdGhlIG5leHQgY291bnRlci4KKwl2c2V0aXZsaQl6ZXJvLCA0LCBlMzIsIG0xLCB0 YSwgbXUKKwl2YWRkLnZ4CQl2MTYsIHYxNiwgVkxfQkxPQ0tTLCB2MC50CisJdnJldjgudgkJdjE2 LCB2MTYsIHYwLnQJLy8gQ29udmVydCBjb3VudGVycyBiYWNrIHRvIGJpZy1lbmRpYW4uCisJdnNl MzIudgkJdjE2LCAoSVZQKQorCisJcmV0CisuZW5kbQorCisvLyB2b2lkIGFlc19jdHIzMl9jcnlw dF96dmtuZWRfenZrYihjb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHggKmtleSwKKy8vCQkJCSAg ICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNpemVfdCBsZW4sCisvLwkJCQkgICAgdTggaXZbMTZd KTsKK1NZTV9GVU5DX1NUQVJUKGFlc19jdHIzMl9jcnlwdF96dmtuZWRfenZrYikKKwlhZXNfYmVn aW4JS0VZUCwgMTI4ZiwgMTkyZgorCWFlc19jdHIzMl9jcnlwdAkyNTYKKzEyODoKKwlhZXNfY3Ry MzJfY3J5cHQJMTI4CisxOTI6CisJYWVzX2N0cjMyX2NyeXB0CTE5MgorU1lNX0ZVTkNfRU5EKGFl c19jdHIzMl9jcnlwdF96dmtuZWRfenZrYikKZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3YvY3J5cHRv L2Flcy1yaXNjdjY0LXp2a25lZC5TIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZr bmVkLlMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwMC4uNzhkNGUxMTg2 YzA3NAotLS0gL2Rldi9udWxsCisrKyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2 a25lZC5TCkBAIC0wLDAgKzEsMTgwIEBACisvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBh Y2hlLTIuMCBPUiBCU0QtMi1DbGF1c2UgKi8KKy8vCisvLyBUaGlzIGZpbGUgaXMgZHVhbC1saWNl bnNlZCwgbWVhbmluZyB0aGF0IHlvdSBjYW4gdXNlIGl0IHVuZGVyIHlvdXIKKy8vIGNob2ljZSBv ZiBlaXRoZXIgb2YgdGhlIGZvbGxvd2luZyB0d28gbGljZW5zZXM6CisvLworLy8gQ29weXJpZ2h0 IDIwMjMgVGhlIE9wZW5TU0wgUHJvamVjdCBBdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgor Ly8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSAyLjAgKHRoZSAiTGljZW5z ZSIpLiBZb3UgY2FuIG9idGFpbgorLy8gYSBjb3B5IGluIHRoZSBmaWxlIExJQ0VOU0UgaW4gdGhl IHNvdXJjZSBkaXN0cmlidXRpb24gb3IgYXQKKy8vIGh0dHBzOi8vd3d3Lm9wZW5zc2wub3JnL3Nv dXJjZS9saWNlbnNlLmh0bWwKKy8vCisvLyBvcgorLy8KKy8vIENvcHlyaWdodCAoYykgMjAyMywg Q2hyaXN0b3BoIE3DvGxsbmVyIDxjaHJpc3RvcGgubXVlbGxuZXJAdnJ1bGwuZXU+CisvLyBDb3B5 cmlnaHQgKGMpIDIwMjMsIFBob2ViZSBDaGVuIDxwaG9lYmUuY2hlbkBzaWZpdmUuY29tPgorLy8g Q29weXJpZ2h0IChjKSAyMDIzLCBKZXJyeSBTaGloIDxqZXJyeS5zaGloQHNpZml2ZS5jb20+Cisv LyBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDCisvLyBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8K Ky8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdp dGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRo YXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCisvLyBhcmUgbWV0OgorLy8gMS4gUmVkaXN0cmli dXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8v ICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlz Y2xhaW1lci4KKy8vIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJv ZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25k aXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisvLyAgICBkb2N1bWVu dGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0 aW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBI T0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElN UExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUg SU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8v IEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBU SEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkg RElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1Ig Q09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8s IFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNF LAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVS IENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENP TlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VO Q0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9G IFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VD SCBEQU1BR0UuCisKKy8vIFRoZSBnZW5lcmF0ZWQgY29kZSBvZiB0aGlzIGZpbGUgZGVwZW5kcyBv biB0aGUgZm9sbG93aW5nIFJJU0MtViBleHRlbnNpb25zOgorLy8gLSBSVjY0SQorLy8gLSBSSVND LVYgVmVjdG9yICgnVicpIHdpdGggVkxFTiA+PSAxMjgKKy8vIC0gUklTQy1WIFZlY3RvciBBRVMg YmxvY2sgY2lwaGVyIGV4dGVuc2lvbiAoJ1p2a25lZCcpCisKKyNpbmNsdWRlIDxsaW51eC9saW5r YWdlLmg+CisKKy50ZXh0Cisub3B0aW9uIGFyY2gsICt6dmtuZWQKKworI2luY2x1ZGUgImFlcy1t YWNyb3MuUyIKKworI2RlZmluZSBLRVlQCQlhMAorI2RlZmluZSBJTlAJCWExCisjZGVmaW5lIE9V VFAJCWEyCisjZGVmaW5lIExFTgkJYTMKKyNkZWZpbmUgSVZQCQlhNAorCisubWFjcm8JX19hZXNf Y3J5cHRfenZrbmVkCWVuYywga2V5bGVuCisJdmxlMzIudgkJdjE2LCAoSU5QKQorCWFlc19jcnlw dAl2MTYsIFxlbmMsIFxrZXlsZW4KKwl2c2UzMi52CQl2MTYsIChPVVRQKQorCXJldAorLmVuZG0K KworLm1hY3JvCWFlc19jcnlwdF96dmtuZWQJZW5jCisJYWVzX2JlZ2luCUtFWVAsIDEyOGYsIDE5 MmYKKwlfX2Flc19jcnlwdF96dmtuZWQJXGVuYywgMjU2CisxMjg6CisJX19hZXNfY3J5cHRfenZr bmVkCVxlbmMsIDEyOAorMTkyOgorCV9fYWVzX2NyeXB0X3p2a25lZAlcZW5jLCAxOTIKKy5lbmRt CisKKy8vIHZvaWQgYWVzX2VuY3J5cHRfenZrbmVkKGNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0 eCAqa2V5LAorLy8JCQkgICBjb25zdCB1OCBpblsxNl0sIHU4IG91dFsxNl0pOworU1lNX0ZVTkNf U1RBUlQoYWVzX2VuY3J5cHRfenZrbmVkKQorCWFlc19jcnlwdF96dmtuZWQJMQorU1lNX0ZVTkNf RU5EKGFlc19lbmNyeXB0X3p2a25lZCkKKworLy8gU2FtZSBwcm90b3R5cGUgYW5kIGNhbGxpbmcg Y29udmVudGlvbiBhcyB0aGUgZW5jcnlwdGlvbiBmdW5jdGlvbgorU1lNX0ZVTkNfU1RBUlQoYWVz X2RlY3J5cHRfenZrbmVkKQorCWFlc19jcnlwdF96dmtuZWQJMAorU1lNX0ZVTkNfRU5EKGFlc19k ZWNyeXB0X3p2a25lZCkKKworLm1hY3JvCV9fYWVzX2VjYl9jcnlwdAllbmMsIGtleWxlbgorCXNy bGkJCXQwLCBMRU4sIDIKKwkvLyB0MCBpcyB0aGUgcmVtYWluaW5nIGxlbmd0aCBpbiAzMi1iaXQg d29yZHMuICBJdCdzIGEgbXVsdGlwbGUgb2YgNC4KKzE6CisJdnNldHZsaQkJdDEsIHQwLCBlMzIs IG04LCB0YSwgbWEKKwlzdWIJCXQwLCB0MCwgdDEJLy8gU3VidHJhY3QgbnVtYmVyIG9mIHdvcmRz IHByb2Nlc3NlZAorCXNsbGkJCXQxLCB0MSwgMgkvLyBXb3JkcyB0byBieXRlcworCXZsZTMyLnYJ CXYxNiwgKElOUCkKKwlhZXNfY3J5cHQJdjE2LCBcZW5jLCBca2V5bGVuCisJdnNlMzIudgkJdjE2 LCAoT1VUUCkKKwlhZGQJCUlOUCwgSU5QLCB0MQorCWFkZAkJT1VUUCwgT1VUUCwgdDEKKwlibmV6 CQl0MCwgMWIKKworCXJldAorLmVuZG0KKworLm1hY3JvCWFlc19lY2JfY3J5cHQJZW5jCisJYWVz X2JlZ2luCUtFWVAsIDEyOGYsIDE5MmYKKwlfX2Flc19lY2JfY3J5cHQJXGVuYywgMjU2CisxMjg6 CisJX19hZXNfZWNiX2NyeXB0CVxlbmMsIDEyOAorMTkyOgorCV9fYWVzX2VjYl9jcnlwdAlcZW5j LCAxOTIKKy5lbmRtCisKKy8vIHZvaWQgYWVzX2VjYl9lbmNyeXB0X3p2a25lZChjb25zdCBzdHJ1 Y3QgY3J5cHRvX2Flc19jdHggKmtleSwKKy8vCQkJICAgICAgIGNvbnN0IHU4ICppbiwgdTggKm91 dCwgc2l6ZV90IGxlbik7CisvLworLy8gfGxlbnwgbXVzdCBiZSBub256ZXJvIGFuZCBhIG11bHRp cGxlIG9mIDE2IChBRVNfQkxPQ0tfU0laRSkuCitTWU1fRlVOQ19TVEFSVChhZXNfZWNiX2VuY3J5 cHRfenZrbmVkKQorCWFlc19lY2JfY3J5cHQJMQorU1lNX0ZVTkNfRU5EKGFlc19lY2JfZW5jcnlw dF96dmtuZWQpCisKKy8vIFNhbWUgcHJvdG90eXBlIGFuZCBjYWxsaW5nIGNvbnZlbnRpb24gYXMg dGhlIGVuY3J5cHRpb24gZnVuY3Rpb24KK1NZTV9GVU5DX1NUQVJUKGFlc19lY2JfZGVjcnlwdF96 dmtuZWQpCisJYWVzX2VjYl9jcnlwdAkwCitTWU1fRlVOQ19FTkQoYWVzX2VjYl9kZWNyeXB0X3p2 a25lZCkKKworLm1hY3JvCWFlc19jYmNfZW5jcnlwdAlrZXlsZW4KKwl2bGUzMi52CQl2MTYsIChJ VlApCS8vIExvYWQgSVYKKzE6CisJdmxlMzIudgkJdjE3LCAoSU5QKQkvLyBMb2FkIHBsYWludGV4 dCBibG9jaworCXZ4b3IudnYJCXYxNiwgdjE2LCB2MTcJLy8gWE9SIHdpdGggSVYgb3IgcHJldiBj aXBoZXJ0ZXh0IGJsb2NrCisJYWVzX2VuY3J5cHQJdjE2LCBca2V5bGVuCS8vIEVuY3J5cHQKKwl2 c2UzMi52CQl2MTYsIChPVVRQKQkvLyBTdG9yZSBjaXBoZXJ0ZXh0IGJsb2NrCisJYWRkaQkJSU5Q LCBJTlAsIDE2CisJYWRkaQkJT1VUUCwgT1VUUCwgMTYKKwlhZGRpCQlMRU4sIExFTiwgLTE2CisJ Ym5legkJTEVOLCAxYgorCisJdnNlMzIudgkJdjE2LCAoSVZQKQkvLyBTdG9yZSBuZXh0IElWCisJ cmV0CisuZW5kbQorCisubWFjcm8JYWVzX2NiY19kZWNyeXB0CWtleWxlbgorCXZsZTMyLnYJCXYx NiwgKElWUCkJLy8gTG9hZCBJVgorMToKKwl2bGUzMi52CQl2MTcsIChJTlApCS8vIExvYWQgY2lw aGVydGV4dCBibG9jaworCXZtdi52LnYJCXYxOCwgdjE3CS8vIFNhdmUgY2lwaGVydGV4dCBibG9j aworCWFlc19kZWNyeXB0CXYxNywgXGtleWxlbgkvLyBEZWNyeXB0CisJdnhvci52dgkJdjE3LCB2 MTcsIHYxNgkvLyBYT1Igd2l0aCBJViBvciBwcmV2IGNpcGhlcnRleHQgYmxvY2sKKwl2c2UzMi52 CQl2MTcsIChPVVRQKQkvLyBTdG9yZSBwbGFpbnRleHQgYmxvY2sKKwl2bXYudi52CQl2MTYsIHYx OAkvLyBOZXh0ICJJViIgaXMgcHJldiBjaXBoZXJ0ZXh0IGJsb2NrCisJYWRkaQkJSU5QLCBJTlAs IDE2CisJYWRkaQkJT1VUUCwgT1VUUCwgMTYKKwlhZGRpCQlMRU4sIExFTiwgLTE2CisJYm5legkJ TEVOLCAxYgorCisJdnNlMzIudgkJdjE2LCAoSVZQKQkvLyBTdG9yZSBuZXh0IElWCisJcmV0Cisu ZW5kbQorCisvLyB2b2lkIGFlc19jYmNfZW5jcnlwdF96dmtuZWQoY29uc3Qgc3RydWN0IGNyeXB0 b19hZXNfY3R4ICprZXksCisvLwkJCSAgICAgICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNpemVf dCBsZW4sIHU4IGl2WzE2XSk7CisvLworLy8gfGxlbnwgbXVzdCBiZSBub256ZXJvIGFuZCBhIG11 bHRpcGxlIG9mIDE2IChBRVNfQkxPQ0tfU0laRSkuCitTWU1fRlVOQ19TVEFSVChhZXNfY2JjX2Vu Y3J5cHRfenZrbmVkKQorCWFlc19iZWdpbglLRVlQLCAxMjhmLCAxOTJmCisJYWVzX2NiY19lbmNy eXB0CTI1NgorMTI4OgorCWFlc19jYmNfZW5jcnlwdAkxMjgKKzE5MjoKKwlhZXNfY2JjX2VuY3J5 cHQJMTkyCitTWU1fRlVOQ19FTkQoYWVzX2NiY19lbmNyeXB0X3p2a25lZCkKKworLy8gU2FtZSBw cm90b3R5cGUgYW5kIGNhbGxpbmcgY29udmVudGlvbiBhcyB0aGUgZW5jcnlwdGlvbiBmdW5jdGlv bgorU1lNX0ZVTkNfU1RBUlQoYWVzX2NiY19kZWNyeXB0X3p2a25lZCkKKwlhZXNfYmVnaW4JS0VZ UCwgMTI4ZiwgMTkyZgorCWFlc19jYmNfZGVjcnlwdAkyNTYKKzEyODoKKwlhZXNfY2JjX2RlY3J5 cHQJMTI4CisxOTI6CisJYWVzX2NiY19kZWNyeXB0CTE5MgorU1lNX0ZVTkNfRU5EKGFlc19jYmNf ZGVjcnlwdF96dmtuZWQpCi0tIAoyLjQzLjAKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fXwpsaW51eC1yaXNjdiBtYWlsaW5nIGxpc3QKbGludXgtcmlzY3ZA bGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xp c3RpbmZvL2xpbnV4LXJpc2N2Cg==