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 68DA036AF5; Fri, 5 Jan 2024 18:51:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n3Out9+g" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7F975C433D9; Fri, 5 Jan 2024 18:51:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1704480690; bh=i8YhV27gpx+OSDHWglug9n/uD7xBsTN3bFNKdWJ5qT0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n3Out9+ge/7+DGaIz/i1PR/buOCLMeKvADnSJMLvWEDJSr12yKbvTJcS4RqZPfY1m mdhOlvPgX12jEncpmiX93qBUmH022et1RN3x10V0Xaa9LZX4CsMZnxyCU951QOGC/e xiW9KAU/gr5CA/ZkOEW8lkkf3bBaLF4W85ikwnMUQZh8k6xDvVqK9bg+vQGsl0JVZI gX8hGrIbUKcH9mD9y+BoP8370yFXqLkIaiSqX/ExuW+FGnL1rq+RRMYpeNupHjnx0x phoDdLvb914I9j+aupSe+JfFuAP8K9PknpzfZjDV4qXStbTKS2NEejSl85mpHmetn0 dFMYUnuEGs3VQ== From: Eric Biggers To: linux-crypto@vger.kernel.org, linux-riscv@lists.infradead.org, Jerry Shih Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , Heiko Stuebner , Phoebe Chen , hongrong.hsu@sifive.com, Paul Walmsley , Palmer Dabbelt , Albert Ou , Andy Chiu Subject: [PATCH v2 06/12] crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS} Date: Fri, 5 Jan 2024 10:49:42 -0800 Message-ID: <20240105184950.43181-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240105184950.43181-1-ebiggers@kernel.org> References: <20240105184950.43181-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 | 300 ++++++++++ arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S | 146 +++++ arch/riscv/crypto/aes-riscv64-zvkned.S | 180 ++++++ 7 files changed, 1352 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 b3b6332c9f6d0..f3e0049611c06 100644 --- a/arch/riscv/crypto/Makefile +++ b/arch/riscv/crypto/Makefile @@ -1,4 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only # # linux/arch/riscv/crypto/Makefile # + +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..2ada0c70f4a6a --- /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. INP 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 INP CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING INP ANY WAY OUTP 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..8c400d68b3e7e --- /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); + 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 = 4 * AES_BLOCK_SIZE, /* matches LMUL=4 */ + .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..41eb618e8a5d9 --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S @@ -0,0 +1,300 @@ +/* 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 + +// 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 VL, LEN32, e32, m4, ta, ma + j 2f +1: + vsetvli VL, LEN32, e32, m4, ta, ma + // 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 +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 + + // Repeat if more blocks remain. + bnez LEN32, 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, 111f, 222f + __aes_xts_crypt \enc, 256 +111: + __aes_xts_crypt \enc, 128 +222: + __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..c4a84e84e60df --- /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, 111f, 222f + aes_ctr32_crypt 256 +111: + aes_ctr32_crypt 128 +222: + 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..6f7e8b0f31423 --- /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. INP 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 INP CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING INP ANY WAY OUTP 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, 111f, 222f + __aes_crypt_zvkned \enc, 256 +111: + __aes_crypt_zvkned \enc, 128 +222: + __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, m4, 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, 111f, 222f + __aes_ecb_crypt \enc, 256 +111: + __aes_ecb_crypt \enc, 128 +222: + __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, 111f, 222f + aes_cbc_encrypt 256 +111: + aes_cbc_encrypt 128 +222: + 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, 111f, 222f + aes_cbc_decrypt 256 +111: + aes_cbc_decrypt 128 +222: + 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 7638EC3DA6E for ; Fri, 5 Jan 2024 18:51:53 +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=shoYPQoDSzTljt4KQ3AJzWzRxLVVRmxNPsad78x4Eb4=; b=3pU0g+OaxM33dD 0RwcFMRFllVHLpG03zYaz77E5D/qeBMzWJYoB+zIUFWKxeMrpompRznUfzfxkzZ3lLT1bnF4gRX/X rMaHz3kkK4793vdE7uObiq1IdkJ82nRw5IDR8NuFawQd1M0zTkxaQtbQKLdzs3uf52jmuJuyoHx78 06gWgQQM7pqMKLoieYFBisCn1OKNR5M7XnTiuTk+Gx5EoJWSlkIsy6c5VR0/iaUFmwPzVlKywu6+o 7c8Pg8KU0ObMr9TS8cgCXc1YMIxNVuq7hwB8XnhwF5eVuJJsFHbRcbMOkOAIH5mk3Jh1Wo9y0wIVM 8ehD8jVlAf7ZviSoZuRA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1rLpIF-0001PF-1E; Fri, 05 Jan 2024 18:51:43 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1rLpI4-0001HB-09 for linux-riscv@lists.infradead.org; Fri, 05 Jan 2024 18:51:38 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 250B061BF3; Fri, 5 Jan 2024 18:51:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7F975C433D9; Fri, 5 Jan 2024 18:51:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1704480690; bh=i8YhV27gpx+OSDHWglug9n/uD7xBsTN3bFNKdWJ5qT0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n3Out9+ge/7+DGaIz/i1PR/buOCLMeKvADnSJMLvWEDJSr12yKbvTJcS4RqZPfY1m mdhOlvPgX12jEncpmiX93qBUmH022et1RN3x10V0Xaa9LZX4CsMZnxyCU951QOGC/e xiW9KAU/gr5CA/ZkOEW8lkkf3bBaLF4W85ikwnMUQZh8k6xDvVqK9bg+vQGsl0JVZI gX8hGrIbUKcH9mD9y+BoP8370yFXqLkIaiSqX/ExuW+FGnL1rq+RRMYpeNupHjnx0x phoDdLvb914I9j+aupSe+JfFuAP8K9PknpzfZjDV4qXStbTKS2NEejSl85mpHmetn0 dFMYUnuEGs3VQ== From: Eric Biggers To: linux-crypto@vger.kernel.org, linux-riscv@lists.infradead.org, Jerry Shih Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , Heiko Stuebner , Phoebe Chen , hongrong.hsu@sifive.com, Paul Walmsley , Palmer Dabbelt , Albert Ou , Andy Chiu Subject: [PATCH v2 06/12] crypto: riscv - add vector crypto accelerated AES-{ECB,CBC,CTR,XTS} Date: Fri, 5 Jan 2024 10:49:42 -0800 Message-ID: <20240105184950.43181-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240105184950.43181-1-ebiggers@kernel.org> References: <20240105184950.43181-1-ebiggers@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240105_105132_218776_22A41D88 X-CRM114-Status: GOOD ( 31.47 ) 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 ICAgIHwgMzAwICsrKysrKysrKysKIGFyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25l ZC16dmtiLlMgICB8IDE0NiArKysrKwogYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZr bmVkLlMgICAgICAgIHwgMTgwICsrKysrKwogNyBmaWxlcyBjaGFuZ2VkLCAxMzUyIGluc2VydGlv bnMoKykKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtbWFjcm9zLlMK IGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlzY3Y2NC1nbHVlLmMK IGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlzY3Y2NC16dmtuZWQt enZiYi16dmtnLlMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlz Y3Y2NC16dmtuZWQtenZrYi5TCiBjcmVhdGUgbW9kZSAxMDA2NDQgYXJjaC9yaXNjdi9jcnlwdG8v YWVzLXJpc2N2NjQtenZrbmVkLlMKCmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2NyeXB0by9LY29u ZmlnIGIvYXJjaC9yaXNjdi9jcnlwdG8vS2NvbmZpZwppbmRleCAxMGQ2MGVkYzAxMTBhLi5lYmU4 MDVmYTNmNWY3IDEwMDY0NAotLS0gYS9hcmNoL3Jpc2N2L2NyeXB0by9LY29uZmlnCisrKyBiL2Fy Y2gvcmlzY3YvY3J5cHRvL0tjb25maWcKQEAgLTEsNSArMSwyMSBAQAogIyBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogR1BMLTIuMAogCiBtZW51ICJBY2NlbGVyYXRlZCBDcnlwdG9ncmFwaGljIEFs Z29yaXRobXMgZm9yIENQVSAocmlzY3YpIgogCitjb25maWcgQ1JZUFRPX0FFU19SSVNDVjY0CisJ dHJpc3RhdGUgIkNpcGhlcnM6IEFFUywgbW9kZXM6IEVDQiwgQ0JDLCBDVFIsIFhUUyIKKwlkZXBl bmRzIG9uIDY0QklUICYmIFJJU0NWX0lTQV9WICYmIFRPT0xDSEFJTl9IQVNfVkVDVE9SX0NSWVBU TworCXNlbGVjdCBDUllQVE9fQUxHQVBJCisJc2VsZWN0IENSWVBUT19MSUJfQUVTCisJc2VsZWN0 IENSWVBUT19TS0NJUEhFUgorCWhlbHAKKwkgIEJsb2NrIGNpcGhlcjogQUVTIGNpcGhlciBhbGdv cml0aG1zCisJICBMZW5ndGgtcHJlc2VydmluZyBjaXBoZXJzOiBBRVMgd2l0aCBFQ0IsIENCQywg Q1RSLCBYVFMKKworCSAgQXJjaGl0ZWN0dXJlOiByaXNjdjY0IHVzaW5nOgorCSAgLSBadmtuZWQg dmVjdG9yIGNyeXB0byBleHRlbnNpb24KKwkgIC0gWnZiYiB2ZWN0b3IgZXh0ZW5zaW9uIChYVFMp CisJICAtIFp2a2IgdmVjdG9yIGNyeXB0byBleHRlbnNpb24gKENUUikKKwkgIC0gWnZrZyB2ZWN0 b3IgY3J5cHRvIGV4dGVuc2lvbiAoWFRTKQorCiBlbmRtZW51CmRpZmYgLS1naXQgYS9hcmNoL3Jp c2N2L2NyeXB0by9NYWtlZmlsZSBiL2FyY2gvcmlzY3YvY3J5cHRvL01ha2VmaWxlCmluZGV4IGIz YjYzMzJjOWY2ZDAuLmYzZTAwNDk2MTFjMDYgMTAwNjQ0Ci0tLSBhL2FyY2gvcmlzY3YvY3J5cHRv L01ha2VmaWxlCisrKyBiL2FyY2gvcmlzY3YvY3J5cHRvL01ha2VmaWxlCkBAIC0xLDQgKzEsOCBA QAogIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5CiAjCiAjIGxpbnV4L2Fy Y2gvcmlzY3YvY3J5cHRvL01ha2VmaWxlCiAjCisKK29iai0kKENPTkZJR19DUllQVE9fQUVTX1JJ U0NWNjQpICs9IGFlcy1yaXNjdjY0Lm8KK2Flcy1yaXNjdjY0LXkgOj0gYWVzLXJpc2N2NjQtZ2x1 ZS5vIGFlcy1yaXNjdjY0LXp2a25lZC5vIFwKKwkJIGFlcy1yaXNjdjY0LXp2a25lZC16dmJiLXp2 a2cubyBhZXMtcmlzY3Y2NC16dmtuZWQtenZrYi5vCmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2Ny eXB0by9hZXMtbWFjcm9zLlMgYi9hcmNoL3Jpc2N2L2NyeXB0by9hZXMtbWFjcm9zLlMKbmV3IGZp bGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwMC4uMmFkYTBjNzBmNGE2YQotLS0gL2Rl di9udWxsCisrKyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1tYWNyb3MuUwpAQCAtMCwwICsxLDE1 NiBAQAorLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAgT1IgQlNELTItQ2xh dXNlICovCisvLworLy8gVGhpcyBmaWxlIGlzIGR1YWwtbGljZW5zZWQsIG1lYW5pbmcgdGhhdCB5 b3UgY2FuIHVzZSBpdCB1bmRlciB5b3VyCisvLyBjaG9pY2Ugb2YgZWl0aGVyIG9mIHRoZSBmb2xs b3dpbmcgdHdvIGxpY2Vuc2VzOgorLy8KKy8vIENvcHlyaWdodCAyMDIzIFRoZSBPcGVuU1NMIFBy b2plY3QgQXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKy8vCisvLyBMaWNlbnNlZCB1bmRl ciB0aGUgQXBhY2hlIExpY2Vuc2UgMi4wICh0aGUgIkxpY2Vuc2UiKS4gWW91IGNhbiBvYnRhaW4K Ky8vIGEgY29weSBpbiB0aGUgZmlsZSBMSUNFTlNFIGluIHRoZSBzb3VyY2UgZGlzdHJpYnV0aW9u IG9yIGF0CisvLyBodHRwczovL3d3dy5vcGVuc3NsLm9yZy9zb3VyY2UvbGljZW5zZS5odG1sCisv LworLy8gb3IKKy8vCisvLyBDb3B5cmlnaHQgKGMpIDIwMjMsIENocmlzdG9waCBNw7xsbG5lciA8 Y2hyaXN0b3BoLm11ZWxsbmVyQHZydWxsLmV1PgorLy8gQ29weXJpZ2h0IChjKSAyMDIzLCBQaG9l YmUgQ2hlbiA8cGhvZWJlLmNoZW5Ac2lmaXZlLmNvbT4KKy8vIENvcHlyaWdodCAoYykgMjAyMywg SmVycnkgU2hpaCA8amVycnkuc2hpaEBzaWZpdmUuY29tPgorLy8gQ29weXJpZ2h0IDIwMjQgR29v Z2xlIExMQworLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBh bmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1v ZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29u ZGl0aW9ucworLy8gYXJlIG1ldDoKKy8vIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29k ZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyAgICBub3RpY2UsIHRoaXMgbGlz dCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAyLiBSZWRp c3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHly aWdodAorLy8gICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxv d2luZyBkaXNjbGFpbWVyIGluIHRoZQorLy8gICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIg bWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KKy8vCisvLyBUSElTIFNP RlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVU T1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElO Q0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBP RiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9T RSBBUkUgRElTQ0xBSU1FRC4gSU5QIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9X TkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJ TkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFH RVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VC U1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9G SVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkK Ky8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5QIENPTlRSQUNULCBTVFJJQ1QgTElB QklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBB UklTSU5HIElOUCBBTlkgV0FZIE9VVFAgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwg RVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8g VGhpcyBmaWxlIGNvbnRhaW5zIG1hY3JvcyB0aGF0IGFyZSBzaGFyZWQgYnkgdGhlIG90aGVyIGFl cy0qLlMgZmlsZXMuICBUaGUKKy8vIGdlbmVyYXRlZCBjb2RlIG9mIHRoZXNlIG1hY3JvcyBkZXBl bmRzIG9uIHRoZSBmb2xsb3dpbmcgUklTQy1WIGV4dGVuc2lvbnM6CisvLyAtIFJWNjRJCisvLyAt IFJJU0MtViBWZWN0b3IgKCdWJykgd2l0aCBWTEVOID49IDEyOAorLy8gLSBSSVNDLVYgVmVjdG9y IEFFUyBibG9jayBjaXBoZXIgZXh0ZW5zaW9uICgnWnZrbmVkJykKKworLy8gTG9hZHMgdGhlIEFF UyByb3VuZCBrZXlzIGZyb20gXGtleXAgaW50byB2ZWN0b3IgcmVnaXN0ZXJzIGFuZCBqdW1wcyB0 byBjb2RlCisvLyBzcGVjaWZpYyB0byB0aGUgbGVuZ3RoIG9mIHRoZSBrZXkuICBTcGVjaWZpY2Fs bHk6CisvLyAgIC0gSWYgQUVTLTEyOCwgbG9hZHMgcm91bmQga2V5cyBpbnRvIHYxLXYxMSBhbmQg anVtcHMgdG8gXGxhYmVsMTI4LgorLy8gICAtIElmIEFFUy0xOTIsIGxvYWRzIHJvdW5kIGtleXMg aW50byB2MS12MTMgYW5kIGp1bXBzIHRvIFxsYWJlbDE5Mi4KKy8vICAgLSBJZiBBRVMtMjU2LCBs b2FkcyByb3VuZCBrZXlzIGludG8gdjEtdjE1IGFuZCBjb250aW51ZXMgb253YXJkcy4KKy8vCisv LyBBbHNvIHNldHMgdmw9NCBhbmQgdnR5cGU9ZTMyLG0xLHRhLG1hLiAgQ2xvYmJlcnMgdDAgYW5k IHQxLgorLm1hY3JvCWFlc19iZWdpbglrZXlwLCBsYWJlbDEyOCwgbGFiZWwxOTIKKwlsd3UJCXQw LCA0ODAoXGtleXApCS8vIHQwID0ga2V5IGxlbmd0aCBpbiBieXRlcworCWxpCQl0MSwgMjQJCS8v IHQxID0ga2V5IGxlbmd0aCBmb3IgQUVTLTE5MgorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwgbTEs IHRhLCBtYQorCXZsZTMyLnYJCXYxLCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgor CXZsZTMyLnYJCXYyLCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJ CXYzLCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXY0LCAoXGtl eXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXY1LCAoXGtleXApCisJYWRk aQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXY2LCAoXGtleXApCisJYWRkaQkJXGtleXAs IFxrZXlwLCAxNgorCXZsZTMyLnYJCXY3LCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAx NgorCXZsZTMyLnYJCXY4LCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMy LnYJCXY5LCAoXGtleXApCisJYWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXYxMCwg KFxrZXlwKQorCWFkZGkJCVxrZXlwLCBca2V5cCwgMTYKKwl2bGUzMi52CQl2MTEsIChca2V5cCkK KwlibHQJCXQwLCB0MSwgXGxhYmVsMTI4CS8vIElmIEFFUy0xMjgsIGdvdG8gbGFiZWwxMjguCisJ YWRkaQkJXGtleXAsIFxrZXlwLCAxNgorCXZsZTMyLnYJCXYxMiwgKFxrZXlwKQorCWFkZGkJCVxr ZXlwLCBca2V5cCwgMTYKKwl2bGUzMi52CQl2MTMsIChca2V5cCkKKwliZXEJCXQwLCB0MSwgXGxh YmVsMTkyCS8vIElmIEFFUy0xOTIsIGdvdG8gbGFiZWwxOTIuCisJLy8gRWxzZSwgaXQncyBBRVMt MjU2LgorCWFkZGkJCVxrZXlwLCBca2V5cCwgMTYKKwl2bGUzMi52CQl2MTQsIChca2V5cCkKKwlh ZGRpCQlca2V5cCwgXGtleXAsIDE2CisJdmxlMzIudgkJdjE1LCAoXGtleXApCisuZW5kbQorCisv LyBFbmNyeXB0cyBcZGF0YSB1c2luZyB6dmtuZWQgaW5zdHJ1Y3Rpb25zLCB1c2luZyB0aGUgcm91 bmQga2V5cyBsb2FkZWQgaW50bworLy8gdjEtdjExIChmb3IgQUVTLTEyOCksIHYxLXYxMyAoZm9y IEFFUy0xOTIpLCBvciB2MS12MTUgKGZvciBBRVMtMjU2KS4gIFxrZXlsZW4KKy8vIGlzIHRoZSBB RVMga2V5IGxlbmd0aCBpbiBiaXRzLiAgdmwgYW5kIHZ0eXBlIG11c3QgYWxyZWFkeSBiZSBzZXQK Ky8vIGFwcHJvcHJpYXRlbHkuICBOb3RlIHRoYXQgaWYgdmwgPiA0LCBtdWx0aXBsZSBibG9ja3Mg YXJlIGVuY3J5cHRlZC4KKy5tYWNybwlhZXNfZW5jcnlwdAlkYXRhLCBrZXlsZW4KKwl2YWVzei52 cwlcZGF0YSwgdjEKKwl2YWVzZW0udnMJXGRhdGEsIHYyCisJdmFlc2VtLnZzCVxkYXRhLCB2Mwor CXZhZXNlbS52cwlcZGF0YSwgdjQKKwl2YWVzZW0udnMJXGRhdGEsIHY1CisJdmFlc2VtLnZzCVxk YXRhLCB2NgorCXZhZXNlbS52cwlcZGF0YSwgdjcKKwl2YWVzZW0udnMJXGRhdGEsIHY4CisJdmFl c2VtLnZzCVxkYXRhLCB2OQorCXZhZXNlbS52cwlcZGF0YSwgdjEwCisuaWYgXGtleWxlbiA9PSAx MjgKKwl2YWVzZWYudnMJXGRhdGEsIHYxMQorLmVsc2VpZiBca2V5bGVuID09IDE5MgorCXZhZXNl bS52cwlcZGF0YSwgdjExCisJdmFlc2VtLnZzCVxkYXRhLCB2MTIKKwl2YWVzZWYudnMJXGRhdGEs IHYxMworLmVsc2UKKwl2YWVzZW0udnMJXGRhdGEsIHYxMQorCXZhZXNlbS52cwlcZGF0YSwgdjEy CisJdmFlc2VtLnZzCVxkYXRhLCB2MTMKKwl2YWVzZW0udnMJXGRhdGEsIHYxNAorCXZhZXNlZi52 cwlcZGF0YSwgdjE1CisuZW5kaWYKKy5lbmRtCisKKy8vIFNhbWUgYXMgYWVzX2VuY3J5cHQsIGJ1 dCBkZWNyeXB0cyBpbnN0ZWFkIG9mIGVuY3J5cHRzLgorLm1hY3JvCWFlc19kZWNyeXB0CWRhdGEs IGtleWxlbgorLmlmIFxrZXlsZW4gPT0gMTI4CisJdmFlc3oudnMJXGRhdGEsIHYxMQorLmVsc2Vp ZiBca2V5bGVuID09IDE5MgorCXZhZXN6LnZzCVxkYXRhLCB2MTMKKwl2YWVzZG0udnMJXGRhdGEs IHYxMgorCXZhZXNkbS52cwlcZGF0YSwgdjExCisuZWxzZQorCXZhZXN6LnZzCVxkYXRhLCB2MTUK Kwl2YWVzZG0udnMJXGRhdGEsIHYxNAorCXZhZXNkbS52cwlcZGF0YSwgdjEzCisJdmFlc2RtLnZz CVxkYXRhLCB2MTIKKwl2YWVzZG0udnMJXGRhdGEsIHYxMQorLmVuZGlmCisJdmFlc2RtLnZzCVxk YXRhLCB2MTAKKwl2YWVzZG0udnMJXGRhdGEsIHY5CisJdmFlc2RtLnZzCVxkYXRhLCB2OAorCXZh ZXNkbS52cwlcZGF0YSwgdjcKKwl2YWVzZG0udnMJXGRhdGEsIHY2CisJdmFlc2RtLnZzCVxkYXRh LCB2NQorCXZhZXNkbS52cwlcZGF0YSwgdjQKKwl2YWVzZG0udnMJXGRhdGEsIHYzCisJdmFlc2Rt LnZzCVxkYXRhLCB2MgorCXZhZXNkZi52cwlcZGF0YSwgdjEKKy5lbmRtCisKKy8vIEV4cGFuZHMg dG8gYWVzX2VuY3J5cHQgb3IgYWVzX2RlY3J5cHQgYWNjb3JkaW5nIHRvIFxlbmMsIHdoaWNoIGlz IDEgb3IgMC4KKy5tYWNybwlhZXNfY3J5cHQJZGF0YSwgZW5jLCBrZXlsZW4KKy5pZiBcZW5jCisJ YWVzX2VuY3J5cHQJXGRhdGEsIFxrZXlsZW4KKy5lbHNlCisJYWVzX2RlY3J5cHQJXGRhdGEsIFxr ZXlsZW4KKy5lbmRpZgorLmVuZG0KZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1y aXNjdjY0LWdsdWUuYyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LWdsdWUuYwpuZXcg ZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAwLi44YzQwMGQ2OGIzZTdlCi0tLSAv ZGV2L251bGwKKysrIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtZ2x1ZS5jCkBAIC0w LDAgKzEsNTUwIEBACisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5Cisv KgorICogQUVTIHVzaW5nIHRoZSBSSVNDLVYgdmVjdG9yIGNyeXB0byBleHRlbnNpb25zLiAgSW5j bHVkZXMgdGhlIGJhcmUgYmxvY2sKKyAqIGNpcGhlciBhbmQgdGhlIEVDQiwgQ0JDLCBDVFIsIGFu ZCBYVFMgbW9kZXMuCisgKgorICogQ29weXJpZ2h0IChDKSAyMDIzIFZSVUxMIEdtYkgKKyAqIEF1 dGhvcjogSGVpa28gU3R1ZWJuZXIgPGhlaWtvLnN0dWVibmVyQHZydWxsLmV1PgorICoKKyAqIENv cHlyaWdodCAoQykgMjAyMyBTaUZpdmUsIEluYy4KKyAqIEF1dGhvcjogSmVycnkgU2hpaCA8amVy cnkuc2hpaEBzaWZpdmUuY29tPgorICovCisKKyNpbmNsdWRlIDxhc20vc2ltZC5oPgorI2luY2x1 ZGUgPGFzbS92ZWN0b3IuaD4KKyNpbmNsdWRlIDxjcnlwdG8vYWVzLmg+CisjaW5jbHVkZSA8Y3J5 cHRvL2ludGVybmFsL2NpcGhlci5oPgorI2luY2x1ZGUgPGNyeXB0by9pbnRlcm5hbC9zaW1kLmg+ CisjaW5jbHVkZSA8Y3J5cHRvL2ludGVybmFsL3NrY2lwaGVyLmg+CisjaW5jbHVkZSA8Y3J5cHRv L3NjYXR0ZXJ3YWxrLmg+CisjaW5jbHVkZSA8Y3J5cHRvL3h0cy5oPgorI2luY2x1ZGUgPGxpbnV4 L2xpbmthZ2UuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKworYXNtbGlua2FnZSB2b2lk IGFlc19lbmNyeXB0X3p2a25lZChjb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHggKmtleSwKKwkJ CQkgICBjb25zdCB1OCBpbltBRVNfQkxPQ0tfU0laRV0sCisJCQkJICAgdTggb3V0W0FFU19CTE9D S19TSVpFXSk7Cithc21saW5rYWdlIHZvaWQgYWVzX2RlY3J5cHRfenZrbmVkKGNvbnN0IHN0cnVj dCBjcnlwdG9fYWVzX2N0eCAqa2V5LAorCQkJCSAgIGNvbnN0IHU4IGluW0FFU19CTE9DS19TSVpF XSwKKwkJCQkgICB1OCBvdXRbQUVTX0JMT0NLX1NJWkVdKTsKKworYXNtbGlua2FnZSB2b2lkIGFl c19lY2JfZW5jcnlwdF96dmtuZWQoY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4ICprZXksCisJ CQkJICAgICAgIGNvbnN0IHU4ICppbiwgdTggKm91dCwgc2l6ZV90IGxlbik7Cithc21saW5rYWdl IHZvaWQgYWVzX2VjYl9kZWNyeXB0X3p2a25lZChjb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHgg KmtleSwKKwkJCQkgICAgICAgY29uc3QgdTggKmluLCB1OCAqb3V0LCBzaXplX3QgbGVuKTsKKwor YXNtbGlua2FnZSB2b2lkIGFlc19jYmNfZW5jcnlwdF96dmtuZWQoY29uc3Qgc3RydWN0IGNyeXB0 b19hZXNfY3R4ICprZXksCisJCQkJICAgICAgIGNvbnN0IHU4ICppbiwgdTggKm91dCwgc2l6ZV90 IGxlbiwKKwkJCQkgICAgICAgdTggaXZbQUVTX0JMT0NLX1NJWkVdKTsKK2FzbWxpbmthZ2Ugdm9p ZCBhZXNfY2JjX2RlY3J5cHRfenZrbmVkKGNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqa2V5 LAorCQkJCSAgICAgICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNpemVfdCBsZW4sCisJCQkJICAg ICAgIHU4IGl2W0FFU19CTE9DS19TSVpFXSk7CisKK2FzbWxpbmthZ2Ugdm9pZCBhZXNfY3RyMzJf Y3J5cHRfenZrbmVkX3p2a2IoY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4ICprZXksCisJCQkJ CSAgICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNpemVfdCBsZW4sCisJCQkJCSAgICB1OCBpdltB RVNfQkxPQ0tfU0laRV0pOworCithc21saW5rYWdlIHZvaWQgYWVzX3h0c19lbmNyeXB0X3p2a25l ZF96dmJiX3p2a2coCisJCQljb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHggKmtleSwKKwkJCWNv bnN0IHU4ICppbiwgdTggKm91dCwgc2l6ZV90IGxlbiwKKwkJCXU4IHR3ZWFrW0FFU19CTE9DS19T SVpFXSk7CisKK2FzbWxpbmthZ2Ugdm9pZCBhZXNfeHRzX2RlY3J5cHRfenZrbmVkX3p2YmJfenZr ZygKKwkJCWNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqa2V5LAorCQkJY29uc3QgdTggKmlu LCB1OCAqb3V0LCBzaXplX3QgbGVuLAorCQkJdTggdHdlYWtbQUVTX0JMT0NLX1NJWkVdKTsKKwor c3RhdGljIGludCByaXNjdjY0X2Flc19zZXRrZXkoc3RydWN0IGNyeXB0b19hZXNfY3R4ICpjdHgs CisJCQkgICAgICBjb25zdCB1OCAqa2V5LCB1bnNpZ25lZCBpbnQga2V5bGVuKQoreworCS8qCisJ ICogRm9yIG5vdyB3ZSBqdXN0IHVzZSB0aGUgZ2VuZXJpYyBrZXkgZXhwYW5zaW9uLCBmb3IgdGhl c2UgcmVhc29uczoKKwkgKgorCSAqIC0genZrbmVkJ3Mga2V5IGV4cGFuc2lvbiBpbnN0cnVjdGlv bnMgZG9uJ3Qgc3VwcG9ydCBBRVMtMTkyLgorCSAqICAgU28sIG5vbi16dmtuZWQgZmFsbGJhY2sg Y29kZSB3b3VsZCBiZSBuZWVkZWQgYW55d2F5LgorCSAqCisJICogLSBVc2VycyBvZiBBRVMgaW4g TGludXggdXN1YWxseSBkb24ndCBjaGFuZ2Uga2V5cyBmcmVxdWVudGx5LgorCSAqICAgU28sIGtl eSBleHBhbnNpb24gaXNuJ3QgcGVyZm9ybWFuY2UtY3JpdGljYWwuCisJICoKKwkgKiAtIEZvciBz aW5nbGUtYmxvY2sgQUVTIGV4cG9zZWQgYXMgYSAiY2lwaGVyIiBhbGdvcml0aG0sIGl0J3MKKwkg KiAgIG5lY2Vzc2FyeSB0byB1c2Ugc3RydWN0IGNyeXB0b19hZXNfY3R4IGFuZCBpbml0aWFsaXpl IGl0cyAna2V5X2RlYycKKwkgKiAgIGZpZWxkIHdpdGggdGhlIHJvdW5kIGtleXMgZm9yIHRoZSBF cXVpdmFsZW50IEludmVyc2UgQ2lwaGVyLiAgVGhpcworCSAqICAgaXMgYmVjYXVzZSB3aXRoICJj aXBoZXIiLCBkZWNyeXB0aW9uIGNhbiBiZSByZXF1ZXN0ZWQgZnJvbSBhCisJICogICBjb250ZXh0 IHdoZXJlIHRoZSB2ZWN0b3IgdW5pdCBpc24ndCB1c2FibGUsIG5lY2Vzc2l0YXRpbmcgYQorCSAq ICAgZmFsbGJhY2sgdG8gYWVzX2RlY3J5cHQoKS4gIEJ1dCwgenZrbmVkIGNhbiBvbmx5IGdlbmVy YXRlIGFuZCB1c2UKKwkgKiAgIHRoZSBub3JtYWwgcm91bmQga2V5cy4gIE9mIGNvdXJzZSwgaXQn cyBwcmVmZXJhYmxlIHRvIG5vdCBoYXZlCisJICogICBzcGVjaWFsIGNvZGUganVzdCBmb3IgImNp cGhlciIsIGFzIGUuZy4gWFRTIGFsc28gdXNlcyBhCisJICogICBzaW5nbGUtYmxvY2sgQUVTIGVu Y3J5cHRpb24uICBJdCdzIHNpbXBsZXN0IHRvIGp1c3QgdXNlCisJICogICBzdHJ1Y3QgY3J5cHRv X2Flc19jdHggYW5kIGFlc19leHBhbmRrZXkoKSBldmVyeXdoZXJlLgorCSAqLworCXJldHVybiBh ZXNfZXhwYW5ka2V5KGN0eCwga2V5LCBrZXlsZW4pOworfQorCitzdGF0aWMgaW50IHJpc2N2NjRf YWVzX3NldGtleV9jaXBoZXIoc3RydWN0IGNyeXB0b190Zm0gKnRmbSwKKwkJCQkgICAgIGNvbnN0 IHU4ICprZXksIHVuc2lnbmVkIGludCBrZXlsZW4pCit7CisJc3RydWN0IGNyeXB0b19hZXNfY3R4 ICpjdHggPSBjcnlwdG9fdGZtX2N0eCh0Zm0pOworCisJcmV0dXJuIHJpc2N2NjRfYWVzX3NldGtl eShjdHgsIGtleSwga2V5bGVuKTsKK30KKworc3RhdGljIGludCByaXNjdjY0X2Flc19zZXRrZXlf c2tjaXBoZXIoc3RydWN0IGNyeXB0b19za2NpcGhlciAqdGZtLAorCQkJCSAgICAgICBjb25zdCB1 OCAqa2V5LCB1bnNpZ25lZCBpbnQga2V5bGVuKQoreworCXN0cnVjdCBjcnlwdG9fYWVzX2N0eCAq Y3R4ID0gY3J5cHRvX3NrY2lwaGVyX2N0eCh0Zm0pOworCisJcmV0dXJuIHJpc2N2NjRfYWVzX3Nl dGtleShjdHgsIGtleSwga2V5bGVuKTsKK30KKworLyogQmFyZSBBRVMsIHdpdGhvdXQgYSBtb2Rl IG9mIG9wZXJhdGlvbiAqLworCitzdGF0aWMgdm9pZCByaXNjdjY0X2Flc19lbmNyeXB0KHN0cnVj dCBjcnlwdG9fdGZtICp0Zm0sIHU4ICpkc3QsIGNvbnN0IHU4ICpzcmMpCit7CisJY29uc3Qgc3Ry dWN0IGNyeXB0b19hZXNfY3R4ICpjdHggPSBjcnlwdG9fdGZtX2N0eCh0Zm0pOworCisJaWYgKGNy eXB0b19zaW1kX3VzYWJsZSgpKSB7CisJCWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsKKwkJYWVzX2Vu Y3J5cHRfenZrbmVkKGN0eCwgc3JjLCBkc3QpOworCQlrZXJuZWxfdmVjdG9yX2VuZCgpOworCX0g ZWxzZSB7CisJCWFlc19lbmNyeXB0KGN0eCwgZHN0LCBzcmMpOworCX0KK30KKworc3RhdGljIHZv aWQgcmlzY3Y2NF9hZXNfZGVjcnlwdChzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtLCB1OCAqZHN0LCBj b25zdCB1OCAqc3JjKQoreworCWNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqY3R4ID0gY3J5 cHRvX3RmbV9jdHgodGZtKTsKKworCWlmIChjcnlwdG9fc2ltZF91c2FibGUoKSkgeworCQlrZXJu ZWxfdmVjdG9yX2JlZ2luKCk7CisJCWFlc19kZWNyeXB0X3p2a25lZChjdHgsIHNyYywgZHN0KTsK KwkJa2VybmVsX3ZlY3Rvcl9lbmQoKTsKKwl9IGVsc2UgeworCQlhZXNfZGVjcnlwdChjdHgsIGRz dCwgc3JjKTsKKwl9Cit9CisKKy8qIEFFUy1FQ0IgKi8KKworc3RhdGljIGlubGluZSBpbnQgcmlz Y3Y2NF9hZXNfZWNiX2NyeXB0KHN0cnVjdCBza2NpcGhlcl9yZXF1ZXN0ICpyZXEsIGJvb2wgZW5j KQoreworCXN0cnVjdCBjcnlwdG9fc2tjaXBoZXIgKnRmbSA9IGNyeXB0b19za2NpcGhlcl9yZXF0 Zm0ocmVxKTsKKwljb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHggKmN0eCA9IGNyeXB0b19za2Np cGhlcl9jdHgodGZtKTsKKwlzdHJ1Y3Qgc2tjaXBoZXJfd2FsayB3YWxrOworCXVuc2lnbmVkIGlu dCBuYnl0ZXM7CisJaW50IGVycjsKKworCWVyciA9IHNrY2lwaGVyX3dhbGtfdmlydCgmd2Fsaywg cmVxLCBmYWxzZSk7CisJd2hpbGUgKChuYnl0ZXMgPSB3YWxrLm5ieXRlcykgIT0gMCkgeworCQlr ZXJuZWxfdmVjdG9yX2JlZ2luKCk7CisJCWlmIChlbmMpCisJCQlhZXNfZWNiX2VuY3J5cHRfenZr bmVkKGN0eCwgd2Fsay5zcmMudmlydC5hZGRyLAorCQkJCQkgICAgICAgd2Fsay5kc3QudmlydC5h ZGRyLAorCQkJCQkgICAgICAgbmJ5dGVzICYgfihBRVNfQkxPQ0tfU0laRSAtIDEpKTsKKwkJZWxz ZQorCQkJYWVzX2VjYl9kZWNyeXB0X3p2a25lZChjdHgsIHdhbGsuc3JjLnZpcnQuYWRkciwKKwkJ CQkJICAgICAgIHdhbGsuZHN0LnZpcnQuYWRkciwKKwkJCQkJICAgICAgIG5ieXRlcyAmIH4oQUVT X0JMT0NLX1NJWkUgLSAxKSk7CisJCWtlcm5lbF92ZWN0b3JfZW5kKCk7CisJCWVyciA9IHNrY2lw aGVyX3dhbGtfZG9uZSgmd2FsaywgbmJ5dGVzICYgKEFFU19CTE9DS19TSVpFIC0gMSkpOworCX0K KworCXJldHVybiBlcnI7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfZWNiX2VuY3J5cHQo c3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9hZXNfZWNi X2NyeXB0KHJlcSwgdHJ1ZSk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfZWNiX2RlY3J5 cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9hZXNf ZWNiX2NyeXB0KHJlcSwgZmFsc2UpOworfQorCisvKiBBRVMtQ0JDICovCisKK3N0YXRpYyBpbmxp bmUgaW50IHJpc2N2NjRfYWVzX2NiY19jcnlwdChzdHJ1Y3Qgc2tjaXBoZXJfcmVxdWVzdCAqcmVx LCBib29sIGVuYykKK3sKKwlzdHJ1Y3QgY3J5cHRvX3NrY2lwaGVyICp0Zm0gPSBjcnlwdG9fc2tj aXBoZXJfcmVxdGZtKHJlcSk7CisJY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4ICpjdHggPSBj cnlwdG9fc2tjaXBoZXJfY3R4KHRmbSk7CisJc3RydWN0IHNrY2lwaGVyX3dhbGsgd2FsazsKKwl1 bnNpZ25lZCBpbnQgbmJ5dGVzOworCWludCBlcnI7CisKKwllcnIgPSBza2NpcGhlcl93YWxrX3Zp cnQoJndhbGssIHJlcSwgZmFsc2UpOworCXdoaWxlICgobmJ5dGVzID0gd2Fsay5uYnl0ZXMpICE9 IDApIHsKKwkJa2VybmVsX3ZlY3Rvcl9iZWdpbigpOworCQlpZiAoZW5jKQorCQkJYWVzX2NiY19l bmNyeXB0X3p2a25lZChjdHgsIHdhbGsuc3JjLnZpcnQuYWRkciwKKwkJCQkJICAgICAgIHdhbGsu ZHN0LnZpcnQuYWRkciwKKwkJCQkJICAgICAgIG5ieXRlcyAmIH4oQUVTX0JMT0NLX1NJWkUgLSAx KSwKKwkJCQkJICAgICAgIHdhbGsuaXYpOworCQllbHNlCisJCQlhZXNfY2JjX2RlY3J5cHRfenZr bmVkKGN0eCwgd2Fsay5zcmMudmlydC5hZGRyLAorCQkJCQkgICAgICAgd2Fsay5kc3QudmlydC5h ZGRyLAorCQkJCQkgICAgICAgbmJ5dGVzICYgfihBRVNfQkxPQ0tfU0laRSAtIDEpLAorCQkJCQkg ICAgICAgd2Fsay5pdik7CisJCWtlcm5lbF92ZWN0b3JfZW5kKCk7CisJCWVyciA9IHNrY2lwaGVy X3dhbGtfZG9uZSgmd2FsaywgbmJ5dGVzICYgKEFFU19CTE9DS19TSVpFIC0gMSkpOworCX0KKwor CXJldHVybiBlcnI7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfY2JjX2VuY3J5cHQoc3Ry dWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9hZXNfY2JjX2Ny eXB0KHJlcSwgdHJ1ZSk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfY2JjX2RlY3J5cHQo c3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9hZXNfY2Jj X2NyeXB0KHJlcSwgZmFsc2UpOworfQorCisvKiBBRVMtQ1RSICovCisKK3N0YXRpYyBpbnQgcmlz Y3Y2NF9hZXNfY3RyX2NyeXB0KHN0cnVjdCBza2NpcGhlcl9yZXF1ZXN0ICpyZXEpCit7CisJc3Ry dWN0IGNyeXB0b19za2NpcGhlciAqdGZtID0gY3J5cHRvX3NrY2lwaGVyX3JlcXRmbShyZXEpOwor CWNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqY3R4ID0gY3J5cHRvX3NrY2lwaGVyX2N0eCh0 Zm0pOworCXVuc2lnbmVkIGludCBuYnl0ZXMsIHAxX25ieXRlczsKKwlzdHJ1Y3Qgc2tjaXBoZXJf d2FsayB3YWxrOworCXUzMiBjdHIzMiwgbmJsb2NrczsKKwlpbnQgZXJyOworCisJLyogR2V0IHRo ZSBsb3cgMzItYml0IHdvcmQgb2YgdGhlIDEyOC1iaXQgYmlnIGVuZGlhbiBjb3VudGVyLiAqLwor CWN0cjMyID0gZ2V0X3VuYWxpZ25lZF9iZTMyKHJlcS0+aXYgKyAxMik7CisKKwllcnIgPSBza2Np cGhlcl93YWxrX3ZpcnQoJndhbGssIHJlcSwgZmFsc2UpOworCXdoaWxlICgobmJ5dGVzID0gd2Fs ay5uYnl0ZXMpICE9IDApIHsKKwkJaWYgKG5ieXRlcyA8IHdhbGsudG90YWwpIHsKKwkJCS8qIE5v dCB0aGUgZW5kIHlldCwgc28ga2VlcCB0aGUgbGVuZ3RoIGJsb2NrLWFsaWduZWQuICovCisJCQlu Ynl0ZXMgPSByb3VuZF9kb3duKG5ieXRlcywgQUVTX0JMT0NLX1NJWkUpOworCQkJbmJsb2NrcyA9 IG5ieXRlcyAvIEFFU19CTE9DS19TSVpFOworCQl9IGVsc2UgeworCQkJLyogSXQncyB0aGUgZW5k LCBzbyBpbmNsdWRlIGFueSBmaW5hbCBwYXJ0aWFsIGJsb2NrLiAqLworCQkJbmJsb2NrcyA9IERJ Vl9ST1VORF9VUChuYnl0ZXMsIEFFU19CTE9DS19TSVpFKTsKKwkJfQorCQljdHIzMiArPSBuYmxv Y2tzOworCisJCWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsKKwkJaWYgKGN0cjMyID49IG5ibG9ja3Mp IHsKKwkJCS8qIFRoZSBsb3cgMzItYml0IHdvcmQgb2YgdGhlIGNvdW50ZXIgd29uJ3Qgb3ZlcmZs b3cuICovCisJCQlhZXNfY3RyMzJfY3J5cHRfenZrbmVkX3p2a2IoY3R4LCB3YWxrLnNyYy52aXJ0 LmFkZHIsCisJCQkJCQkgICAgd2Fsay5kc3QudmlydC5hZGRyLCBuYnl0ZXMsCisJCQkJCQkgICAg cmVxLT5pdik7CisJCX0gZWxzZSB7CisJCQkvKgorCQkJICogVGhlIGxvdyAzMi1iaXQgd29yZCBv ZiB0aGUgY291bnRlciB3aWxsIG92ZXJmbG93LgorCQkJICogVGhlIGFzc2VtYmx5IGRvZXNuJ3Qg aGFuZGxlIHRoaXMgY2FzZSwgc28gc3BsaXQgdGhlCisJCQkgKiBvcGVyYXRpb24gaW50byB0d28g YXQgdGhlIHBvaW50IHdoZXJlIHRoZSBvdmVyZmxvdworCQkJICogd2lsbCBvY2N1ci4gIEFmdGVy IHRoZSBmaXJzdCBwYXJ0LCBhZGQgdGhlIGNhcnJ5IGJpdC4KKwkJCSAqLworCQkJcDFfbmJ5dGVz ID0gbWluX3QodW5zaWduZWQgaW50LCBuYnl0ZXMsCisJCQkJCSAgKG5ibG9ja3MgLSBjdHIzMikg KiBBRVNfQkxPQ0tfU0laRSk7CisJCQlhZXNfY3RyMzJfY3J5cHRfenZrbmVkX3p2a2IoY3R4LCB3 YWxrLnNyYy52aXJ0LmFkZHIsCisJCQkJCQkgICAgd2Fsay5kc3QudmlydC5hZGRyLAorCQkJCQkJ ICAgIHAxX25ieXRlcywgcmVxLT5pdik7CisJCQljcnlwdG9faW5jKHJlcS0+aXYsIDEyKTsKKwor CQkJaWYgKGN0cjMyKSB7CisJCQkJYWVzX2N0cjMyX2NyeXB0X3p2a25lZF96dmtiKAorCQkJCQlj dHgsCisJCQkJCXdhbGsuc3JjLnZpcnQuYWRkciArIHAxX25ieXRlcywKKwkJCQkJd2Fsay5kc3Qu dmlydC5hZGRyICsgcDFfbmJ5dGVzLAorCQkJCQluYnl0ZXMgLSBwMV9uYnl0ZXMsIHJlcS0+aXYp OworCQkJfQorCQl9CisJCWtlcm5lbF92ZWN0b3JfZW5kKCk7CisKKwkJZXJyID0gc2tjaXBoZXJf d2Fsa19kb25lKCZ3YWxrLCB3YWxrLm5ieXRlcyAtIG5ieXRlcyk7CisJfQorCisJcmV0dXJuIGVy cjsKK30KKworLyogQUVTLVhUUyAqLworCitzdHJ1Y3QgcmlzY3Y2NF9hZXNfeHRzX2N0eCB7CisJ c3RydWN0IGNyeXB0b19hZXNfY3R4IGN0eDE7CisJc3RydWN0IGNyeXB0b19hZXNfY3R4IGN0eDI7 Cit9OworCitzdGF0aWMgaW50IHJpc2N2NjRfYWVzX3h0c19zZXRrZXkoc3RydWN0IGNyeXB0b19z a2NpcGhlciAqdGZtLCBjb25zdCB1OCAqa2V5LAorCQkJCSAgdW5zaWduZWQgaW50IGtleWxlbikK K3sKKwlzdHJ1Y3QgcmlzY3Y2NF9hZXNfeHRzX2N0eCAqY3R4ID0gY3J5cHRvX3NrY2lwaGVyX2N0 eCh0Zm0pOworCisJcmV0dXJuIHh0c192ZXJpZnlfa2V5KHRmbSwga2V5LCBrZXlsZW4pID86CisJ ICAgICAgIHJpc2N2NjRfYWVzX3NldGtleSgmY3R4LT5jdHgxLCBrZXksIGtleWxlbiAvIDIpID86 CisJICAgICAgIHJpc2N2NjRfYWVzX3NldGtleSgmY3R4LT5jdHgyLCBrZXkgKyBrZXlsZW4gLyAy LCBrZXlsZW4gLyAyKTsKK30KKworc3RhdGljIGludCByaXNjdjY0X2Flc194dHNfY3J5cHQoc3Ry dWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSwgYm9vbCBlbmMpCit7CisJc3RydWN0IGNyeXB0b19z a2NpcGhlciAqdGZtID0gY3J5cHRvX3NrY2lwaGVyX3JlcXRmbShyZXEpOworCXN0cnVjdCByaXNj djY0X2Flc194dHNfY3R4ICpjdHggPSBjcnlwdG9fc2tjaXBoZXJfY3R4KHRmbSk7CisJaW50IHRh aWwgPSByZXEtPmNyeXB0bGVuICUgQUVTX0JMT0NLX1NJWkU7CisJc3RydWN0IHNjYXR0ZXJsaXN0 IHNnX3NyY1syXSwgc2dfZHN0WzJdOworCXN0cnVjdCBza2NpcGhlcl9yZXF1ZXN0IHN1YnJlcTsK KwlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNyYywgKmRzdDsKKwlzdHJ1Y3Qgc2tjaXBoZXJfd2FsayB3 YWxrOworCWludCBlcnI7CisKKwlpZiAocmVxLT5jcnlwdGxlbiA8IEFFU19CTE9DS19TSVpFKQor CQlyZXR1cm4gLUVJTlZBTDsKKworCS8qIEVuY3J5cHQgdGhlIElWIHdpdGggdGhlIHR3ZWFrIGtl eSB0byBnZXQgdGhlIGZpcnN0IHR3ZWFrLiAqLworCWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsKKwlh ZXNfZW5jcnlwdF96dmtuZWQoJmN0eC0+Y3R4MiwgcmVxLT5pdiwgcmVxLT5pdik7CisJa2VybmVs X3ZlY3Rvcl9lbmQoKTsKKworCWVyciA9IHNrY2lwaGVyX3dhbGtfdmlydCgmd2FsaywgcmVxLCBm YWxzZSk7CisKKwkvKgorCSAqIElmIHRoZSBtZXNzYWdlIGxlbmd0aCBpc24ndCBkaXZpc2libGUg YnkgdGhlIEFFUyBibG9jayBzaXplIGFuZCB0aGUKKwkgKiBmdWxsIG1lc3NhZ2UgaXNuJ3QgYXZh aWxhYmxlIGluIG9uZSBzdGVwIG9mIHRoZSBzY2F0dGVybGlzdCB3YWxrLAorCSAqIHRoZW4gc2Vw YXJhdGUgb2ZmIHRoZSBsYXN0IGZ1bGwgYmxvY2sgYW5kIHRoZSBwYXJ0aWFsIGJsb2NrLiAgVGhp cworCSAqIGVuc3VyZXMgdGhhdCB0aGV5IGFyZSBwcm9jZXNzZWQgaW4gdGhlIHNhbWUgY2FsbCB0 byB0aGUgYXNzZW1ibHkKKwkgKiBmdW5jdGlvbiwgd2hpY2ggaXMgcmVxdWlyZWQgZm9yIGNpcGhl cnRleHQgc3RlYWxpbmcuCisJICovCisJaWYgKHVubGlrZWx5KHRhaWwgPiAwICYmIHdhbGsubmJ5 dGVzIDwgd2Fsay50b3RhbCkpIHsKKwkJc2tjaXBoZXJfd2Fsa19hYm9ydCgmd2Fsayk7CisKKwkJ c2tjaXBoZXJfcmVxdWVzdF9zZXRfdGZtKCZzdWJyZXEsIHRmbSk7CisJCXNrY2lwaGVyX3JlcXVl c3Rfc2V0X2NhbGxiYWNrKCZzdWJyZXEsCisJCQkJCSAgICAgIHNrY2lwaGVyX3JlcXVlc3RfZmxh Z3MocmVxKSwKKwkJCQkJICAgICAgTlVMTCwgTlVMTCk7CisJCXNrY2lwaGVyX3JlcXVlc3Rfc2V0 X2NyeXB0KCZzdWJyZXEsIHJlcS0+c3JjLCByZXEtPmRzdCwKKwkJCQkJICAgcmVxLT5jcnlwdGxl biAtIHRhaWwgLSBBRVNfQkxPQ0tfU0laRSwKKwkJCQkJICAgcmVxLT5pdik7CisJCXJlcSA9ICZz dWJyZXE7CisJCWVyciA9IHNrY2lwaGVyX3dhbGtfdmlydCgmd2FsaywgcmVxLCBmYWxzZSk7CisJ fSBlbHNlIHsKKwkJdGFpbCA9IDA7CisJfQorCisJd2hpbGUgKHdhbGsubmJ5dGVzKSB7CisJCXVu c2lnbmVkIGludCBuYnl0ZXMgPSB3YWxrLm5ieXRlczsKKworCQlpZiAobmJ5dGVzIDwgd2Fsay50 b3RhbCkKKwkJCW5ieXRlcyA9IHJvdW5kX2Rvd24obmJ5dGVzLCBBRVNfQkxPQ0tfU0laRSk7CisK KwkJa2VybmVsX3ZlY3Rvcl9iZWdpbigpOworCQlpZiAoZW5jKQorCQkJYWVzX3h0c19lbmNyeXB0 X3p2a25lZF96dmJiX3p2a2coCisJCQkJJmN0eC0+Y3R4MSwgd2Fsay5zcmMudmlydC5hZGRyLAor CQkJCXdhbGsuZHN0LnZpcnQuYWRkciwgbmJ5dGVzLCByZXEtPml2KTsKKwkJZWxzZQorCQkJYWVz X3h0c19kZWNyeXB0X3p2a25lZF96dmJiX3p2a2coCisJCQkJJmN0eC0+Y3R4MSwgd2Fsay5zcmMu dmlydC5hZGRyLAorCQkJCXdhbGsuZHN0LnZpcnQuYWRkciwgbmJ5dGVzLCByZXEtPml2KTsKKwkJ a2VybmVsX3ZlY3Rvcl9lbmQoKTsKKwkJZXJyID0gc2tjaXBoZXJfd2Fsa19kb25lKCZ3YWxrLCB3 YWxrLm5ieXRlcyAtIG5ieXRlcyk7CisJfQorCisJaWYgKGVyciB8fCBsaWtlbHkoIXRhaWwpKQor CQlyZXR1cm4gZXJyOworCisJLyogRG8gY2lwaGVydGV4dCBzdGVhbGluZyB3aXRoIHRoZSBsYXN0 IGZ1bGwgYmxvY2sgYW5kIHBhcnRpYWwgYmxvY2suICovCisKKwlkc3QgPSBzcmMgPSBzY2F0dGVy d2Fsa19mZndkKHNnX3NyYywgcmVxLT5zcmMsIHJlcS0+Y3J5cHRsZW4pOworCWlmIChyZXEtPmRz dCAhPSByZXEtPnNyYykKKwkJZHN0ID0gc2NhdHRlcndhbGtfZmZ3ZChzZ19kc3QsIHJlcS0+ZHN0 LCByZXEtPmNyeXB0bGVuKTsKKworCXNrY2lwaGVyX3JlcXVlc3Rfc2V0X2NyeXB0KHJlcSwgc3Jj LCBkc3QsIEFFU19CTE9DS19TSVpFICsgdGFpbCwKKwkJCQkgICByZXEtPml2KTsKKworCWVyciA9 IHNrY2lwaGVyX3dhbGtfdmlydCgmd2FsaywgcmVxLCBmYWxzZSk7CisJaWYgKGVycikKKwkJcmV0 dXJuIGVycjsKKworCWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsKKwlpZiAoZW5jKQorCQlhZXNfeHRz X2VuY3J5cHRfenZrbmVkX3p2YmJfenZrZygKKwkJCSZjdHgtPmN0eDEsIHdhbGsuc3JjLnZpcnQu YWRkciwKKwkJCXdhbGsuZHN0LnZpcnQuYWRkciwgd2Fsay5uYnl0ZXMsIHJlcS0+aXYpOworCWVs c2UKKwkJYWVzX3h0c19kZWNyeXB0X3p2a25lZF96dmJiX3p2a2coCisJCQkmY3R4LT5jdHgxLCB3 YWxrLnNyYy52aXJ0LmFkZHIsCisJCQl3YWxrLmRzdC52aXJ0LmFkZHIsIHdhbGsubmJ5dGVzLCBy ZXEtPml2KTsKKwlrZXJuZWxfdmVjdG9yX2VuZCgpOworCisJcmV0dXJuIHNrY2lwaGVyX3dhbGtf ZG9uZSgmd2FsaywgMCk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfeHRzX2VuY3J5cHQo c3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9hZXNfeHRz X2NyeXB0KHJlcSwgdHJ1ZSk7Cit9CisKK3N0YXRpYyBpbnQgcmlzY3Y2NF9hZXNfeHRzX2RlY3J5 cHQoc3RydWN0IHNrY2lwaGVyX3JlcXVlc3QgKnJlcSkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9hZXNf eHRzX2NyeXB0KHJlcSwgZmFsc2UpOworfQorCisvKiBBbGdvcml0aG0gZGVmaW5pdGlvbnMgKi8K Kworc3RhdGljIHN0cnVjdCBjcnlwdG9fYWxnIHJpc2N2NjRfenZrbmVkX2Flc19jaXBoZXJfYWxn ID0geworCS5jcmFfZmxhZ3MgPSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSLAorCS5jcmFfYmxvY2tz aXplID0gQUVTX0JMT0NLX1NJWkUsCisJLmNyYV9jdHhzaXplID0gc2l6ZW9mKHN0cnVjdCBjcnlw dG9fYWVzX2N0eCksCisJLmNyYV9wcmlvcml0eSA9IDMwMCwKKwkuY3JhX25hbWUgPSAiYWVzIiwK KwkuY3JhX2RyaXZlcl9uYW1lID0gImFlcy1yaXNjdjY0LXp2a25lZCIsCisJLmNyYV9jaXBoZXIg PSB7CisJCS5jaWFfbWluX2tleXNpemUgPSBBRVNfTUlOX0tFWV9TSVpFLAorCQkuY2lhX21heF9r ZXlzaXplID0gQUVTX01BWF9LRVlfU0laRSwKKwkJLmNpYV9zZXRrZXkgPSByaXNjdjY0X2Flc19z ZXRrZXlfY2lwaGVyLAorCQkuY2lhX2VuY3J5cHQgPSByaXNjdjY0X2Flc19lbmNyeXB0LAorCQku Y2lhX2RlY3J5cHQgPSByaXNjdjY0X2Flc19kZWNyeXB0LAorCX0sCisJLmNyYV9tb2R1bGUgPSBU SElTX01PRFVMRSwKK307CisKK3N0YXRpYyBzdHJ1Y3Qgc2tjaXBoZXJfYWxnIHJpc2N2NjRfenZr bmVkX2Flc19za2NpcGhlcl9hbGdzW10gPSB7CisJeworCQkuc2V0a2V5ID0gcmlzY3Y2NF9hZXNf c2V0a2V5X3NrY2lwaGVyLAorCQkuZW5jcnlwdCA9IHJpc2N2NjRfYWVzX2VjYl9lbmNyeXB0LAor CQkuZGVjcnlwdCA9IHJpc2N2NjRfYWVzX2VjYl9kZWNyeXB0LAorCQkubWluX2tleXNpemUgPSBB RVNfTUlOX0tFWV9TSVpFLAorCQkubWF4X2tleXNpemUgPSBBRVNfTUFYX0tFWV9TSVpFLAorCQku d2Fsa3NpemUgPSA0ICogQUVTX0JMT0NLX1NJWkUsIC8qIG1hdGNoZXMgTE1VTD00ICovCisJCS5i YXNlID0geworCQkJLmNyYV9ibG9ja3NpemUgPSBBRVNfQkxPQ0tfU0laRSwKKwkJCS5jcmFfY3R4 c2l6ZSA9IHNpemVvZihzdHJ1Y3QgY3J5cHRvX2Flc19jdHgpLAorCQkJLmNyYV9wcmlvcml0eSA9 IDMwMCwKKwkJCS5jcmFfbmFtZSA9ICJlY2IoYWVzKSIsCisJCQkuY3JhX2RyaXZlcl9uYW1lID0g ImVjYi1hZXMtcmlzY3Y2NC16dmtuZWQiLAorCQkJLmNyYV9tb2R1bGUgPSBUSElTX01PRFVMRSwK KwkJfSwKKwl9LCB7CisJCS5zZXRrZXkgPSByaXNjdjY0X2Flc19zZXRrZXlfc2tjaXBoZXIsCisJ CS5lbmNyeXB0ID0gcmlzY3Y2NF9hZXNfY2JjX2VuY3J5cHQsCisJCS5kZWNyeXB0ID0gcmlzY3Y2 NF9hZXNfY2JjX2RlY3J5cHQsCisJCS5taW5fa2V5c2l6ZSA9IEFFU19NSU5fS0VZX1NJWkUsCisJ CS5tYXhfa2V5c2l6ZSA9IEFFU19NQVhfS0VZX1NJWkUsCisJCS5pdnNpemUgPSBBRVNfQkxPQ0tf U0laRSwKKwkJLmJhc2UgPSB7CisJCQkuY3JhX2Jsb2Nrc2l6ZSA9IEFFU19CTE9DS19TSVpFLAor CQkJLmNyYV9jdHhzaXplID0gc2l6ZW9mKHN0cnVjdCBjcnlwdG9fYWVzX2N0eCksCisJCQkuY3Jh X3ByaW9yaXR5ID0gMzAwLAorCQkJLmNyYV9uYW1lID0gImNiYyhhZXMpIiwKKwkJCS5jcmFfZHJp dmVyX25hbWUgPSAiY2JjLWFlcy1yaXNjdjY0LXp2a25lZCIsCisJCQkuY3JhX21vZHVsZSA9IFRI SVNfTU9EVUxFLAorCQl9LAorCX0KK307CisKK3N0YXRpYyBzdHJ1Y3Qgc2tjaXBoZXJfYWxnIHJp c2N2NjRfenZrbmVkX3p2a2JfYWVzX3NrY2lwaGVyX2FsZyA9IHsKKwkuc2V0a2V5ID0gcmlzY3Y2 NF9hZXNfc2V0a2V5X3NrY2lwaGVyLAorCS5lbmNyeXB0ID0gcmlzY3Y2NF9hZXNfY3RyX2NyeXB0 LAorCS5kZWNyeXB0ID0gcmlzY3Y2NF9hZXNfY3RyX2NyeXB0LAorCS5taW5fa2V5c2l6ZSA9IEFF U19NSU5fS0VZX1NJWkUsCisJLm1heF9rZXlzaXplID0gQUVTX01BWF9LRVlfU0laRSwKKwkuaXZz aXplID0gQUVTX0JMT0NLX1NJWkUsCisJLmNodW5rc2l6ZSA9IEFFU19CTE9DS19TSVpFLAorCS53 YWxrc2l6ZSA9IDQgKiBBRVNfQkxPQ0tfU0laRSwgLyogbWF0Y2hlcyBMTVVMPTQgKi8KKwkuYmFz ZSA9IHsKKwkJLmNyYV9ibG9ja3NpemUgPSAxLAorCQkuY3JhX2N0eHNpemUgPSBzaXplb2Yoc3Ry dWN0IGNyeXB0b19hZXNfY3R4KSwKKwkJLmNyYV9wcmlvcml0eSA9IDMwMCwKKwkJLmNyYV9uYW1l ID0gImN0cihhZXMpIiwKKwkJLmNyYV9kcml2ZXJfbmFtZSA9ICJjdHItYWVzLXJpc2N2NjQtenZr bmVkLXp2a2IiLAorCQkuY3JhX21vZHVsZSA9IFRISVNfTU9EVUxFLAorCX0sCit9OworCitzdGF0 aWMgc3RydWN0IHNrY2lwaGVyX2FsZyByaXNjdjY0X3p2a25lZF96dmJiX3p2a2dfYWVzX3NrY2lw aGVyX2FsZyA9IHsKKwkuc2V0a2V5ID0gcmlzY3Y2NF9hZXNfeHRzX3NldGtleSwKKwkuZW5jcnlw dCA9IHJpc2N2NjRfYWVzX3h0c19lbmNyeXB0LAorCS5kZWNyeXB0ID0gcmlzY3Y2NF9hZXNfeHRz X2RlY3J5cHQsCisJLm1pbl9rZXlzaXplID0gMiAqIEFFU19NSU5fS0VZX1NJWkUsCisJLm1heF9r ZXlzaXplID0gMiAqIEFFU19NQVhfS0VZX1NJWkUsCisJLml2c2l6ZSA9IEFFU19CTE9DS19TSVpF LAorCS5jaHVua3NpemUgPSBBRVNfQkxPQ0tfU0laRSwKKwkud2Fsa3NpemUgPSA0ICogQUVTX0JM T0NLX1NJWkUsIC8qIG1hdGNoZXMgTE1VTD00ICovCisJLmJhc2UgPSB7CisJCS5jcmFfYmxvY2tz aXplID0gQUVTX0JMT0NLX1NJWkUsCisJCS5jcmFfY3R4c2l6ZSA9IHNpemVvZihzdHJ1Y3Qgcmlz Y3Y2NF9hZXNfeHRzX2N0eCksCisJCS5jcmFfcHJpb3JpdHkgPSAzMDAsCisJCS5jcmFfbmFtZSA9 ICJ4dHMoYWVzKSIsCisJCS5jcmFfZHJpdmVyX25hbWUgPSAieHRzLWFlcy1yaXNjdjY0LXp2a25l ZC16dmJiLXp2a2ciLAorCQkuY3JhX21vZHVsZSA9IFRISVNfTU9EVUxFLAorCX0sCit9OworCitz dGF0aWMgaW5saW5lIGJvb2wgcmlzY3Y2NF9hZXNfeHRzX3N1cHBvcnRlZCh2b2lkKQoreworCXJl dHVybiByaXNjdl9pc2FfZXh0ZW5zaW9uX2F2YWlsYWJsZShOVUxMLCBaVkJCKSAmJgorCSAgICAg ICByaXNjdl9pc2FfZXh0ZW5zaW9uX2F2YWlsYWJsZShOVUxMLCBaVktHKSAmJgorCSAgICAgICBy aXNjdl92ZWN0b3JfdmxlbigpIDwgMjA0OCAvKiBJbXBsZW1lbnRhdGlvbiBsaW1pdGF0aW9uICov OworfQorCitzdGF0aWMgaW50IF9faW5pdCByaXNjdjY0X2Flc19tb2RfaW5pdCh2b2lkKQorewor CWludCBlcnIgPSAtRU5PREVWOworCisJaWYgKHJpc2N2X2lzYV9leHRlbnNpb25fYXZhaWxhYmxl KE5VTEwsIFpWS05FRCkgJiYKKwkgICAgcmlzY3ZfdmVjdG9yX3ZsZW4oKSA+PSAxMjgpIHsKKwkJ ZXJyID0gY3J5cHRvX3JlZ2lzdGVyX2FsZygmcmlzY3Y2NF96dmtuZWRfYWVzX2NpcGhlcl9hbGcp OworCQlpZiAoZXJyKQorCQkJcmV0dXJuIGVycjsKKworCQllcnIgPSBjcnlwdG9fcmVnaXN0ZXJf c2tjaXBoZXJzKAorCQkJcmlzY3Y2NF96dmtuZWRfYWVzX3NrY2lwaGVyX2FsZ3MsCisJCQlBUlJB WV9TSVpFKHJpc2N2NjRfenZrbmVkX2Flc19za2NpcGhlcl9hbGdzKSk7CisJCWlmIChlcnIpCisJ CQlnb3RvIHVucmVnaXN0ZXJfenZrbmVkX2NpcGhlcl9hbGc7CisKKwkJaWYgKHJpc2N2X2lzYV9l eHRlbnNpb25fYXZhaWxhYmxlKE5VTEwsIFpWS0IpKSB7CisJCQllcnIgPSBjcnlwdG9fcmVnaXN0 ZXJfc2tjaXBoZXIoCisJCQkJJnJpc2N2NjRfenZrbmVkX3p2a2JfYWVzX3NrY2lwaGVyX2FsZyk7 CisJCQlpZiAoZXJyKQorCQkJCWdvdG8gdW5yZWdpc3Rlcl96dmtuZWRfc2tjaXBoZXJfYWxnczsK KwkJfQorCisJCWlmIChyaXNjdjY0X2Flc194dHNfc3VwcG9ydGVkKCkpIHsKKwkJCWVyciA9IGNy eXB0b19yZWdpc3Rlcl9za2NpcGhlcigKKwkJCQkmcmlzY3Y2NF96dmtuZWRfenZiYl96dmtnX2Fl c19za2NpcGhlcl9hbGcpOworCQkJaWYgKGVycikKKwkJCQlnb3RvIHVucmVnaXN0ZXJfenZrbmVk X3p2a2Jfc2tjaXBoZXJfYWxnOworCQl9CisJfQorCisJcmV0dXJuIGVycjsKKwordW5yZWdpc3Rl cl96dmtuZWRfenZrYl9za2NpcGhlcl9hbGc6CisJaWYgKHJpc2N2X2lzYV9leHRlbnNpb25fYXZh aWxhYmxlKE5VTEwsIFpWS0IpKQorCQljcnlwdG9fdW5yZWdpc3Rlcl9za2NpcGhlcigmcmlzY3Y2 NF96dmtuZWRfenZrYl9hZXNfc2tjaXBoZXJfYWxnKTsKK3VucmVnaXN0ZXJfenZrbmVkX3NrY2lw aGVyX2FsZ3M6CisJY3J5cHRvX3VucmVnaXN0ZXJfc2tjaXBoZXJzKHJpc2N2NjRfenZrbmVkX2Fl c19za2NpcGhlcl9hbGdzLAorCQkJCSAgICBBUlJBWV9TSVpFKHJpc2N2NjRfenZrbmVkX2Flc19z a2NpcGhlcl9hbGdzKSk7Cit1bnJlZ2lzdGVyX3p2a25lZF9jaXBoZXJfYWxnOgorCWNyeXB0b191 bnJlZ2lzdGVyX2FsZygmcmlzY3Y2NF96dmtuZWRfYWVzX2NpcGhlcl9hbGcpOworCXJldHVybiBl cnI7Cit9CisKK3N0YXRpYyB2b2lkIF9fZXhpdCByaXNjdjY0X2Flc19tb2RfZXhpdCh2b2lkKQor eworCWlmIChyaXNjdjY0X2Flc194dHNfc3VwcG9ydGVkKCkpCisJCWNyeXB0b191bnJlZ2lzdGVy X3NrY2lwaGVyKCZyaXNjdjY0X3p2a25lZF96dmJiX3p2a2dfYWVzX3NrY2lwaGVyX2FsZyk7CisJ aWYgKHJpc2N2X2lzYV9leHRlbnNpb25fYXZhaWxhYmxlKE5VTEwsIFpWS0IpKQorCQljcnlwdG9f dW5yZWdpc3Rlcl9za2NpcGhlcigmcmlzY3Y2NF96dmtuZWRfenZrYl9hZXNfc2tjaXBoZXJfYWxn KTsKKwljcnlwdG9fdW5yZWdpc3Rlcl9za2NpcGhlcnMocmlzY3Y2NF96dmtuZWRfYWVzX3NrY2lw aGVyX2FsZ3MsCisJCQkJICAgIEFSUkFZX1NJWkUocmlzY3Y2NF96dmtuZWRfYWVzX3NrY2lwaGVy X2FsZ3MpKTsKKwljcnlwdG9fdW5yZWdpc3Rlcl9hbGcoJnJpc2N2NjRfenZrbmVkX2Flc19jaXBo ZXJfYWxnKTsKK30KKworbW9kdWxlX2luaXQocmlzY3Y2NF9hZXNfbW9kX2luaXQpOworbW9kdWxl X2V4aXQocmlzY3Y2NF9hZXNfbW9kX2V4aXQpOworCitNT0RVTEVfREVTQ1JJUFRJT04oIkFFUy1F Q0IvQ0JDL0NUUi9YVFMgKFJJU0MtViBhY2NlbGVyYXRlZCkiKTsKK01PRFVMRV9BVVRIT1IoIkpl cnJ5IFNoaWggPGplcnJ5LnNoaWhAc2lmaXZlLmNvbT4iKTsKK01PRFVMRV9MSUNFTlNFKCJHUEwi KTsKK01PRFVMRV9BTElBU19DUllQVE8oImFlcyIpOworTU9EVUxFX0FMSUFTX0NSWVBUTygiZWNi KGFlcykiKTsKK01PRFVMRV9BTElBU19DUllQVE8oImNiYyhhZXMpIik7CitNT0RVTEVfQUxJQVNf Q1JZUFRPKCJjdHIoYWVzKSIpOworTU9EVUxFX0FMSUFTX0NSWVBUTygieHRzKGFlcykiKTsKZGlm ZiAtLWdpdCBhL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC16dmJiLXp2a2cu UyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC16dmJiLXp2a2cuUwpuZXcg ZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAwLi40MWViNjE4ZThhNWQ5Ci0tLSAv ZGV2L251bGwKKysrIGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZrbmVkLXp2YmIt enZrZy5TCkBAIC0wLDAgKzEsMzAwIEBACisvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBh Y2hlLTIuMCBPUiBCU0QtMi1DbGF1c2UgKi8KKy8vCisvLyBUaGlzIGZpbGUgaXMgZHVhbC1saWNl bnNlZCwgbWVhbmluZyB0aGF0IHlvdSBjYW4gdXNlIGl0IHVuZGVyIHlvdXIKKy8vIGNob2ljZSBv ZiBlaXRoZXIgb2YgdGhlIGZvbGxvd2luZyB0d28gbGljZW5zZXM6CisvLworLy8gQ29weXJpZ2h0 IDIwMjMgVGhlIE9wZW5TU0wgUHJvamVjdCBBdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgor Ly8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSAyLjAgKHRoZSAiTGljZW5z ZSIpLiBZb3UgY2FuIG9idGFpbgorLy8gYSBjb3B5IGluIHRoZSBmaWxlIExJQ0VOU0UgaW4gdGhl IHNvdXJjZSBkaXN0cmlidXRpb24gb3IgYXQKKy8vIGh0dHBzOi8vd3d3Lm9wZW5zc2wub3JnL3Nv dXJjZS9saWNlbnNlLmh0bWwKKy8vCisvLyBvcgorLy8KKy8vIENvcHlyaWdodCAoYykgMjAyMywg SmVycnkgU2hpaCA8amVycnkuc2hpaEBzaWZpdmUuY29tPgorLy8gQ29weXJpZ2h0IDIwMjQgR29v Z2xlIExMQworLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBh bmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1v ZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29u ZGl0aW9ucworLy8gYXJlIG1ldDoKKy8vIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29k ZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyAgICBub3RpY2UsIHRoaXMgbGlz dCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAyLiBSZWRp c3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHly aWdodAorLy8gICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxv d2luZyBkaXNjbGFpbWVyIGluIHRoZQorLy8gICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIg bWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KKy8vCisvLyBUSElTIFNP RlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVU T1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElO Q0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBP RiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9T RSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dO RVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElO Q0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdF UyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJT VElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJ VFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQor Ly8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJ TElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJ U0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVO IElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGUg Z2VuZXJhdGVkIGNvZGUgb2YgdGhpcyBmaWxlIGRlcGVuZHMgb24gdGhlIGZvbGxvd2luZyBSSVND LVYgZXh0ZW5zaW9uczoKKy8vIC0gUlY2NEkKKy8vIC0gUklTQy1WIFZlY3RvciAoJ1YnKSB3aXRo IFZMRU4gPj0gMTI4ICYmIFZMRU4gPCAyMDQ4CisvLyAtIFJJU0MtViBWZWN0b3IgQUVTIGJsb2Nr IGNpcGhlciBleHRlbnNpb24gKCdadmtuZWQnKQorLy8gLSBSSVNDLVYgVmVjdG9yIEJpdC1tYW5p cHVsYXRpb24gZXh0ZW5zaW9uICgnWnZiYicpCisvLyAtIFJJU0MtViBWZWN0b3IgR0NNL0dNQUMg ZXh0ZW5zaW9uICgnWnZrZycpCisKKyNpbmNsdWRlIDxsaW51eC9saW5rYWdlLmg+CisKKy50ZXh0 Cisub3B0aW9uIGFyY2gsICt6dmtuZWQsICt6dmJiLCArenZrZworCisjaW5jbHVkZSAiYWVzLW1h Y3Jvcy5TIgorCisjZGVmaW5lIEtFWVAJCWEwCisjZGVmaW5lIElOUAkJYTEKKyNkZWZpbmUgT1VU UAkJYTIKKyNkZWZpbmUgTEVOCQlhMworI2RlZmluZSBUV0VBS1AJCWE0CisKKyNkZWZpbmUgTEVO MzIJCWE1CisjZGVmaW5lIFRBSUxfTEVOCWE2CisjZGVmaW5lIFZMCQlhNworCisvLyB2MS12MTUg Y29udGFpbiB0aGUgQUVTIHJvdW5kIGtleXMsIGJ1dCB0aGV5IGFyZSB1c2VkIGZvciB0ZW1wb3Jh cmllcyBiZWZvcmUKKy8vIHRoZSBBRVMgcm91bmQga2V5cyBoYXZlIGJlZW4gbG9hZGVkLgorI2Rl ZmluZSBUV0VBS1MJCXYxNgkvLyBMTVVMPTQgKG1vc3Qgb2YgdGhlIHRpbWUpCisjZGVmaW5lIFRX RUFLU19CUkVWCXYyMAkvLyBMTVVMPTQgKG1vc3Qgb2YgdGhlIHRpbWUpCisjZGVmaW5lIE1VTFRT X0JSRVYJdjI0CS8vIExNVUw9NCAobW9zdCBvZiB0aGUgdGltZSkKKyNkZWZpbmUgVE1QMAkJdjI4 CisjZGVmaW5lIFRNUDEJCXYyOQorI2RlZmluZSBUTVAyCQl2MzAKKyNkZWZpbmUgVE1QMwkJdjMx CisKKy8vIHh0c19pbml0IGluaXRpYWxpemVzIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgorLy8KKy8v CVRXRUFLUzogTiAxMjgtYml0IHR3ZWFrcyBUKih4XmkpIGZvciBpIGluIDAuLihOIC0gMSkKKy8v CVRXRUFLU19CUkVWOiBzYW1lIGFzIFRXRUFLUywgYnV0IGJpdC1yZXZlcnNlZAorLy8JTVVMVFNf QlJFVjogTiAxMjgtYml0IHZhbHVlcyB4Xk4sIGJpdC1yZXZlcnNlZC4gIE9ubHkgaWYgTiA+IDEu CisvLworLy8gTiBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgd2lsbCBiZSBw cm9jZXNzZWQgcGVyIGxvb3AgaXRlcmF0aW9uLAorLy8gY29tcHV0ZWQgdXNpbmcgdnNldHZsaS4K Ky8vCisvLyBUaGUgZmllbGQgY29udmVudGlvbiB1c2VkIGJ5IFhUUyBpcyB0aGUgc2FtZSBhcyB0 aGF0IG9mIEdIQVNILCBidXQgd2l0aCB0aGUKKy8vIGJpdHMgcmV2ZXJzZWQgd2l0aGluIGVhY2gg Ynl0ZS4gIFRoZSB6dmtnIGV4dGVuc2lvbiBwcm92aWRlcyB0aGUgdmdtdWwKKy8vIGluc3RydWN0 aW9uIHdoaWNoIGRvZXMgbXVsdGlwbGljYXRpb24gaW4gdGhpcyBmaWVsZC4gIFRoZXJlZm9yZSwg Zm9yIHR3ZWFrCisvLyBjb21wdXRhdGlvbiB3ZSB1c2UgdmdtdWwgdG8gZG8gbXVsdGlwbGljYXRp b25zIGluIHBhcmFsbGVsLCBpbnN0ZWFkIG9mCisvLyBzZXJpYWxseSBtdWx0aXBseWluZyBieSB4 IHVzaW5nIHNoaWZ0aW5nK3hvcmluZy4gIE5vdGUgdGhhdCBmb3IgdGhpcyB0byB3b3JrLAorLy8g dGhlIGlucHV0cyBhbmQgb3V0cHV0cyB0byB2Z211bCBtdXN0IGJlIGJpdC1yZXZlcnNlZCAod2Ug ZG8gaXQgd2l0aCB2YnJldjgpLgorLm1hY3JvCXh0c19pbml0CisKKwkvLyBMb2FkIHRoZSBmaXJz dCB0d2VhayBULgorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwgbTEsIHRhLCBtYQorCXZsZTMyLnYJ CVRXRUFLUywgKFRXRUFLUCkKKworCS8vIElmIHRoZXJlJ3Mgb25seSBvbmUgYmxvY2sgKG9yIG5v IGJsb2NrcyBhdCBhbGwpLCB0aGVuIHNraXAgdGhlIHR3ZWFrCisJLy8gc2VxdWVuY2UgY29tcHV0 YXRpb24gYmVjYXVzZSAoYXQgbW9zdCkgVCBpdHNlbGYgaXMgbmVlZGVkLgorCWxpCQl0MCwgMTYK KwlibGUJCUxFTiwgdDAsIC5MaW5pdF9zaW5nbGVfYmxvY2tcQAorCisJLy8gU2F2ZSBhIGNvcHkg b2YgVCBiaXQtcmV2ZXJzZWQgaW4gdjEyLgorCXZicmV2OC52CXYxMiwgVFdFQUtTCisKKwkvLwor CS8vIEdlbmVyYXRlIHheaSBmb3IgaSBpbiAwLi4oTiAtIDEpLCBpLmUuIDEyOC1iaXQgdmFsdWVz IDEgPDwgaSBhc3N1bWluZworCS8vIHRoYXQgTiA8PSAxMjguICBUaG91Z2gsIHRoaXMgY29kZSBh Y3R1YWxseSByZXF1aXJlcyBOIDwgNjQgKG9yCisJLy8gZXF1aXZhbGVudGx5IFZMRU4gPCAyMDQ4 KSBkdWUgdG8gdGhlIHVzZSBvZiA2NC1iaXQgaW50ZXJtZWRpYXRlCisJLy8gdmFsdWVzIGhlcmUg YW5kIGluIHRoZSB4Xk4gY29tcHV0YXRpb24gbGF0ZXIuCisJLy8KKwl2c2V0dmxpCQlWTCwgTEVO MzIsIGUzMiwgbTQsIHRhLCBtYQorCXNybGkJCXQwLCBWTCwgMgkvLyB0MCA9IE4gKG51bSBibG9j a3MpCisJLy8gR2VuZXJhdGUgdHdvIHNlcXVlbmNlcywgZWFjaCB3aXRoIE4gMzItYml0IHZhbHVl czoKKwkvLyB2MD1bMSwgMSwgMSwgLi4uXSBhbmQgdjE9WzAsIDEsIDIsIC4uLl0uCisJdnNldHZs aQkJemVybywgdDAsIGUzMiwgbTEsIHRhLCBtYQorCXZtdi52LmkJCXYwLCAxCisJdmlkLnYJCXYx CisJLy8gVXNlIHZ6ZXh0IHRvIHplcm8tZXh0ZW5kIHRoZSBzZXF1ZW5jZXMgdG8gNjQgYml0cy4g IFJlaW50ZXJwcmV0IHRoZW0KKwkvLyBhcyB0d28gc2VxdWVuY2VzLCBlYWNoIHdpdGggMipOIDMy LWJpdCB2YWx1ZXM6CisJLy8gdjI9WzEsIDAsIDEsIDAsIDEsIDAsIC4uLl0gYW5kIHY0PVswLCAw LCAxLCAwLCAyLCAwLCAuLi5dLgorCXZzZXR2bGkJCXplcm8sIHQwLCBlNjQsIG0yLCB0YSwgbWEK Kwl2emV4dC52ZjIJdjIsIHYwCisJdnpleHQudmYyCXY0LCB2MQorCXNsbGkJCXQxLCB0MCwgMQkv LyB0MSA9IDIqTgorCXZzZXR2bGkJCXplcm8sIHQxLCBlMzIsIG0yLCB0YSwgbWEKKwkvLyBVc2Ug dndzbGwgdG8gY29tcHV0ZSBbMTw8MCwgMDw8MCwgMTw8MSwgMDw8MCwgMTw8MiwgMDw8MCwgLi4u XSwKKwkvLyB3aWRlbmluZyB0byA2NCBiaXRzIHBlciBlbGVtZW50LiAgV2hlbiByZWludGVycHJl dGVkIGFzIE4gMTI4LWJpdAorCS8vIHZhbHVlcywgdGhpcyBpcyB0aGUgbmVlZGVkIHNlcXVlbmNl IG9mIDEyOC1iaXQgdmFsdWVzIDEgPDwgaSAoeF5pKS4KKwl2d3NsbC52dgl2OCwgdjIsIHY0CisK KwkvLyBDb3B5IHRoZSBiaXQtcmV2ZXJzZWQgVCB0byBhbGwgTiBlbGVtZW50cyBvZiBUV0VBS1Nf QlJFViwgdGhlbgorCS8vIG11bHRpcGx5IGJ5IHheaS4gIFRoaXMgZ2l2ZXMgdGhlIHNlcXVlbmNl IFQqKHheaSksIGJpdC1yZXZlcnNlZC4KKwl2c2V0dmxpCQl6ZXJvLCBMRU4zMiwgZTMyLCBtNCwg dGEsIG1hCisJdm12LnYuaQkJVFdFQUtTX0JSRVYsIDAKKwl2YWVzei52cwlUV0VBS1NfQlJFViwg djEyCisJdmJyZXY4LnYJdjgsIHY4CisJdmdtdWwudnYJVFdFQUtTX0JSRVYsIHY4CisKKwkvLyBT YXZlIGEgY29weSBvZiB0aGUgc2VxdWVuY2UgVCooeF5pKSB3aXRoIHRoZSBiaXQgcmV2ZXJzYWwg dW5kb25lLgorCXZicmV2OC52CVRXRUFLUywgVFdFQUtTX0JSRVYKKworCS8vIEdlbmVyYXRlIE4g Y29waWVzIG9mIHheTiwgaS5lLiAxMjgtYml0IHZhbHVlcyAxIDw8IE4sIGJpdC1yZXZlcnNlZC4K KwlsaQkJdDEsIDEKKwlzbGwJCXQxLCB0MSwgdDAJLy8gdDEgPSAxIDw8IE4KKwl2c2V0aXZsaQl6 ZXJvLCAyLCBlNjQsIG0xLCB0YSwgbWEKKwl2bXYudi5pCQl2MCwgMAorCXZzZXRpdmxpCXplcm8s IDEsIGU2NCwgbTEsIHR1LCBtYQorCXZtdi52LngJCXYwLCB0MQorCXZicmV2OC52CXYwLCB2MAor CXZzZXR2bGkJCXplcm8sIExFTjMyLCBlMzIsIG00LCB0YSwgbWEKKwl2bXYudi5pCQlNVUxUU19C UkVWLCAwCisJdmFlc3oudnMJTVVMVFNfQlJFViwgdjAKKworCWoJCS5MaW5pdF9kb25lXEAKKwor Lkxpbml0X3NpbmdsZV9ibG9ja1xAOgorCXZicmV2OC52CVRXRUFLU19CUkVWLCBUV0VBS1MKKy5M aW5pdF9kb25lXEA6CisuZW5kbQorCisvLyBTZXQgdGhlIGZpcnN0IDEyOCBiaXRzIG9mIE1VTFRT X0JSRVYgdG8gMHg0MCwgaS5lLiAneCcgYml0LXJldmVyc2VkLiAgVGhpcyBpcworLy8gdGhlIG11 bHRpcGxpZXIgcmVxdWlyZWQgdG8gYWR2YW5jZSB0aGUgdHdlYWsgYnkgb25lLgorLm1hY3JvCWxv YWRfeAorCWxpCQl0MCwgMHg0MAorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwgbTEsIHRhLCBtYQor CXZtdi52LmkJCU1VTFRTX0JSRVYsIDAKKwl2c2V0aXZsaQl6ZXJvLCAxLCBlOCwgbTEsIHR1LCBt YQorCXZtdi52LngJCU1VTFRTX0JSRVYsIHQwCisuZW5kbQorCisubWFjcm8JX19hZXNfeHRzX2Ny eXB0CWVuYywga2V5bGVuCisJLy8gV2l0aCAxNiA8IGxlbiA8PSAzMSwgdGhlcmUncyBubyBtYWlu IGxvb3AsIGp1c3QgY2lwaGVydGV4dCBzdGVhbGluZy4KKwliZXF6CQlMRU4zMiwgLkxjdHNfd2l0 aG91dF9tYWluX2xvb3BcQAorCisJdnNldHZsaQkJVkwsIExFTjMyLCBlMzIsIG00LCB0YSwgbWEK KwlqCQkyZgorMToKKwl2c2V0dmxpCQlWTCwgTEVOMzIsIGUzMiwgbTQsIHRhLCBtYQorCS8vIENv bXB1dGUgdGhlIG5leHQgc2VxdWVuY2Ugb2YgdHdlYWtzIGJ5IG11bHRpcGx5aW5nIHRoZSBwcmV2 aW91cworCS8vIHNlcXVlbmNlIGJ5IHheTi4gIFN0b3JlIHRoZSByZXN1bHQgaW4gYm90aCBiaXQt cmV2ZXJzZWQgb3JkZXIgYW5kCisJLy8gcmVndWxhciBvcmRlciAoaS5lLiB3aXRoIHRoZSBiaXQg cmV2ZXJzYWwgdW5kb25lKS4KKwl2Z211bC52dglUV0VBS1NfQlJFViwgTVVMVFNfQlJFVgorCXZi cmV2OC52CVRXRUFLUywgVFdFQUtTX0JSRVYKKzI6CisJLy8gRW5jcnlwdCBvciBkZWNyeXB0IFZM LzQgYmxvY2tzLgorCXZsZTMyLnYJCVRNUDAsIChJTlApCisJdnhvci52dgkJVE1QMCwgVE1QMCwg VFdFQUtTCisJYWVzX2NyeXB0CVRNUDAsIFxlbmMsIFxrZXlsZW4KKwl2eG9yLnZ2CQlUTVAwLCBU TVAwLCBUV0VBS1MKKwl2c2UzMi52CQlUTVAwLCAoT1VUUCkKKworCS8vIFVwZGF0ZSB0aGUgcG9p bnRlcnMgYW5kIHRoZSByZW1haW5pbmcgbGVuZ3RoLgorCXNsbGkJCXQwLCBWTCwgMgorCWFkZAkJ SU5QLCBJTlAsIHQwCisJYWRkCQlPVVRQLCBPVVRQLCB0MAorCXN1YgkJTEVOMzIsIExFTjMyLCBW TAorCisJLy8gUmVwZWF0IGlmIG1vcmUgYmxvY2tzIHJlbWFpbi4KKwlibmV6CQlMRU4zMiwgMWIK KworLkxtYWluX2xvb3BfZG9uZVxAOgorCWxvYWRfeAorCisJLy8gQ29tcHV0ZSB0aGUgbmV4dCB0 d2Vhay4KKwlhZGRpCQl0MCwgVkwsIC00CisJdnNldGl2bGkJemVybywgNCwgZTMyLCBtNCwgdGEs IG1hCisJdnNsaWRlZG93bi52eAlUV0VBS1NfQlJFViwgVFdFQUtTX0JSRVYsIHQwCS8vIEV4dHJh Y3QgbGFzdCB0d2VhaworCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwgbTEsIHRhLCBtYQorCXZnbXVs LnZ2CVRXRUFLU19CUkVWLCBNVUxUU19CUkVWCQkvLyBBZHZhbmNlIHRvIG5leHQgdHdlYWsKKwor CWJuZXoJCVRBSUxfTEVOLCAuTGN0c1xACisKKwkvLyBVcGRhdGUgKlRXRUFLUCB0byBjb250YWlu IHRoZSBuZXh0IHR3ZWFrLgorCXZicmV2OC52CVRXRUFLUywgVFdFQUtTX0JSRVYKKwl2c2UzMi52 CQlUV0VBS1MsIChUV0VBS1ApCisJcmV0CisKKy5MY3RzX3dpdGhvdXRfbWFpbl9sb29wXEA6CisJ bG9hZF94CisuTGN0c1xAOgorCS8vIFRXRUFLU19CUkVWIG5vdyBjb250YWlucyB0aGUgbmV4dCB0 d2Vhay4gIENvbXB1dGUgdGhlIG9uZSBhZnRlciB0aGF0LgorCXZzZXRpdmxpCXplcm8sIDQsIGUz MiwgbTEsIHRhLCBtYQorCXZtdi52LnYJCVRNUDAsIFRXRUFLU19CUkVWCisJdmdtdWwudnYJVE1Q MCwgTVVMVFNfQlJFVgorCS8vIFVuZG8gdGhlIGJpdCByZXZlcnNhbCBvZiB0aGUgbmV4dCB0d28g dHdlYWtzIGFuZCBzdG9yZSB0aGVtIGluIFRNUDEKKwkvLyBhbmQgVE1QMiwgc3VjaCB0aGF0IFRN UDEgaXMgdGhlIGZpcnN0IG5lZWRlZCBhbmQgVE1QMiB0aGUgc2Vjb25kLgorLmlmIFxlbmMKKwl2 YnJldjgudglUTVAxLCBUV0VBS1NfQlJFVgorCXZicmV2OC52CVRNUDIsIFRNUDAKKy5lbHNlCisJ dmJyZXY4LnYJVE1QMSwgVE1QMAorCXZicmV2OC52CVRNUDIsIFRXRUFLU19CUkVWCisuZW5kaWYK KworCS8vIEVuY3J5cHQvZGVjcnlwdCB0aGUgbGFzdCBmdWxsIGJsb2NrLgorCXZsZTMyLnYJCVRN UDAsIChJTlApCisJdnhvci52dgkJVE1QMCwgVE1QMCwgVE1QMQorCWFlc19jcnlwdAlUTVAwLCBc ZW5jLCBca2V5bGVuCisJdnhvci52dgkJVE1QMCwgVE1QMCwgVE1QMQorCisJLy8gU3dhcCB0aGUg Zmlyc3QgVEFJTF9MRU4gYnl0ZXMgb2YgdGhlIGFib3ZlIHJlc3VsdCB3aXRoIHRoZSB0YWlsLgor CS8vIE5vdGUgdGhhdCB0byBzdXBwb3J0IGluLXBsYWNlIGVuY3J5cHRpb24vZGVjcnlwdGlvbiwg dGhlIGxvYWQgZnJvbQorCS8vIHRoZSBpbnB1dCB0YWlsIG11c3QgaGFwcGVuIGJlZm9yZSB0aGUg c3RvcmUgdG8gdGhlIG91dHB1dCB0YWlsLgorCWFkZGkJCXQwLCBJTlAsIDE2CisJYWRkaQkJdDEs IE9VVFAsIDE2CisJdm12LnYudgkJVE1QMywgVE1QMAorCXZzZXR2bGkJCXplcm8sIFRBSUxfTEVO LCBlOCwgbTEsIHR1LCBtYQorCXZsZTgudgkJVE1QMCwgKHQwKQorCXZzZTgudgkJVE1QMywgKHQx KQorCisJLy8gRW5jcnlwdC9kZWNyeXB0IGFnYWluIGFuZCBzdG9yZSB0aGUgbGFzdCBmdWxsIGJs b2NrLgorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwgbTEsIHRhLCBtYQorCXZ4b3IudnYJCVRNUDAs IFRNUDAsIFRNUDIKKwlhZXNfY3J5cHQJVE1QMCwgXGVuYywgXGtleWxlbgorCXZ4b3IudnYJCVRN UDAsIFRNUDAsIFRNUDIKKwl2c2UzMi52CQlUTVAwLCAoT1VUUCkKKworCXJldAorLmVuZG0KKwor Lm1hY3JvCWFlc194dHNfY3J5cHQJZW5jCisKKwkvLyBDaGVjayB3aGV0aGVyIHRoZSBsZW5ndGgg aXMgYSBtdWx0aXBsZSBvZiB0aGUgQUVTIGJsb2NrIHNpemUuCisJYW5kaQkJVEFJTF9MRU4sIExF TiwgMTUKKwliZXF6CQlUQUlMX0xFTiwgMWYKKworCS8vIFRoZSBsZW5ndGggaXNuJ3QgYSBtdWx0 aXBsZSBvZiB0aGUgQUVTIGJsb2NrIHNpemUsIHNvIGNpcGhlcnRleHQKKwkvLyBzdGVhbGluZyB3 aWxsIGJlIHJlcXVpcmVkLiAgQ2lwaGVydGV4dCBzdGVhbGluZyBpbnZvbHZlcyBzcGVjaWFsCisJ Ly8gaGFuZGxpbmcgb2YgdGhlIHBhcnRpYWwgYmxvY2sgYW5kIHRoZSBsYXN0IGZ1bGwgYmxvY2ss IHNvIHN1YnRyYWN0CisJLy8gdGhlIGxlbmd0aCBvZiBib3RoIGZyb20gdGhlIGxlbmd0aCB0byBi ZSBwcm9jZXNzZWQgaW4gdGhlIG1haW4gbG9vcC4KKwlzdWIJCUxFTiwgTEVOLCBUQUlMX0xFTgor CWFkZGkJCUxFTiwgTEVOLCAtMTYKKzE6CisJc3JsaQkJTEVOMzIsIExFTiwgMgorCS8vIExFTiBh bmQgTEVOMzIgbm93IGNvbnRhaW4gdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgYmxvY2tzIHRoYXQg d2lsbCBiZQorCS8vIHByb2Nlc3NlZCBpbiB0aGUgbWFpbiBsb29wLCBpbiBieXRlcyBhbmQgMzIt Yml0IHdvcmRzIHJlc3BlY3RpdmVseS4KKworCXh0c19pbml0CisJYWVzX2JlZ2luCUtFWVAsIDEx MWYsIDIyMmYKKwlfX2Flc194dHNfY3J5cHQJXGVuYywgMjU2CisxMTE6CisJX19hZXNfeHRzX2Ny eXB0CVxlbmMsIDEyOAorMjIyOgorCV9fYWVzX3h0c19jcnlwdAlcZW5jLCAxOTIKKy5lbmRtCisK Ky8vIHZvaWQgYWVzX3h0c19lbmNyeXB0X3p2a25lZF96dmJiX3p2a2coY29uc3Qgc3RydWN0IGNy eXB0b19hZXNfY3R4ICprZXksCisvLwkJCQkJIGNvbnN0IHU4ICppbiwgdTggKm91dCwgc2l6ZV90 IGxlbiwKKy8vCQkJCQkgdTggdHdlYWtbMTZdKTsKKy8vCisvLyB8a2V5fCBpcyB0aGUgZGF0YSBr ZXkuICB8dHdlYWt8IGNvbnRhaW5zIHRoZSBuZXh0IHR3ZWFrOyB0aGUgZW5jcnlwdGlvbiBvZgor Ly8gdGhlIG9yaWdpbmFsIElWIHdpdGggdGhlIHR3ZWFrIGtleSB3YXMgYWxyZWFkeSBkb25lLiAg VGhpcyBmdW5jdGlvbiBzdXBwb3J0cworLy8gaW5jcmVtZW50YWwgY29tcHV0YXRpb24sIGJ1dCB8 bGVufCBtdXN0IGFsd2F5cyBiZSA+PSAxNiAoQUVTX0JMT0NLX1NJWkUpLCBhbmQKKy8vIHxsZW58 IG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNiBleGNlcHQgb24gdGhlIGxhc3QgY2FsbC4gIElmIHxs ZW58IGlzIGEKKy8vIG11bHRpcGxlIG9mIDE2LCB0aGVuIHRoaXMgZnVuY3Rpb24gdXBkYXRlcyB8 dHdlYWt8IHRvIGNvbnRhaW4gdGhlIG5leHQgdHdlYWsuCitTWU1fRlVOQ19TVEFSVChhZXNfeHRz X2VuY3J5cHRfenZrbmVkX3p2YmJfenZrZykKKwlhZXNfeHRzX2NyeXB0CTEKK1NZTV9GVU5DX0VO RChhZXNfeHRzX2VuY3J5cHRfenZrbmVkX3p2YmJfenZrZykKKworLy8gU2FtZSBwcm90b3R5cGUg YW5kIGNhbGxpbmcgY29udmVudGlvbiBhcyB0aGUgZW5jcnlwdGlvbiBmdW5jdGlvbgorU1lNX0ZV TkNfU1RBUlQoYWVzX3h0c19kZWNyeXB0X3p2a25lZF96dmJiX3p2a2cpCisJYWVzX3h0c19jcnlw dAkwCitTWU1fRlVOQ19FTkQoYWVzX3h0c19kZWNyeXB0X3p2a25lZF96dmJiX3p2a2cpCmRpZmYg LS1naXQgYS9hcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlzY3Y2NC16dmtuZWQtenZrYi5TIGIvYXJj aC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZrbmVkLXp2a2IuUwpuZXcgZmlsZSBtb2RlIDEw MDY0NAppbmRleCAwMDAwMDAwMDAwMDAwLi5jNGE4NGU4NGU2MGRmCi0tLSAvZGV2L251bGwKKysr IGIvYXJjaC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZrbmVkLXp2a2IuUwpAQCAtMCwwICsx LDE0NiBAQAorLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAgT1IgQlNELTIt Q2xhdXNlICovCisvLworLy8gVGhpcyBmaWxlIGlzIGR1YWwtbGljZW5zZWQsIG1lYW5pbmcgdGhh dCB5b3UgY2FuIHVzZSBpdCB1bmRlciB5b3VyCisvLyBjaG9pY2Ugb2YgZWl0aGVyIG9mIHRoZSBm b2xsb3dpbmcgdHdvIGxpY2Vuc2VzOgorLy8KKy8vIENvcHlyaWdodCAyMDIzIFRoZSBPcGVuU1NM IFByb2plY3QgQXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKy8vCisvLyBMaWNlbnNlZCB1 bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgMi4wICh0aGUgIkxpY2Vuc2UiKS4gWW91IGNhbiBvYnRh aW4KKy8vIGEgY29weSBpbiB0aGUgZmlsZSBMSUNFTlNFIGluIHRoZSBzb3VyY2UgZGlzdHJpYnV0 aW9uIG9yIGF0CisvLyBodHRwczovL3d3dy5vcGVuc3NsLm9yZy9zb3VyY2UvbGljZW5zZS5odG1s CisvLworLy8gb3IKKy8vCisvLyBDb3B5cmlnaHQgKGMpIDIwMjMsIEplcnJ5IFNoaWggPGplcnJ5 LnNoaWhAc2lmaXZlLmNvbT4KKy8vIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTEMKKy8vIEFsbCBy aWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2Ug YW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBw ZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKKy8vIGFyZSBt ZXQ6CisvLyAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhl IGFib3ZlIGNvcHlyaWdodAorLy8gICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBh bmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gMi4gUmVkaXN0cmlidXRpb25zIGluIGJp bmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vICAgIG5vdGlj ZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBp biB0aGUKKy8vICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRl ZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURF RCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBB TkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QK Ky8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZ IEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQu IElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9S UyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BF Q0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVU IE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBT RVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJ TlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFC SUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8v IChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBP VVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRI RSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhlIGdlbmVyYXRlZCBjb2RlIG9m IHRoaXMgZmlsZSBkZXBlbmRzIG9uIHRoZSBmb2xsb3dpbmcgUklTQy1WIGV4dGVuc2lvbnM6Cisv LyAtIFJWNjRJCisvLyAtIFJJU0MtViBWZWN0b3IgKCdWJykgd2l0aCBWTEVOID49IDEyOAorLy8g LSBSSVNDLVYgVmVjdG9yIEFFUyBibG9jayBjaXBoZXIgZXh0ZW5zaW9uICgnWnZrbmVkJykKKy8v IC0gUklTQy1WIFZlY3RvciBDcnlwdG9ncmFwaHkgQml0LW1hbmlwdWxhdGlvbiBleHRlbnNpb24g KCdadmtiJykKKworI2luY2x1ZGUgPGxpbnV4L2xpbmthZ2UuaD4KKworLnRleHQKKy5vcHRpb24g YXJjaCwgK3p2a25lZCwgK3p2a2IKKworI2luY2x1ZGUgImFlcy1tYWNyb3MuUyIKKworI2RlZmlu ZSBLRVlQCQlhMAorI2RlZmluZSBJTlAJCWExCisjZGVmaW5lIE9VVFAJCWEyCisjZGVmaW5lIExF TgkJYTMKKyNkZWZpbmUgSVZQCQlhNAorCisjZGVmaW5lIExFTjMyCQlhNQorI2RlZmluZSBWTF9F MzIJCWE2CisjZGVmaW5lIFZMX0JMT0NLUwlhNworCisubWFjcm8JYWVzX2N0cjMyX2NyeXB0CWtl eWxlbgorCS8vIExFTjMyID0gbnVtYmVyIG9mIGJsb2Nrcywgcm91bmRlZCB1cCwgaW4gMzItYml0 IHdvcmRzLgorCWFkZGkJCXQwLCBMRU4sIDE1CisJc3JsaQkJdDAsIHQwLCA0CisJc2xsaQkJTEVO MzIsIHQwLCAyCisKKwkvLyBDcmVhdGUgYSBtYXNrIHRoYXQgc2VsZWN0cyB0aGUgbGFzdCAzMi1i aXQgd29yZCBvZiBlYWNoIDEyOC1iaXQKKwkvLyBibG9jay4gIFRoaXMgaXMgdGhlIHdvcmQgdGhh dCBjb250YWlucyB0aGUgKGJpZy1lbmRpYW4pIGNvdW50ZXIuCisJbGkJCXQwLCAweDg4CisJdnNl dHZsaQkJdDEsIHplcm8sIGU4LCBtMSwgdGEsIG1hCisJdm12LnYueAkJdjAsIHQwCisKKwkvLyBM b2FkIHRoZSBJViBpbnRvIHYzMS4gIFRoZSBsYXN0IDMyLWJpdCB3b3JkIGNvbnRhaW5zIHRoZSBj b3VudGVyLgorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwgbTEsIHRhLCBtYQorCXZsZTMyLnYJCXYz MSwgKElWUCkKKworCS8vIENvbnZlcnQgdGhlIGJpZy1lbmRpYW4gY291bnRlciBpbnRvIGxpdHRs ZS1lbmRpYW4uCisJdnNldGl2bGkJemVybywgNCwgZTMyLCBtMSwgdGEsIG11CisJdnJldjgudgkJ djMxLCB2MzEsIHYwLnQKKworCS8vIFNwbGF0IHRoZSBJViB0byB2MTYgKHdpdGggTE1VTD00KS4g IFRoZSBudW1iZXIgb2YgY29waWVzIGlzIHRoZQorCS8vIG1heGltdW0gbnVtYmVyIG9mIGJsb2Nr cyB0aGF0IHdpbGwgYmUgcHJvY2Vzc2VkIHBlciBpdGVyYXRpb24uCisJdnNldHZsaQkJemVybywg TEVOMzIsIGUzMiwgbTQsIHRhLCBtYQorCXZtdi52LmkJCXYxNiwgMAorCXZhZXN6LnZzCXYxNiwg djMxCisKKwkvLyB2MjAgPSBbeCwgeCwgeCwgMCwgeCwgeCwgeCwgMSwgLi4uXQorCXZpb3RhLm0J CXYyMCwgdjAsIHYwLnQKKwkvLyB2MTYgPSBbSVYwLCBJVjEsIElWMiwgY291bnRlciswLCBJVjAs IElWMSwgSVYyLCBjb3VudGVyKzEsIC4uLl0KKwl2c2V0dmxpCQlWTF9FMzIsIExFTjMyLCBlMzIs IG00LCB0YSwgbXUKKwl2YWRkLnZ2CQl2MTYsIHYxNiwgdjIwLCB2MC50CisKKwlqIDJmCisxOgor CS8vIFNldCB0aGUgbnVtYmVyIG9mIGJsb2NrcyB0byBwcm9jZXNzIGluIHRoaXMgaXRlcmF0aW9u LiAgdmw9VkxfRTMyIGlzCisJLy8gdGhlIGxlbmd0aCBpbiAzMi1iaXQgd29yZHMsIGkuZS4gNCB0 aW1lcyB0aGUgbnVtYmVyIG9mIGJsb2Nrcy4KKwl2c2V0dmxpCQlWTF9FMzIsIExFTjMyLCBlMzIs IG00LCB0YSwgbXUKKworCS8vIEluY3JlbWVudCB0aGUgY291bnRlcnMgYnkgdGhlIG51bWJlciBv ZiBibG9ja3MgcHJvY2Vzc2VkIGluIHRoZQorCS8vIHByZXZpb3VzIGl0ZXJhdGlvbi4KKwl2YWRk LnZ4CQl2MTYsIHYxNiwgVkxfQkxPQ0tTLCB2MC50CisyOgorCS8vIFByZXBhcmUgdGhlIEFFUyBp bnB1dHMgaW50byB2MjQuCisJdm12LnYudgkJdjI0LCB2MTYKKwl2cmV2OC52CQl2MjQsIHYyNCwg djAudAkvLyBDb252ZXJ0IGNvdW50ZXJzIGJhY2sgdG8gYmlnLWVuZGlhbi4KKworCS8vIEVuY3J5 cHQgdGhlIEFFUyBpbnB1dHMgdG8gY3JlYXRlIHRoZSBuZXh0IHBvcnRpb24gb2YgdGhlIGtleXN0 cmVhbS4KKwlhZXNfZW5jcnlwdAl2MjQsIFxrZXlsZW4KKworCS8vIFhPUiB0aGUgZGF0YSB3aXRo IHRoZSBrZXlzdHJlYW0uCisJdnNldHZsaQkJdDAsIExFTiwgZTgsIG00LCB0YSwgbWEKKwl2bGU4 LnYJCXYyMCwgKElOUCkKKwl2eG9yLnZ2CQl2MjAsIHYyMCwgdjI0CisJdnNlOC52CQl2MjAsIChP VVRQKQorCisJLy8gQWR2YW5jZSB0aGUgcG9pbnRlcnMgYW5kIHVwZGF0ZSB0aGUgcmVtYWluaW5n IGxlbmd0aC4KKwlhZGQJCUlOUCwgSU5QLCB0MAorCWFkZAkJT1VUUCwgT1VUUCwgdDAKKwlzdWIJ CUxFTiwgTEVOLCB0MAorCXN1YgkJTEVOMzIsIExFTjMyLCBWTF9FMzIKKwlzcmxpCQlWTF9CTE9D S1MsIFZMX0UzMiwgMgorCisJLy8gUmVwZWF0IGlmIG1vcmUgZGF0YSByZW1haW5zLgorCWJuZXoJ CUxFTiwgMWIKKworCS8vIFVwZGF0ZSAqSVZQIHRvIGNvbnRhaW4gdGhlIG5leHQgY291bnRlci4K Kwl2c2V0aXZsaQl6ZXJvLCA0LCBlMzIsIG0xLCB0YSwgbXUKKwl2YWRkLnZ4CQl2MTYsIHYxNiwg VkxfQkxPQ0tTLCB2MC50CisJdnJldjgudgkJdjE2LCB2MTYsIHYwLnQJLy8gQ29udmVydCBjb3Vu dGVycyBiYWNrIHRvIGJpZy1lbmRpYW4uCisJdnNlMzIudgkJdjE2LCAoSVZQKQorCisJcmV0Cisu ZW5kbQorCisvLyB2b2lkIGFlc19jdHIzMl9jcnlwdF96dmtuZWRfenZrYihjb25zdCBzdHJ1Y3Qg Y3J5cHRvX2Flc19jdHggKmtleSwKKy8vCQkJCSAgICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNp emVfdCBsZW4sCisvLwkJCQkgICAgdTggaXZbMTZdKTsKK1NZTV9GVU5DX1NUQVJUKGFlc19jdHIz Ml9jcnlwdF96dmtuZWRfenZrYikKKwlhZXNfYmVnaW4JS0VZUCwgMTExZiwgMjIyZgorCWFlc19j dHIzMl9jcnlwdAkyNTYKKzExMToKKwlhZXNfY3RyMzJfY3J5cHQJMTI4CisyMjI6CisJYWVzX2N0 cjMyX2NyeXB0CTE5MgorU1lNX0ZVTkNfRU5EKGFlc19jdHIzMl9jcnlwdF96dmtuZWRfenZrYikK ZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC5TIGIvYXJj aC9yaXNjdi9jcnlwdG8vYWVzLXJpc2N2NjQtenZrbmVkLlMKbmV3IGZpbGUgbW9kZSAxMDA2NDQK aW5kZXggMDAwMDAwMDAwMDAwMC4uNmY3ZThiMGYzMTQyMwotLS0gL2Rldi9udWxsCisrKyBiL2Fy Y2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC5TCkBAIC0wLDAgKzEsMTgwIEBACisv KiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMCBPUiBCU0QtMi1DbGF1c2UgKi8K Ky8vCisvLyBUaGlzIGZpbGUgaXMgZHVhbC1saWNlbnNlZCwgbWVhbmluZyB0aGF0IHlvdSBjYW4g dXNlIGl0IHVuZGVyIHlvdXIKKy8vIGNob2ljZSBvZiBlaXRoZXIgb2YgdGhlIGZvbGxvd2luZyB0 d28gbGljZW5zZXM6CisvLworLy8gQ29weXJpZ2h0IDIwMjMgVGhlIE9wZW5TU0wgUHJvamVjdCBB dXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgorLy8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBB cGFjaGUgTGljZW5zZSAyLjAgKHRoZSAiTGljZW5zZSIpLiBZb3UgY2FuIG9idGFpbgorLy8gYSBj b3B5IGluIHRoZSBmaWxlIExJQ0VOU0UgaW4gdGhlIHNvdXJjZSBkaXN0cmlidXRpb24gb3IgYXQK Ky8vIGh0dHBzOi8vd3d3Lm9wZW5zc2wub3JnL3NvdXJjZS9saWNlbnNlLmh0bWwKKy8vCisvLyBv cgorLy8KKy8vIENvcHlyaWdodCAoYykgMjAyMywgQ2hyaXN0b3BoIE3DvGxsbmVyIDxjaHJpc3Rv cGgubXVlbGxuZXJAdnJ1bGwuZXU+CisvLyBDb3B5cmlnaHQgKGMpIDIwMjMsIFBob2ViZSBDaGVu IDxwaG9lYmUuY2hlbkBzaWZpdmUuY29tPgorLy8gQ29weXJpZ2h0IChjKSAyMDIzLCBKZXJyeSBT aGloIDxqZXJyeS5zaGloQHNpZml2ZS5jb20+CisvLyBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExD CisvLyBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2Ug aW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0 aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25z CisvLyBhcmUgbWV0OgorLy8gMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3Qg cmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNv bmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vIDIuIFJlZGlzdHJpYnV0 aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cisv LyAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRp c2NsYWltZXIgaW4gdGhlCisvLyAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlh bHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUg SVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8v ICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5H LCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNI QU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBE SVNDTEFJTUVELiBJTlAgTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1Ig Q09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5U QUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5D TFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRF IEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9S IEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhF T1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlAgQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFks IE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcg SU5QIEFOWSBXQVkgT1VUUCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElG IEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGUgZ2Vu ZXJhdGVkIGNvZGUgb2YgdGhpcyBmaWxlIGRlcGVuZHMgb24gdGhlIGZvbGxvd2luZyBSSVNDLVYg ZXh0ZW5zaW9uczoKKy8vIC0gUlY2NEkKKy8vIC0gUklTQy1WIFZlY3RvciAoJ1YnKSB3aXRoIFZM RU4gPj0gMTI4CisvLyAtIFJJU0MtViBWZWN0b3IgQUVTIGJsb2NrIGNpcGhlciBleHRlbnNpb24g KCdadmtuZWQnKQorCisjaW5jbHVkZSA8bGludXgvbGlua2FnZS5oPgorCisudGV4dAorLm9wdGlv biBhcmNoLCArenZrbmVkCisKKyNpbmNsdWRlICJhZXMtbWFjcm9zLlMiCisKKyNkZWZpbmUgS0VZ UAkJYTAKKyNkZWZpbmUgSU5QCQlhMQorI2RlZmluZSBPVVRQCQlhMgorI2RlZmluZSBMRU4JCWEz CisjZGVmaW5lIElWUAkJYTQKKworLm1hY3JvCV9fYWVzX2NyeXB0X3p2a25lZAllbmMsIGtleWxl bgorCXZsZTMyLnYJCXYxNiwgKElOUCkKKwlhZXNfY3J5cHQJdjE2LCBcZW5jLCBca2V5bGVuCisJ dnNlMzIudgkJdjE2LCAoT1VUUCkKKwlyZXQKKy5lbmRtCisKKy5tYWNybwlhZXNfY3J5cHRfenZr bmVkCWVuYworCWFlc19iZWdpbglLRVlQLCAxMTFmLCAyMjJmCisJX19hZXNfY3J5cHRfenZrbmVk CVxlbmMsIDI1NgorMTExOgorCV9fYWVzX2NyeXB0X3p2a25lZAlcZW5jLCAxMjgKKzIyMjoKKwlf X2Flc19jcnlwdF96dmtuZWQJXGVuYywgMTkyCisuZW5kbQorCisvLyB2b2lkIGFlc19lbmNyeXB0 X3p2a25lZChjb25zdCBzdHJ1Y3QgY3J5cHRvX2Flc19jdHggKmtleSwKKy8vCQkJICAgY29uc3Qg dTggaW5bMTZdLCB1OCBvdXRbMTZdKTsKK1NZTV9GVU5DX1NUQVJUKGFlc19lbmNyeXB0X3p2a25l ZCkKKwlhZXNfY3J5cHRfenZrbmVkCTEKK1NZTV9GVU5DX0VORChhZXNfZW5jcnlwdF96dmtuZWQp CisKKy8vIFNhbWUgcHJvdG90eXBlIGFuZCBjYWxsaW5nIGNvbnZlbnRpb24gYXMgdGhlIGVuY3J5 cHRpb24gZnVuY3Rpb24KK1NZTV9GVU5DX1NUQVJUKGFlc19kZWNyeXB0X3p2a25lZCkKKwlhZXNf Y3J5cHRfenZrbmVkCTAKK1NZTV9GVU5DX0VORChhZXNfZGVjcnlwdF96dmtuZWQpCisKKy5tYWNy bwlfX2Flc19lY2JfY3J5cHQJZW5jLCBrZXlsZW4KKwlzcmxpCQl0MCwgTEVOLCAyCisJLy8gdDAg aXMgdGhlIHJlbWFpbmluZyBsZW5ndGggaW4gMzItYml0IHdvcmRzLiAgSXQncyBhIG11bHRpcGxl IG9mIDQuCisxOgorCXZzZXR2bGkJCXQxLCB0MCwgZTMyLCBtNCwgdGEsIG1hCisJc3ViCQl0MCwg dDAsIHQxCS8vIFN1YnRyYWN0IG51bWJlciBvZiB3b3JkcyBwcm9jZXNzZWQKKwlzbGxpCQl0MSwg dDEsIDIJLy8gV29yZHMgdG8gYnl0ZXMKKwl2bGUzMi52CQl2MTYsIChJTlApCisJYWVzX2NyeXB0 CXYxNiwgXGVuYywgXGtleWxlbgorCXZzZTMyLnYJCXYxNiwgKE9VVFApCisJYWRkCQlJTlAsIElO UCwgdDEKKwlhZGQJCU9VVFAsIE9VVFAsIHQxCisJYm5legkJdDAsIDFiCisKKwlyZXQKKy5lbmRt CisKKy5tYWNybwlhZXNfZWNiX2NyeXB0CWVuYworCWFlc19iZWdpbglLRVlQLCAxMTFmLCAyMjJm CisJX19hZXNfZWNiX2NyeXB0CVxlbmMsIDI1NgorMTExOgorCV9fYWVzX2VjYl9jcnlwdAlcZW5j LCAxMjgKKzIyMjoKKwlfX2Flc19lY2JfY3J5cHQJXGVuYywgMTkyCisuZW5kbQorCisvLyB2b2lk IGFlc19lY2JfZW5jcnlwdF96dmtuZWQoY29uc3Qgc3RydWN0IGNyeXB0b19hZXNfY3R4ICprZXks CisvLwkJCSAgICAgICBjb25zdCB1OCAqaW4sIHU4ICpvdXQsIHNpemVfdCBsZW4pOworLy8KKy8v IHxsZW58IG11c3QgYmUgbm9uemVybyBhbmQgYSBtdWx0aXBsZSBvZiAxNiAoQUVTX0JMT0NLX1NJ WkUpLgorU1lNX0ZVTkNfU1RBUlQoYWVzX2VjYl9lbmNyeXB0X3p2a25lZCkKKwlhZXNfZWNiX2Ny eXB0CTEKK1NZTV9GVU5DX0VORChhZXNfZWNiX2VuY3J5cHRfenZrbmVkKQorCisvLyBTYW1lIHBy b3RvdHlwZSBhbmQgY2FsbGluZyBjb252ZW50aW9uIGFzIHRoZSBlbmNyeXB0aW9uIGZ1bmN0aW9u CitTWU1fRlVOQ19TVEFSVChhZXNfZWNiX2RlY3J5cHRfenZrbmVkKQorCWFlc19lY2JfY3J5cHQJ MAorU1lNX0ZVTkNfRU5EKGFlc19lY2JfZGVjcnlwdF96dmtuZWQpCisKKy5tYWNybwlhZXNfY2Jj X2VuY3J5cHQJa2V5bGVuCisJdmxlMzIudgkJdjE2LCAoSVZQKQkvLyBMb2FkIElWCisxOgorCXZs ZTMyLnYJCXYxNywgKElOUCkJLy8gTG9hZCBwbGFpbnRleHQgYmxvY2sKKwl2eG9yLnZ2CQl2MTYs IHYxNiwgdjE3CS8vIFhPUiB3aXRoIElWIG9yIHByZXYgY2lwaGVydGV4dCBibG9jaworCWFlc19l bmNyeXB0CXYxNiwgXGtleWxlbgkvLyBFbmNyeXB0CisJdnNlMzIudgkJdjE2LCAoT1VUUCkJLy8g U3RvcmUgY2lwaGVydGV4dCBibG9jaworCWFkZGkJCUlOUCwgSU5QLCAxNgorCWFkZGkJCU9VVFAs IE9VVFAsIDE2CisJYWRkaQkJTEVOLCBMRU4sIC0xNgorCWJuZXoJCUxFTiwgMWIKKworCXZzZTMy LnYJCXYxNiwgKElWUCkJLy8gU3RvcmUgbmV4dCBJVgorCXJldAorLmVuZG0KKworLm1hY3JvCWFl c19jYmNfZGVjcnlwdAlrZXlsZW4KKwl2bGUzMi52CQl2MTYsIChJVlApCS8vIExvYWQgSVYKKzE6 CisJdmxlMzIudgkJdjE3LCAoSU5QKQkvLyBMb2FkIGNpcGhlcnRleHQgYmxvY2sKKwl2bXYudi52 CQl2MTgsIHYxNwkvLyBTYXZlIGNpcGhlcnRleHQgYmxvY2sKKwlhZXNfZGVjcnlwdAl2MTcsIFxr ZXlsZW4JLy8gRGVjcnlwdAorCXZ4b3IudnYJCXYxNywgdjE3LCB2MTYJLy8gWE9SIHdpdGggSVYg b3IgcHJldiBjaXBoZXJ0ZXh0IGJsb2NrCisJdnNlMzIudgkJdjE3LCAoT1VUUCkJLy8gU3RvcmUg cGxhaW50ZXh0IGJsb2NrCisJdm12LnYudgkJdjE2LCB2MTgJLy8gTmV4dCAiSVYiIGlzIHByZXYg Y2lwaGVydGV4dCBibG9jaworCWFkZGkJCUlOUCwgSU5QLCAxNgorCWFkZGkJCU9VVFAsIE9VVFAs IDE2CisJYWRkaQkJTEVOLCBMRU4sIC0xNgorCWJuZXoJCUxFTiwgMWIKKworCXZzZTMyLnYJCXYx NiwgKElWUCkJLy8gU3RvcmUgbmV4dCBJVgorCXJldAorLmVuZG0KKworLy8gdm9pZCBhZXNfY2Jj X2VuY3J5cHRfenZrbmVkKGNvbnN0IHN0cnVjdCBjcnlwdG9fYWVzX2N0eCAqa2V5LAorLy8JCQkg ICAgICAgY29uc3QgdTggKmluLCB1OCAqb3V0LCBzaXplX3QgbGVuLCB1OCBpdlsxNl0pOworLy8K Ky8vIHxsZW58IG11c3QgYmUgbm9uemVybyBhbmQgYSBtdWx0aXBsZSBvZiAxNiAoQUVTX0JMT0NL X1NJWkUpLgorU1lNX0ZVTkNfU1RBUlQoYWVzX2NiY19lbmNyeXB0X3p2a25lZCkKKwlhZXNfYmVn aW4JS0VZUCwgMTExZiwgMjIyZgorCWFlc19jYmNfZW5jcnlwdAkyNTYKKzExMToKKwlhZXNfY2Jj X2VuY3J5cHQJMTI4CisyMjI6CisJYWVzX2NiY19lbmNyeXB0CTE5MgorU1lNX0ZVTkNfRU5EKGFl c19jYmNfZW5jcnlwdF96dmtuZWQpCisKKy8vIFNhbWUgcHJvdG90eXBlIGFuZCBjYWxsaW5nIGNv bnZlbnRpb24gYXMgdGhlIGVuY3J5cHRpb24gZnVuY3Rpb24KK1NZTV9GVU5DX1NUQVJUKGFlc19j YmNfZGVjcnlwdF96dmtuZWQpCisJYWVzX2JlZ2luCUtFWVAsIDExMWYsIDIyMmYKKwlhZXNfY2Jj X2RlY3J5cHQJMjU2CisxMTE6CisJYWVzX2NiY19kZWNyeXB0CTEyOAorMjIyOgorCWFlc19jYmNf ZGVjcnlwdAkxOTIKK1NZTV9GVU5DX0VORChhZXNfY2JjX2RlY3J5cHRfenZrbmVkKQotLSAKMi40 My4wCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlu dXgtcmlzY3YgbWFpbGluZyBsaXN0CmxpbnV4LXJpc2N2QGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0 cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1yaXNjdgo=