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 919AAFC12; Tue, 2 Jan 2024 06:50:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WT/Vo8V9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 910FDC433CC; Tue, 2 Jan 2024 06:50:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1704178241; bh=ND9Tv7H6FJIXTYm2p0CmtFR+DV+u8u1ZvhgPdvx4ufo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WT/Vo8V9vq2qzHAipvEGbPzGkblpLDLfthoMXbDqJOBh7R3yyaNURZoDDM0+I13ZS xRjWLX8VhChMw6BNZu4X7+78KCiPQJo0Pm4T+QoHZdq2d1OMI4Y5HksqaSDVxADvB4 gXTm92I6RIJvf+yvEmP0GhsIsbgEYCfh8peQs5N4PP91gV2Xifc2rvylG6Gih9q/M1 UqgmtpeRurSkNdRnBwp05dCCygAFKMeArVn1TyhjaaNEFeLPwGlR80mRVZbgyJhMhX evas9C+IE2sOOHz5q6efiQ5aVns6EdnUTnPZmf886g3X8nMFli2JHSdLYPAEdMPg1e hBTYd+Ch4Dq8g== 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 , Charalampos Mitrodimas , Heiko Stuebner Subject: [RFC PATCH 10/13] crypto: riscv - add vector crypto accelerated SHA-{256,224} Date: Tue, 2 Jan 2024 00:47:36 -0600 Message-ID: <20240102064743.220490-11-ebiggers@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240102064743.220490-1-ebiggers@kernel.org> References: <20240102064743.220490-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 an implementation of SHA-224 and SHA-256 using the Zvknha or Zvknhb extension. 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 a regular .S file instead of the so-called perlasm, using the assembler instead of bare '.inst', and greatly reducing code duplication. Co-developed-by: Charalampos Mitrodimas Signed-off-by: Charalampos Mitrodimas Co-developed-by: Heiko Stuebner Signed-off-by: Heiko Stuebner 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 | 11 + arch/riscv/crypto/Makefile | 3 + arch/riscv/crypto/sha256-riscv64-glue.c | 137 +++++++++++ .../sha256-riscv64-zvknha_or_zvknhb-zvkb.S | 225 ++++++++++++++++++ 4 files changed, 376 insertions(+) create mode 100644 arch/riscv/crypto/sha256-riscv64-glue.c create mode 100644 arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig index 573818bb3e677..533bc6def123a 100644 --- a/arch/riscv/crypto/Kconfig +++ b/arch/riscv/crypto/Kconfig @@ -47,11 +47,22 @@ config CRYPTO_CHACHA_RISCV64 config CRYPTO_GHASH_RISCV64 tristate "Hash functions: GHASH" depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO select CRYPTO_GCM help GCM GHASH function (NIST SP 800-38D) Architecture: riscv64 using: - Zvkg vector crypto extension +config CRYPTO_SHA256_RISCV64 + tristate "Hash functions: SHA-224 and SHA-256" + depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO + select CRYPTO_SHA256 + help + SHA-224 and SHA-256 secure hash algorithm (FIPS 180) + + Architecture: riscv64 using: + - Zvknha or Zvknhb vector crypto extensions + - Zvkb vector crypto extension + endmenu diff --git a/arch/riscv/crypto/Makefile b/arch/riscv/crypto/Makefile index d21d3a3fc157c..28a58e89927ae 100644 --- a/arch/riscv/crypto/Makefile +++ b/arch/riscv/crypto/Makefile @@ -7,10 +7,13 @@ obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o obj-$(CONFIG_CRYPTO_AES_BLOCK_RISCV64) += aes-block-riscv64.o aes-block-riscv64-y := aes-riscv64-block-mode-glue.o aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o + +obj-$(CONFIG_CRYPTO_SHA256_RISCV64) += sha256-riscv64.o +sha256-riscv64-y := sha256-riscv64-glue.o sha256-riscv64-zvknha_or_zvknhb-zvkb.o diff --git a/arch/riscv/crypto/sha256-riscv64-glue.c b/arch/riscv/crypto/sha256-riscv64-glue.c new file mode 100644 index 0000000000000..5c3fa3d0174a4 --- /dev/null +++ b/arch/riscv/crypto/sha256-riscv64-glue.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * SHA-256 and SHA-224 using the RISC-V vector crypto extensions + * + * Copyright (C) 2022 VRULL GmbH + * Author: Heiko Stuebner + * + * Copyright (C) 2023 SiFive, Inc. + * Author: Jerry Shih + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * Note: the asm function only uses the 'state' field of struct sha256_state. + * It is assumed to be the first field. + */ +asmlinkage void sha256_transform_zvknha_or_zvknhb_zvkb( + struct sha256_state *state, const u8 *data, int num_blocks); + +static int riscv64_sha256_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + /* + * Ensure struct sha256_state begins directly with the SHA-256 + * 256-bit internal state, as this is what the asm function expects. + */ + BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0); + + if (crypto_simd_usable()) { + kernel_vector_begin(); + sha256_base_do_update(desc, data, len, + sha256_transform_zvknha_or_zvknhb_zvkb); + kernel_vector_end(); + } else { + crypto_sha256_update(desc, data, len); + } + return 0; +} + +static int riscv64_sha256_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + if (crypto_simd_usable()) { + kernel_vector_begin(); + if (len) + sha256_base_do_update( + desc, data, len, + sha256_transform_zvknha_or_zvknhb_zvkb); + sha256_base_do_finalize( + desc, sha256_transform_zvknha_or_zvknhb_zvkb); + kernel_vector_end(); + + return sha256_base_finish(desc, out); + } + + return crypto_sha256_finup(desc, data, len, out); +} + +static int riscv64_sha256_final(struct shash_desc *desc, u8 *out) +{ + return riscv64_sha256_finup(desc, NULL, 0, out); +} + +static int riscv64_sha256_digest(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + return sha256_base_init(desc) ?: + riscv64_sha256_finup(desc, data, len, out); +} + +static struct shash_alg riscv64_sha256_algs[] = { + { + .init = sha256_base_init, + .update = riscv64_sha256_update, + .final = riscv64_sha256_final, + .finup = riscv64_sha256_finup, + .digest = riscv64_sha256_digest, + .descsize = sizeof(struct sha256_state), + .digestsize = SHA256_DIGEST_SIZE, + .base = { + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_priority = 300, + .cra_name = "sha256", + .cra_driver_name = "sha256-riscv64-zvknha_or_zvknhb-zvkb", + .cra_module = THIS_MODULE, + }, + }, { + .init = sha224_base_init, + .update = riscv64_sha256_update, + .final = riscv64_sha256_final, + .finup = riscv64_sha256_finup, + .descsize = sizeof(struct sha256_state), + .digestsize = SHA224_DIGEST_SIZE, + .base = { + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_priority = 300, + .cra_name = "sha224", + .cra_driver_name = "sha224-riscv64-zvknha_or_zvknhb-zvkb", + .cra_module = THIS_MODULE, + }, + }, +}; + +static int __init riscv64_sha256_mod_init(void) +{ + /* Both zvknha and zvknhb provide the SHA-256 instructions. */ + if ((riscv_isa_extension_available(NULL, ZVKNHA) || + riscv_isa_extension_available(NULL, ZVKNHB)) && + riscv_isa_extension_available(NULL, ZVKB) && + riscv_vector_vlen() >= 128) + return crypto_register_shashes(riscv64_sha256_algs, + ARRAY_SIZE(riscv64_sha256_algs)); + + return -ENODEV; +} + +static void __exit riscv64_sha256_mod_fini(void) +{ + crypto_unregister_shashes(riscv64_sha256_algs, + ARRAY_SIZE(riscv64_sha256_algs)); +} + +module_init(riscv64_sha256_mod_init); +module_exit(riscv64_sha256_mod_fini); + +MODULE_DESCRIPTION("SHA-256 (RISC-V accelerated)"); +MODULE_AUTHOR("Heiko Stuebner "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CRYPTO("sha256"); +MODULE_ALIAS_CRYPTO("sha224"); diff --git a/arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S b/arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S new file mode 100644 index 0000000000000..faa7ee2b129b1 --- /dev/null +++ b/arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S @@ -0,0 +1,225 @@ +/* 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 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 SHA-2 Secure Hash extension ('Zvknha' or 'Zvknhb') +// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb') + +#include + +.text +.option arch, +zvknha, +zvkb + +#define STATEP a0 +#define DATA a1 +#define NUM_BLOCKS a2 + +#define STATEP_C a3 + +#define MASK v0 +#define INDICES v1 +#define W0 v2 +#define W1 v3 +#define W2 v4 +#define W3 v5 +#define VTMP v6 +#define FEBA v7 +#define HGDC v8 +#define K0 v10 +#define K1 v11 +#define K2 v12 +#define K3 v13 +#define K4 v14 +#define K5 v15 +#define K6 v16 +#define K7 v17 +#define K8 v18 +#define K9 v19 +#define K10 v20 +#define K11 v21 +#define K12 v22 +#define K13 v23 +#define K14 v24 +#define K15 v25 +#define PREV_FEBA v30 +#define PREV_HGDC v31 + +// Do 4 rounds of SHA-256. w0 contains the current 4 message schedule words. +// +// If not all the message schedule words have been computed yet, then this also +// computes 4 more message schedule words. w1-w3 contain the next 3 groups of 4 +// message schedule words; this macro computes the group after w3 and writes it +// to w0. This means that the next (w0, w1, w2, w3) is the current (w1, w2, w3, +// w0), so the caller must cycle through the registers accordingly. +.macro sha256_4rounds last, k, w0, w1, w2, w3 + vadd.vv VTMP, \k, \w0 + vsha2cl.vv HGDC, FEBA, VTMP + vsha2ch.vv FEBA, HGDC, VTMP +.if !\last + vmerge.vvm VTMP, \w2, \w1, MASK + vsha2ms.vv \w0, VTMP, \w3 +.endif +.endm + +.macro sha256_16rounds last, k0, k1, k2, k3 + sha256_4rounds \last, \k0, W0, W1, W2, W3 + sha256_4rounds \last, \k1, W1, W2, W3, W0 + sha256_4rounds \last, \k2, W2, W3, W0, W1 + sha256_4rounds \last, \k3, W3, W0, W1, W2 +.endm + +// void sha256_transform_zvknha_or_zvknhb_zvkb(u32 state[8], const u8 *data, +// int num_blocks); +SYM_TYPED_FUNC_START(sha256_transform_zvknha_or_zvknhb_zvkb) + + // Load the round constants into K0-K15. + vsetivli zero, 4, e32, m1, ta, ma + la t0, K256 + vle32.v K0, (t0) + addi t0, t0, 16 + vle32.v K1, (t0) + addi t0, t0, 16 + vle32.v K2, (t0) + addi t0, t0, 16 + vle32.v K3, (t0) + addi t0, t0, 16 + vle32.v K4, (t0) + addi t0, t0, 16 + vle32.v K5, (t0) + addi t0, t0, 16 + vle32.v K6, (t0) + addi t0, t0, 16 + vle32.v K7, (t0) + addi t0, t0, 16 + vle32.v K8, (t0) + addi t0, t0, 16 + vle32.v K9, (t0) + addi t0, t0, 16 + vle32.v K10, (t0) + addi t0, t0, 16 + vle32.v K11, (t0) + addi t0, t0, 16 + vle32.v K12, (t0) + addi t0, t0, 16 + vle32.v K13, (t0) + addi t0, t0, 16 + vle32.v K14, (t0) + addi t0, t0, 16 + vle32.v K15, (t0) + + // Setup mask for the vmerge to replace the first word (idx==0) in + // message scheduling. There are 4 words, so an 8-bit mask suffices. + vsetivli zero, 1, e8, m1, ta, ma + vmv.v.i MASK, 0x01 + + // Load the state. The state is stored as {a,b,c,d,e,f,g,h}, but we + // need {f,e,b,a},{h,g,d,c}. The dst vtype is e32m1 and the index vtype + // is e8mf4. We use index-load with the i8 indices {20, 16, 4, 0}, + // loaded using the 32-bit little endian value 0x00041014. + li t0, 0x00041014 + vsetivli zero, 1, e32, m1, ta, ma + vmv.v.x INDICES, t0 + addi STATEP_C, STATEP, 8 + vsetivli zero, 4, e32, m1, ta, ma + vluxei8.v FEBA, (STATEP), INDICES + vluxei8.v HGDC, (STATEP_C), INDICES + +.Lnext_block: + addi NUM_BLOCKS, NUM_BLOCKS, -1 + + // Save the previous state, as it's needed later. + vmv.v.v PREV_FEBA, FEBA + vmv.v.v PREV_HGDC, HGDC + + // Load the next 512-bit message block and endian-swap each 32-bit word. + vle32.v W0, (DATA) + vrev8.v W0, W0 + addi DATA, DATA, 16 + vle32.v W1, (DATA) + vrev8.v W1, W1 + addi DATA, DATA, 16 + vle32.v W2, (DATA) + vrev8.v W2, W2 + addi DATA, DATA, 16 + vle32.v W3, (DATA) + vrev8.v W3, W3 + addi DATA, DATA, 16 + + // Do the 64 rounds of SHA-256. + sha256_16rounds 0, K0, K1, K2, K3 + sha256_16rounds 0, K4, K5, K6, K7 + sha256_16rounds 0, K8, K9, K10, K11 + sha256_16rounds 1, K12, K13, K14, K15 + + // Add the previous state. + vadd.vv FEBA, FEBA, PREV_FEBA + vadd.vv HGDC, HGDC, PREV_HGDC + + // Repeat if more blocks remain. + bnez NUM_BLOCKS, .Lnext_block + + // Store the new state and return. + vsuxei8.v FEBA, (STATEP), INDICES + vsuxei8.v HGDC, (STATEP_C), INDICES + ret +SYM_FUNC_END(sha256_transform_zvknha_or_zvknhb_zvkb) + +.section ".rodata" +.p2align 2 +.type K256, @object +K256: + .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5 + .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 + .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3 + .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 + .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc + .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da + .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7 + .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 + .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13 + .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 + .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3 + .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 + .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5 + .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 + .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208 + .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +.size K256, . - K256 -- 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 47353C46CD2 for ; Tue, 2 Jan 2024 06:50:59 +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=Gj1t9GGZBV1zIfQyMpjzw4MXme1FmY2ilZY/jYhnuRk=; b=v5WQqH6jhtKrmN vi+sWOfxRWGISBUYvgD7qR0BDfdRVKTJdTyzWWQ2+nRWefD1PCc+2MEbTRD/RuHxmEY29L+DRRwvf cicZQv8gogeAlE5WKa+jjRqrxRxOGXscTdBhQzz4GX/LGylAHsvLGq/1LTlNtP0ZG2FwDjgmpLR2Z ZM3AWwN9W9Bnf9VY+GjZJhDU4SONXZy8ST6Q27PeQS+tHYe7yz9+LzUfA3mb+OYU6Na1flD3BYI/b d3aVkXXibavZC6/MvrcbtJnO1qYOk9MTfRWLgdlw0Z51leibESdescVrewgOj3OwmuNkgr/pXH0Gc ibQim2tQK6ZlLcwGiJsw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1rKYbz-007CaN-2T; Tue, 02 Jan 2024 06:50:51 +0000 Received: from sin.source.kernel.org ([145.40.73.55]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1rKYbs-007CQu-14 for linux-riscv@lists.infradead.org; Tue, 02 Jan 2024 06:50:48 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 2A740CE0B8A; Tue, 2 Jan 2024 06:50:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 910FDC433CC; Tue, 2 Jan 2024 06:50:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1704178241; bh=ND9Tv7H6FJIXTYm2p0CmtFR+DV+u8u1ZvhgPdvx4ufo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WT/Vo8V9vq2qzHAipvEGbPzGkblpLDLfthoMXbDqJOBh7R3yyaNURZoDDM0+I13ZS xRjWLX8VhChMw6BNZu4X7+78KCiPQJo0Pm4T+QoHZdq2d1OMI4Y5HksqaSDVxADvB4 gXTm92I6RIJvf+yvEmP0GhsIsbgEYCfh8peQs5N4PP91gV2Xifc2rvylG6Gih9q/M1 UqgmtpeRurSkNdRnBwp05dCCygAFKMeArVn1TyhjaaNEFeLPwGlR80mRVZbgyJhMhX evas9C+IE2sOOHz5q6efiQ5aVns6EdnUTnPZmf886g3X8nMFli2JHSdLYPAEdMPg1e hBTYd+Ch4Dq8g== 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 , Charalampos Mitrodimas , Heiko Stuebner Subject: [RFC PATCH 10/13] crypto: riscv - add vector crypto accelerated SHA-{256,224} Date: Tue, 2 Jan 2024 00:47:36 -0600 Message-ID: <20240102064743.220490-11-ebiggers@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240102064743.220490-1-ebiggers@kernel.org> References: <20240102064743.220490-1-ebiggers@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240101_225044_833021_805B6932 X-CRM114-Status: GOOD ( 31.06 ) 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 RnJvbTogSmVycnkgU2hpaCA8amVycnkuc2hpaEBzaWZpdmUuY29tPgoKQWRkIGFuIGltcGxlbWVu dGF0aW9uIG9mIFNIQS0yMjQgYW5kIFNIQS0yNTYgdXNpbmcgdGhlIFp2a25oYSBvciBadmtuaGIK ZXh0ZW5zaW9uLiAgVGhlIGFzc2VtYmx5IGNvZGUgaXMgZGVyaXZlZCBmcm9tIE9wZW5TU0wgY29k ZQoob3BlbnNzbC9vcGVuc3NsIzIxOTIzKSB0aGF0IHdhcyBkdWFsLWxpY2Vuc2VkIHNvIHRoYXQg aXQgY291bGQgYmUKcmV1c2VkIGluIHRoZSBrZXJuZWwuICBOZXZlcnRoZWxlc3MsIHRoZSBhc3Nl bWJseSBoYXMgYmVlbiBzaWduaWZpY2FudGx5CnJld29ya2VkIGZvciBpbnRlZ3JhdGlvbiB3aXRo IHRoZSBrZXJuZWwsIGZvciBleGFtcGxlIGJ5IHVzaW5nIGEgcmVndWxhcgouUyBmaWxlIGluc3Rl YWQgb2YgdGhlIHNvLWNhbGxlZCBwZXJsYXNtLCB1c2luZyB0aGUgYXNzZW1ibGVyIGluc3RlYWQg b2YKYmFyZSAnLmluc3QnLCBhbmQgZ3JlYXRseSByZWR1Y2luZyBjb2RlIGR1cGxpY2F0aW9uLgoK Q28tZGV2ZWxvcGVkLWJ5OiBDaGFyYWxhbXBvcyBNaXRyb2RpbWFzIDxjaGFyYWxhbXBvcy5taXRy b2RpbWFzQHZydWxsLmV1PgpTaWduZWQtb2ZmLWJ5OiBDaGFyYWxhbXBvcyBNaXRyb2RpbWFzIDxj aGFyYWxhbXBvcy5taXRyb2RpbWFzQHZydWxsLmV1PgpDby1kZXZlbG9wZWQtYnk6IEhlaWtvIFN0 dWVibmVyIDxoZWlrby5zdHVlYm5lckB2cnVsbC5ldT4KU2lnbmVkLW9mZi1ieTogSGVpa28gU3R1 ZWJuZXIgPGhlaWtvLnN0dWVibmVyQHZydWxsLmV1PgpDby1kZXZlbG9wZWQtYnk6IFBob2ViZSBD aGVuIDxwaG9lYmUuY2hlbkBzaWZpdmUuY29tPgpTaWduZWQtb2ZmLWJ5OiBQaG9lYmUgQ2hlbiA8 cGhvZWJlLmNoZW5Ac2lmaXZlLmNvbT4KU2lnbmVkLW9mZi1ieTogSmVycnkgU2hpaCA8amVycnku c2hpaEBzaWZpdmUuY29tPgpDby1kZXZlbG9wZWQtYnk6IEVyaWMgQmlnZ2VycyA8ZWJpZ2dlcnNA Z29vZ2xlLmNvbT4KU2lnbmVkLW9mZi1ieTogRXJpYyBCaWdnZXJzIDxlYmlnZ2Vyc0Bnb29nbGUu Y29tPgotLS0KIGFyY2gvcmlzY3YvY3J5cHRvL0tjb25maWcgICAgICAgICAgICAgICAgICAgICB8 ICAxMSArCiBhcmNoL3Jpc2N2L2NyeXB0by9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICAgfCAg IDMgKwogYXJjaC9yaXNjdi9jcnlwdG8vc2hhMjU2LXJpc2N2NjQtZ2x1ZS5jICAgICAgIHwgMTM3 ICsrKysrKysrKysrCiAuLi4vc2hhMjU2LXJpc2N2NjQtenZrbmhhX29yX3p2a25oYi16dmtiLlMg ICAgfCAyMjUgKysrKysrKysrKysrKysrKysrCiA0IGZpbGVzIGNoYW5nZWQsIDM3NiBpbnNlcnRp b25zKCspCiBjcmVhdGUgbW9kZSAxMDA2NDQgYXJjaC9yaXNjdi9jcnlwdG8vc2hhMjU2LXJpc2N2 NjQtZ2x1ZS5jCiBjcmVhdGUgbW9kZSAxMDA2NDQgYXJjaC9yaXNjdi9jcnlwdG8vc2hhMjU2LXJp c2N2NjQtenZrbmhhX29yX3p2a25oYi16dmtiLlMKCmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2Ny eXB0by9LY29uZmlnIGIvYXJjaC9yaXNjdi9jcnlwdG8vS2NvbmZpZwppbmRleCA1NzM4MThiYjNl Njc3Li41MzNiYzZkZWYxMjNhIDEwMDY0NAotLS0gYS9hcmNoL3Jpc2N2L2NyeXB0by9LY29uZmln CisrKyBiL2FyY2gvcmlzY3YvY3J5cHRvL0tjb25maWcKQEAgLTQ3LDExICs0NywyMiBAQCBjb25m aWcgQ1JZUFRPX0NIQUNIQV9SSVNDVjY0CiBjb25maWcgQ1JZUFRPX0dIQVNIX1JJU0NWNjQKIAl0 cmlzdGF0ZSAiSGFzaCBmdW5jdGlvbnM6IEdIQVNIIgogCWRlcGVuZHMgb24gNjRCSVQgJiYgUklT Q1ZfSVNBX1YgJiYgVE9PTENIQUlOX0hBU19WRUNUT1JfQ1JZUFRPCiAJc2VsZWN0IENSWVBUT19H Q00KIAloZWxwCiAJICBHQ00gR0hBU0ggZnVuY3Rpb24gKE5JU1QgU1AgODAwLTM4RCkKIAogCSAg QXJjaGl0ZWN0dXJlOiByaXNjdjY0IHVzaW5nOgogCSAgLSBadmtnIHZlY3RvciBjcnlwdG8gZXh0 ZW5zaW9uCiAKK2NvbmZpZyBDUllQVE9fU0hBMjU2X1JJU0NWNjQKKwl0cmlzdGF0ZSAiSGFzaCBm dW5jdGlvbnM6IFNIQS0yMjQgYW5kIFNIQS0yNTYiCisJZGVwZW5kcyBvbiA2NEJJVCAmJiBSSVND Vl9JU0FfViAmJiBUT09MQ0hBSU5fSEFTX1ZFQ1RPUl9DUllQVE8KKwlzZWxlY3QgQ1JZUFRPX1NI QTI1NgorCWhlbHAKKwkgIFNIQS0yMjQgYW5kIFNIQS0yNTYgc2VjdXJlIGhhc2ggYWxnb3JpdGht IChGSVBTIDE4MCkKKworCSAgQXJjaGl0ZWN0dXJlOiByaXNjdjY0IHVzaW5nOgorCSAgLSBadmtu aGEgb3IgWnZrbmhiIHZlY3RvciBjcnlwdG8gZXh0ZW5zaW9ucworCSAgLSBadmtiIHZlY3RvciBj cnlwdG8gZXh0ZW5zaW9uCisKIGVuZG1lbnUKZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3YvY3J5cHRv L01ha2VmaWxlIGIvYXJjaC9yaXNjdi9jcnlwdG8vTWFrZWZpbGUKaW5kZXggZDIxZDNhM2ZjMTU3 Yy4uMjhhNThlODk5MjdhZSAxMDA2NDQKLS0tIGEvYXJjaC9yaXNjdi9jcnlwdG8vTWFrZWZpbGUK KysrIGIvYXJjaC9yaXNjdi9jcnlwdG8vTWFrZWZpbGUKQEAgLTcsMTAgKzcsMTMgQEAgb2JqLSQo Q09ORklHX0NSWVBUT19BRVNfUklTQ1Y2NCkgKz0gYWVzLXJpc2N2NjQubwogYWVzLXJpc2N2NjQt eSA6PSBhZXMtcmlzY3Y2NC1nbHVlLm8gYWVzLXJpc2N2NjQtenZrbmVkLm8KIAogb2JqLSQoQ09O RklHX0NSWVBUT19BRVNfQkxPQ0tfUklTQ1Y2NCkgKz0gYWVzLWJsb2NrLXJpc2N2NjQubwogYWVz LWJsb2NrLXJpc2N2NjQteSA6PSBhZXMtcmlzY3Y2NC1ibG9jay1tb2RlLWdsdWUubyBhZXMtcmlz Y3Y2NC16dmtuZWQtenZiYi16dmtnLm8gYWVzLXJpc2N2NjQtenZrbmVkLXp2a2IubwogCiBvYmot JChDT05GSUdfQ1JZUFRPX0NIQUNIQV9SSVNDVjY0KSArPSBjaGFjaGEtcmlzY3Y2NC5vCiBjaGFj aGEtcmlzY3Y2NC15IDo9IGNoYWNoYS1yaXNjdjY0LWdsdWUubyBjaGFjaGEtcmlzY3Y2NC16dmti Lm8KIAogb2JqLSQoQ09ORklHX0NSWVBUT19HSEFTSF9SSVNDVjY0KSArPSBnaGFzaC1yaXNjdjY0 Lm8KIGdoYXNoLXJpc2N2NjQteSA6PSBnaGFzaC1yaXNjdjY0LWdsdWUubyBnaGFzaC1yaXNjdjY0 LXp2a2cubworCitvYmotJChDT05GSUdfQ1JZUFRPX1NIQTI1Nl9SSVNDVjY0KSArPSBzaGEyNTYt cmlzY3Y2NC5vCitzaGEyNTYtcmlzY3Y2NC15IDo9IHNoYTI1Ni1yaXNjdjY0LWdsdWUubyBzaGEy NTYtcmlzY3Y2NC16dmtuaGFfb3JfenZrbmhiLXp2a2IubwpkaWZmIC0tZ2l0IGEvYXJjaC9yaXNj di9jcnlwdG8vc2hhMjU2LXJpc2N2NjQtZ2x1ZS5jIGIvYXJjaC9yaXNjdi9jcnlwdG8vc2hhMjU2 LXJpc2N2NjQtZ2x1ZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMDAu LjVjM2ZhM2QwMTc0YTQKLS0tIC9kZXYvbnVsbAorKysgYi9hcmNoL3Jpc2N2L2NyeXB0by9zaGEy NTYtcmlzY3Y2NC1nbHVlLmMKQEAgLTAsMCArMSwxMzcgQEAKKy8vIFNQRFgtTGljZW5zZS1JZGVu dGlmaWVyOiBHUEwtMi4wLW9yLWxhdGVyCisvKgorICogU0hBLTI1NiBhbmQgU0hBLTIyNCB1c2lu ZyB0aGUgUklTQy1WIHZlY3RvciBjcnlwdG8gZXh0ZW5zaW9ucworICoKKyAqIENvcHlyaWdodCAo QykgMjAyMiBWUlVMTCBHbWJICisgKiBBdXRob3I6IEhlaWtvIFN0dWVibmVyIDxoZWlrby5zdHVl Ym5lckB2cnVsbC5ldT4KKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMjMgU2lGaXZlLCBJbmMuCisg KiBBdXRob3I6IEplcnJ5IFNoaWggPGplcnJ5LnNoaWhAc2lmaXZlLmNvbT4KKyAqLworCisjaW5j bHVkZSA8YXNtL3NpbWQuaD4KKyNpbmNsdWRlIDxhc20vdmVjdG9yLmg+CisjaW5jbHVkZSA8Y3J5 cHRvL2ludGVybmFsL2hhc2guaD4KKyNpbmNsdWRlIDxjcnlwdG8vaW50ZXJuYWwvc2ltZC5oPgor I2luY2x1ZGUgPGNyeXB0by9zaGEyNTZfYmFzZS5oPgorI2luY2x1ZGUgPGxpbnV4L2xpbmthZ2Uu aD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKworLyoKKyAqIE5vdGU6IHRoZSBhc20gZnVu Y3Rpb24gb25seSB1c2VzIHRoZSAnc3RhdGUnIGZpZWxkIG9mIHN0cnVjdCBzaGEyNTZfc3RhdGUu CisgKiBJdCBpcyBhc3N1bWVkIHRvIGJlIHRoZSBmaXJzdCBmaWVsZC4KKyAqLworYXNtbGlua2Fn ZSB2b2lkIHNoYTI1Nl90cmFuc2Zvcm1fenZrbmhhX29yX3p2a25oYl96dmtiKAorCXN0cnVjdCBz aGEyNTZfc3RhdGUgKnN0YXRlLCBjb25zdCB1OCAqZGF0YSwgaW50IG51bV9ibG9ja3MpOworCitz dGF0aWMgaW50IHJpc2N2NjRfc2hhMjU2X3VwZGF0ZShzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywg Y29uc3QgdTggKmRhdGEsCisJCQkJIHVuc2lnbmVkIGludCBsZW4pCit7CisJLyoKKwkgKiBFbnN1 cmUgc3RydWN0IHNoYTI1Nl9zdGF0ZSBiZWdpbnMgZGlyZWN0bHkgd2l0aCB0aGUgU0hBLTI1Ngor CSAqIDI1Ni1iaXQgaW50ZXJuYWwgc3RhdGUsIGFzIHRoaXMgaXMgd2hhdCB0aGUgYXNtIGZ1bmN0 aW9uIGV4cGVjdHMuCisJICovCisJQlVJTERfQlVHX09OKG9mZnNldG9mKHN0cnVjdCBzaGEyNTZf c3RhdGUsIHN0YXRlKSAhPSAwKTsKKworCWlmIChjcnlwdG9fc2ltZF91c2FibGUoKSkgeworCQlr ZXJuZWxfdmVjdG9yX2JlZ2luKCk7CisJCXNoYTI1Nl9iYXNlX2RvX3VwZGF0ZShkZXNjLCBkYXRh LCBsZW4sCisJCQkJICAgICAgc2hhMjU2X3RyYW5zZm9ybV96dmtuaGFfb3JfenZrbmhiX3p2a2Ip OworCQlrZXJuZWxfdmVjdG9yX2VuZCgpOworCX0gZWxzZSB7CisJCWNyeXB0b19zaGEyNTZfdXBk YXRlKGRlc2MsIGRhdGEsIGxlbik7CisJfQorCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IHJp c2N2NjRfc2hhMjU2X2ZpbnVwKHN0cnVjdCBzaGFzaF9kZXNjICpkZXNjLCBjb25zdCB1OCAqZGF0 YSwKKwkJCQl1bnNpZ25lZCBpbnQgbGVuLCB1OCAqb3V0KQoreworCWlmIChjcnlwdG9fc2ltZF91 c2FibGUoKSkgeworCQlrZXJuZWxfdmVjdG9yX2JlZ2luKCk7CisJCWlmIChsZW4pCisJCQlzaGEy NTZfYmFzZV9kb191cGRhdGUoCisJCQkJZGVzYywgZGF0YSwgbGVuLAorCQkJCXNoYTI1Nl90cmFu c2Zvcm1fenZrbmhhX29yX3p2a25oYl96dmtiKTsKKwkJc2hhMjU2X2Jhc2VfZG9fZmluYWxpemUo CisJCQlkZXNjLCBzaGEyNTZfdHJhbnNmb3JtX3p2a25oYV9vcl96dmtuaGJfenZrYik7CisJCWtl cm5lbF92ZWN0b3JfZW5kKCk7CisKKwkJcmV0dXJuIHNoYTI1Nl9iYXNlX2ZpbmlzaChkZXNjLCBv dXQpOworCX0KKworCXJldHVybiBjcnlwdG9fc2hhMjU2X2ZpbnVwKGRlc2MsIGRhdGEsIGxlbiwg b3V0KTsKK30KKworc3RhdGljIGludCByaXNjdjY0X3NoYTI1Nl9maW5hbChzdHJ1Y3Qgc2hhc2hf ZGVzYyAqZGVzYywgdTggKm91dCkKK3sKKwlyZXR1cm4gcmlzY3Y2NF9zaGEyNTZfZmludXAoZGVz YywgTlVMTCwgMCwgb3V0KTsKK30KKworc3RhdGljIGludCByaXNjdjY0X3NoYTI1Nl9kaWdlc3Qo c3RydWN0IHNoYXNoX2Rlc2MgKmRlc2MsIGNvbnN0IHU4ICpkYXRhLAorCQkJCSB1bnNpZ25lZCBp bnQgbGVuLCB1OCAqb3V0KQoreworCXJldHVybiBzaGEyNTZfYmFzZV9pbml0KGRlc2MpID86CisJ ICAgICAgIHJpc2N2NjRfc2hhMjU2X2ZpbnVwKGRlc2MsIGRhdGEsIGxlbiwgb3V0KTsKK30KKwor c3RhdGljIHN0cnVjdCBzaGFzaF9hbGcgcmlzY3Y2NF9zaGEyNTZfYWxnc1tdID0geworCXsKKwkJ LmluaXQgPSBzaGEyNTZfYmFzZV9pbml0LAorCQkudXBkYXRlID0gcmlzY3Y2NF9zaGEyNTZfdXBk YXRlLAorCQkuZmluYWwgPSByaXNjdjY0X3NoYTI1Nl9maW5hbCwKKwkJLmZpbnVwID0gcmlzY3Y2 NF9zaGEyNTZfZmludXAsCisJCS5kaWdlc3QgPSByaXNjdjY0X3NoYTI1Nl9kaWdlc3QsCisJCS5k ZXNjc2l6ZSA9IHNpemVvZihzdHJ1Y3Qgc2hhMjU2X3N0YXRlKSwKKwkJLmRpZ2VzdHNpemUgPSBT SEEyNTZfRElHRVNUX1NJWkUsCisJCS5iYXNlID0geworCQkJLmNyYV9ibG9ja3NpemUgPSBTSEEy NTZfQkxPQ0tfU0laRSwKKwkJCS5jcmFfcHJpb3JpdHkgPSAzMDAsCisJCQkuY3JhX25hbWUgPSAi c2hhMjU2IiwKKwkJCS5jcmFfZHJpdmVyX25hbWUgPSAic2hhMjU2LXJpc2N2NjQtenZrbmhhX29y X3p2a25oYi16dmtiIiwKKwkJCS5jcmFfbW9kdWxlID0gVEhJU19NT0RVTEUsCisJCX0sCisJfSwg eworCQkuaW5pdCA9IHNoYTIyNF9iYXNlX2luaXQsCisJCS51cGRhdGUgPSByaXNjdjY0X3NoYTI1 Nl91cGRhdGUsCisJCS5maW5hbCA9IHJpc2N2NjRfc2hhMjU2X2ZpbmFsLAorCQkuZmludXAgPSBy aXNjdjY0X3NoYTI1Nl9maW51cCwKKwkJLmRlc2NzaXplID0gc2l6ZW9mKHN0cnVjdCBzaGEyNTZf c3RhdGUpLAorCQkuZGlnZXN0c2l6ZSA9IFNIQTIyNF9ESUdFU1RfU0laRSwKKwkJLmJhc2UgPSB7 CisJCQkuY3JhX2Jsb2Nrc2l6ZSA9IFNIQTIyNF9CTE9DS19TSVpFLAorCQkJLmNyYV9wcmlvcml0 eSA9IDMwMCwKKwkJCS5jcmFfbmFtZSA9ICJzaGEyMjQiLAorCQkJLmNyYV9kcml2ZXJfbmFtZSA9 ICJzaGEyMjQtcmlzY3Y2NC16dmtuaGFfb3JfenZrbmhiLXp2a2IiLAorCQkJLmNyYV9tb2R1bGUg PSBUSElTX01PRFVMRSwKKwkJfSwKKwl9LAorfTsKKworc3RhdGljIGludCBfX2luaXQgcmlzY3Y2 NF9zaGEyNTZfbW9kX2luaXQodm9pZCkKK3sKKwkvKiBCb3RoIHp2a25oYSBhbmQgenZrbmhiIHBy b3ZpZGUgdGhlIFNIQS0yNTYgaW5zdHJ1Y3Rpb25zLiAqLworCWlmICgocmlzY3ZfaXNhX2V4dGVu c2lvbl9hdmFpbGFibGUoTlVMTCwgWlZLTkhBKSB8fAorCSAgICAgcmlzY3ZfaXNhX2V4dGVuc2lv bl9hdmFpbGFibGUoTlVMTCwgWlZLTkhCKSkgJiYKKwkgICAgcmlzY3ZfaXNhX2V4dGVuc2lvbl9h dmFpbGFibGUoTlVMTCwgWlZLQikgJiYKKwkgICAgcmlzY3ZfdmVjdG9yX3ZsZW4oKSA+PSAxMjgp CisJCXJldHVybiBjcnlwdG9fcmVnaXN0ZXJfc2hhc2hlcyhyaXNjdjY0X3NoYTI1Nl9hbGdzLAor CQkJCQkgICAgICAgQVJSQVlfU0laRShyaXNjdjY0X3NoYTI1Nl9hbGdzKSk7CisKKwlyZXR1cm4g LUVOT0RFVjsKK30KKworc3RhdGljIHZvaWQgX19leGl0IHJpc2N2NjRfc2hhMjU2X21vZF9maW5p KHZvaWQpCit7CisJY3J5cHRvX3VucmVnaXN0ZXJfc2hhc2hlcyhyaXNjdjY0X3NoYTI1Nl9hbGdz LAorCQkJCSAgQVJSQVlfU0laRShyaXNjdjY0X3NoYTI1Nl9hbGdzKSk7Cit9CisKK21vZHVsZV9p bml0KHJpc2N2NjRfc2hhMjU2X21vZF9pbml0KTsKK21vZHVsZV9leGl0KHJpc2N2NjRfc2hhMjU2 X21vZF9maW5pKTsKKworTU9EVUxFX0RFU0NSSVBUSU9OKCJTSEEtMjU2IChSSVNDLVYgYWNjZWxl cmF0ZWQpIik7CitNT0RVTEVfQVVUSE9SKCJIZWlrbyBTdHVlYm5lciA8aGVpa28uc3R1ZWJuZXJA dnJ1bGwuZXU+Iik7CitNT0RVTEVfTElDRU5TRSgiR1BMIik7CitNT0RVTEVfQUxJQVNfQ1JZUFRP KCJzaGEyNTYiKTsKK01PRFVMRV9BTElBU19DUllQVE8oInNoYTIyNCIpOwpkaWZmIC0tZ2l0IGEv YXJjaC9yaXNjdi9jcnlwdG8vc2hhMjU2LXJpc2N2NjQtenZrbmhhX29yX3p2a25oYi16dmtiLlMg Yi9hcmNoL3Jpc2N2L2NyeXB0by9zaGEyNTYtcmlzY3Y2NC16dmtuaGFfb3JfenZrbmhiLXp2a2Iu UwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAwLi5mYWE3ZWUyYjEyOWIx Ci0tLSAvZGV2L251bGwKKysrIGIvYXJjaC9yaXNjdi9jcnlwdG8vc2hhMjU2LXJpc2N2NjQtenZr bmhhX29yX3p2a25oYi16dmtiLlMKQEAgLTAsMCArMSwyMjUgQEAKKy8qIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiBBcGFjaGUtMi4wIE9SIEJTRC0yLUNsYXVzZSAqLworLy8KKy8vIFRoaXMgZmls ZSBpcyBkdWFsLWxpY2Vuc2VkLCBtZWFuaW5nIHRoYXQgeW91IGNhbiB1c2UgaXQgdW5kZXIgeW91 cgorLy8gY2hvaWNlIG9mIGVpdGhlciBvZiB0aGUgZm9sbG93aW5nIHR3byBsaWNlbnNlczoKKy8v CisvLyBDb3B5cmlnaHQgMjAyMyBUaGUgT3BlblNTTCBQcm9qZWN0IEF1dGhvcnMuIEFsbCBSaWdo dHMgUmVzZXJ2ZWQuCisvLworLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIDIu MCAodGhlICJMaWNlbnNlIikuIFlvdSBjYW4gb2J0YWluCisvLyBhIGNvcHkgaW4gdGhlIGZpbGUg TElDRU5TRSBpbiB0aGUgc291cmNlIGRpc3RyaWJ1dGlvbiBvciBhdAorLy8gaHR0cHM6Ly93d3cu b3BlbnNzbC5vcmcvc291cmNlL2xpY2Vuc2UuaHRtbAorLy8KKy8vIG9yCisvLworLy8gQ29weXJp Z2h0IChjKSAyMDIzLCBDaHJpc3RvcGggTcO8bGxuZXIgPGNocmlzdG9waC5tdWVsbG5lckB2cnVs bC5ldT4KKy8vIENvcHlyaWdodCAoYykgMjAyMywgUGhvZWJlIENoZW4gPHBob2ViZS5jaGVuQHNp Zml2ZS5jb20+CisvLyBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDCisvLyBBbGwgcmlnaHRzIHJl c2VydmVkLgorLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5h cnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVk IHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCisvLyBhcmUgbWV0OgorLy8g MS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBj b3B5cmlnaHQKKy8vICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBm b2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9y bSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyAgICBub3RpY2UsIHRoaXMg bGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisv LyAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0 aGUgZGlzdHJpYnV0aW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhF IENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBF WFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1J VEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklU TkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBF VkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElB QkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVY RU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8v IExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7 IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBU SU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBX SEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVE SU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRI RSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lC SUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoZSBnZW5lcmF0ZWQgY29kZSBvZiB0aGlzIGZp bGUgZGVwZW5kcyBvbiB0aGUgZm9sbG93aW5nIFJJU0MtViBleHRlbnNpb25zOgorLy8gLSBSVjY0 SQorLy8gLSBSSVNDLVYgVmVjdG9yICgnVicpIHdpdGggVkxFTiA+PSAxMjgKKy8vIC0gUklTQy1W IFZlY3RvciBTSEEtMiBTZWN1cmUgSGFzaCBleHRlbnNpb24gKCdadmtuaGEnIG9yICdadmtuaGIn KQorLy8gLSBSSVNDLVYgVmVjdG9yIENyeXB0b2dyYXBoeSBCaXQtbWFuaXB1bGF0aW9uIGV4dGVu c2lvbiAoJ1p2a2InKQorCisjaW5jbHVkZSA8bGludXgvY2ZpX3R5cGVzLmg+CisKKy50ZXh0Cisu b3B0aW9uIGFyY2gsICt6dmtuaGEsICt6dmtiCisKKyNkZWZpbmUgU1RBVEVQCQlhMAorI2RlZmlu ZSBEQVRBCQlhMQorI2RlZmluZSBOVU1fQkxPQ0tTCWEyCisKKyNkZWZpbmUgU1RBVEVQX0MJYTMK KworI2RlZmluZSBNQVNLCQl2MAorI2RlZmluZSBJTkRJQ0VTCQl2MQorI2RlZmluZSBXMAkJdjIK KyNkZWZpbmUgVzEJCXYzCisjZGVmaW5lIFcyCQl2NAorI2RlZmluZSBXMwkJdjUKKyNkZWZpbmUg VlRNUAkJdjYKKyNkZWZpbmUgRkVCQQkJdjcKKyNkZWZpbmUgSEdEQwkJdjgKKyNkZWZpbmUgSzAJ CXYxMAorI2RlZmluZSBLMQkJdjExCisjZGVmaW5lIEsyCQl2MTIKKyNkZWZpbmUgSzMJCXYxMwor I2RlZmluZSBLNAkJdjE0CisjZGVmaW5lIEs1CQl2MTUKKyNkZWZpbmUgSzYJCXYxNgorI2RlZmlu ZSBLNwkJdjE3CisjZGVmaW5lIEs4CQl2MTgKKyNkZWZpbmUgSzkJCXYxOQorI2RlZmluZSBLMTAJ CXYyMAorI2RlZmluZSBLMTEJCXYyMQorI2RlZmluZSBLMTIJCXYyMgorI2RlZmluZSBLMTMJCXYy MworI2RlZmluZSBLMTQJCXYyNAorI2RlZmluZSBLMTUJCXYyNQorI2RlZmluZSBQUkVWX0ZFQkEJ djMwCisjZGVmaW5lIFBSRVZfSEdEQwl2MzEKKworLy8gRG8gNCByb3VuZHMgb2YgU0hBLTI1Ni4g IHcwIGNvbnRhaW5zIHRoZSBjdXJyZW50IDQgbWVzc2FnZSBzY2hlZHVsZSB3b3Jkcy4KKy8vCisv LyBJZiBub3QgYWxsIHRoZSBtZXNzYWdlIHNjaGVkdWxlIHdvcmRzIGhhdmUgYmVlbiBjb21wdXRl ZCB5ZXQsIHRoZW4gdGhpcyBhbHNvCisvLyBjb21wdXRlcyA0IG1vcmUgbWVzc2FnZSBzY2hlZHVs ZSB3b3Jkcy4gIHcxLXczIGNvbnRhaW4gdGhlIG5leHQgMyBncm91cHMgb2YgNAorLy8gbWVzc2Fn ZSBzY2hlZHVsZSB3b3JkczsgdGhpcyBtYWNybyBjb21wdXRlcyB0aGUgZ3JvdXAgYWZ0ZXIgdzMg YW5kIHdyaXRlcyBpdAorLy8gdG8gdzAuICBUaGlzIG1lYW5zIHRoYXQgdGhlIG5leHQgKHcwLCB3 MSwgdzIsIHczKSBpcyB0aGUgY3VycmVudCAodzEsIHcyLCB3MywKKy8vIHcwKSwgc28gdGhlIGNh bGxlciBtdXN0IGN5Y2xlIHRocm91Z2ggdGhlIHJlZ2lzdGVycyBhY2NvcmRpbmdseS4KKy5tYWNy bwlzaGEyNTZfNHJvdW5kcwlsYXN0LCBrLCB3MCwgdzEsIHcyLCB3MworCXZhZGQudnYJCVZUTVAs IFxrLCBcdzAKKwl2c2hhMmNsLnZ2CUhHREMsIEZFQkEsIFZUTVAKKwl2c2hhMmNoLnZ2CUZFQkEs IEhHREMsIFZUTVAKKy5pZiAhXGxhc3QKKwl2bWVyZ2UudnZtCVZUTVAsIFx3MiwgXHcxLCBNQVNL CisJdnNoYTJtcy52dglcdzAsIFZUTVAsIFx3MworLmVuZGlmCisuZW5kbQorCisubWFjcm8Jc2hh MjU2XzE2cm91bmRzCWxhc3QsIGswLCBrMSwgazIsIGszCisJc2hhMjU2XzRyb3VuZHMJXGxhc3Qs IFxrMCwgVzAsIFcxLCBXMiwgVzMKKwlzaGEyNTZfNHJvdW5kcwlcbGFzdCwgXGsxLCBXMSwgVzIs IFczLCBXMAorCXNoYTI1Nl80cm91bmRzCVxsYXN0LCBcazIsIFcyLCBXMywgVzAsIFcxCisJc2hh MjU2XzRyb3VuZHMJXGxhc3QsIFxrMywgVzMsIFcwLCBXMSwgVzIKKy5lbmRtCisKKy8vIHZvaWQg c2hhMjU2X3RyYW5zZm9ybV96dmtuaGFfb3JfenZrbmhiX3p2a2IodTMyIHN0YXRlWzhdLCBjb25z dCB1OCAqZGF0YSwKKy8vCQkJCQkgICAgICAgaW50IG51bV9ibG9ja3MpOworU1lNX1RZUEVEX0ZV TkNfU1RBUlQoc2hhMjU2X3RyYW5zZm9ybV96dmtuaGFfb3JfenZrbmhiX3p2a2IpCisKKwkvLyBM b2FkIHRoZSByb3VuZCBjb25zdGFudHMgaW50byBLMC1LMTUuCisJdnNldGl2bGkJemVybywgNCwg ZTMyLCBtMSwgdGEsIG1hCisJbGEJCXQwLCBLMjU2CisJdmxlMzIudgkJSzAsICh0MCkKKwlhZGRp CQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzEsICh0MCkKKwlhZGRpCQl0MCwgdDAsIDE2CisJdmxl MzIudgkJSzIsICh0MCkKKwlhZGRpCQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzMsICh0MCkKKwlh ZGRpCQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzQsICh0MCkKKwlhZGRpCQl0MCwgdDAsIDE2CisJ dmxlMzIudgkJSzUsICh0MCkKKwlhZGRpCQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzYsICh0MCkK KwlhZGRpCQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzcsICh0MCkKKwlhZGRpCQl0MCwgdDAsIDE2 CisJdmxlMzIudgkJSzgsICh0MCkKKwlhZGRpCQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzksICh0 MCkKKwlhZGRpCQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzEwLCAodDApCisJYWRkaQkJdDAsIHQw LCAxNgorCXZsZTMyLnYJCUsxMSwgKHQwKQorCWFkZGkJCXQwLCB0MCwgMTYKKwl2bGUzMi52CQlL MTIsICh0MCkKKwlhZGRpCQl0MCwgdDAsIDE2CisJdmxlMzIudgkJSzEzLCAodDApCisJYWRkaQkJ dDAsIHQwLCAxNgorCXZsZTMyLnYJCUsxNCwgKHQwKQorCWFkZGkJCXQwLCB0MCwgMTYKKwl2bGUz Mi52CQlLMTUsICh0MCkKKworCS8vIFNldHVwIG1hc2sgZm9yIHRoZSB2bWVyZ2UgdG8gcmVwbGFj ZSB0aGUgZmlyc3Qgd29yZCAoaWR4PT0wKSBpbgorCS8vIG1lc3NhZ2Ugc2NoZWR1bGluZy4gIFRo ZXJlIGFyZSA0IHdvcmRzLCBzbyBhbiA4LWJpdCBtYXNrIHN1ZmZpY2VzLgorCXZzZXRpdmxpCXpl cm8sIDEsIGU4LCBtMSwgdGEsIG1hCisJdm12LnYuaQkJTUFTSywgMHgwMQorCisJLy8gTG9hZCB0 aGUgc3RhdGUuICBUaGUgc3RhdGUgaXMgc3RvcmVkIGFzIHthLGIsYyxkLGUsZixnLGh9LCBidXQg d2UKKwkvLyBuZWVkIHtmLGUsYixhfSx7aCxnLGQsY30uICBUaGUgZHN0IHZ0eXBlIGlzIGUzMm0x IGFuZCB0aGUgaW5kZXggdnR5cGUKKwkvLyBpcyBlOG1mNC4gIFdlIHVzZSBpbmRleC1sb2FkIHdp dGggdGhlIGk4IGluZGljZXMgezIwLCAxNiwgNCwgMH0sCisJLy8gbG9hZGVkIHVzaW5nIHRoZSAz Mi1iaXQgbGl0dGxlIGVuZGlhbiB2YWx1ZSAweDAwMDQxMDE0LgorCWxpCQl0MCwgMHgwMDA0MTAx NAorCXZzZXRpdmxpCXplcm8sIDEsIGUzMiwgbTEsIHRhLCBtYQorCXZtdi52LngJCUlORElDRVMs IHQwCisJYWRkaQkJU1RBVEVQX0MsIFNUQVRFUCwgOAorCXZzZXRpdmxpCXplcm8sIDQsIGUzMiwg bTEsIHRhLCBtYQorCXZsdXhlaTgudglGRUJBLCAoU1RBVEVQKSwgSU5ESUNFUworCXZsdXhlaTgu dglIR0RDLCAoU1RBVEVQX0MpLCBJTkRJQ0VTCisKKy5MbmV4dF9ibG9jazoKKwlhZGRpCQlOVU1f QkxPQ0tTLCBOVU1fQkxPQ0tTLCAtMQorCisJLy8gU2F2ZSB0aGUgcHJldmlvdXMgc3RhdGUsIGFz IGl0J3MgbmVlZGVkIGxhdGVyLgorCXZtdi52LnYJCVBSRVZfRkVCQSwgRkVCQQorCXZtdi52LnYJ CVBSRVZfSEdEQywgSEdEQworCisJLy8gTG9hZCB0aGUgbmV4dCA1MTItYml0IG1lc3NhZ2UgYmxv Y2sgYW5kIGVuZGlhbi1zd2FwIGVhY2ggMzItYml0IHdvcmQuCisJdmxlMzIudgkJVzAsIChEQVRB KQorCXZyZXY4LnYJCVcwLCBXMAorCWFkZGkJCURBVEEsIERBVEEsIDE2CisJdmxlMzIudgkJVzEs IChEQVRBKQorCXZyZXY4LnYJCVcxLCBXMQorCWFkZGkJCURBVEEsIERBVEEsIDE2CisJdmxlMzIu dgkJVzIsIChEQVRBKQorCXZyZXY4LnYJCVcyLCBXMgorCWFkZGkJCURBVEEsIERBVEEsIDE2CisJ dmxlMzIudgkJVzMsIChEQVRBKQorCXZyZXY4LnYJCVczLCBXMworCWFkZGkJCURBVEEsIERBVEEs IDE2CisKKwkvLyBEbyB0aGUgNjQgcm91bmRzIG9mIFNIQS0yNTYuCisJc2hhMjU2XzE2cm91bmRz CTAsIEswLCBLMSwgSzIsIEszCisJc2hhMjU2XzE2cm91bmRzCTAsIEs0LCBLNSwgSzYsIEs3CisJ c2hhMjU2XzE2cm91bmRzCTAsIEs4LCBLOSwgSzEwLCBLMTEKKwlzaGEyNTZfMTZyb3VuZHMJMSwg SzEyLCBLMTMsIEsxNCwgSzE1CisKKwkvLyBBZGQgdGhlIHByZXZpb3VzIHN0YXRlLgorCXZhZGQu dnYJCUZFQkEsIEZFQkEsIFBSRVZfRkVCQQorCXZhZGQudnYJCUhHREMsIEhHREMsIFBSRVZfSEdE QworCisJLy8gUmVwZWF0IGlmIG1vcmUgYmxvY2tzIHJlbWFpbi4KKwlibmV6CQlOVU1fQkxPQ0tT LCAuTG5leHRfYmxvY2sKKworCS8vIFN0b3JlIHRoZSBuZXcgc3RhdGUgYW5kIHJldHVybi4KKwl2 c3V4ZWk4LnYJRkVCQSwgKFNUQVRFUCksIElORElDRVMKKwl2c3V4ZWk4LnYJSEdEQywgKFNUQVRF UF9DKSwgSU5ESUNFUworCXJldAorU1lNX0ZVTkNfRU5EKHNoYTI1Nl90cmFuc2Zvcm1fenZrbmhh X29yX3p2a25oYl96dmtiKQorCisuc2VjdGlvbiAiLnJvZGF0YSIKKy5wMmFsaWduIDIKKy50eXBl IEsyNTYsIEBvYmplY3QKK0syNTY6CisJLndvcmQJCTB4NDI4YTJmOTgsIDB4NzEzNzQ0OTEsIDB4 YjVjMGZiY2YsIDB4ZTliNWRiYTUKKwkud29yZAkJMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5 MjNmODJhNCwgMHhhYjFjNWVkNQorCS53b3JkCQkweGQ4MDdhYTk4LCAweDEyODM1YjAxLCAweDI0 MzE4NWJlLCAweDU1MGM3ZGMzCisJLndvcmQJCTB4NzJiZTVkNzQsIDB4ODBkZWIxZmUsIDB4OWJk YzA2YTcsIDB4YzE5YmYxNzQKKwkud29yZAkJMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMx OWRjNiwgMHgyNDBjYTFjYworCS53b3JkCQkweDJkZTkyYzZmLCAweDRhNzQ4NGFhLCAweDVjYjBh OWRjLCAweDc2Zjk4OGRhCisJLndvcmQJCTB4OTgzZTUxNTIsIDB4YTgzMWM2NmQsIDB4YjAwMzI3 YzgsIDB4YmY1OTdmYzcKKwkud29yZAkJMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1 MSwgMHgxNDI5Mjk2NworCS53b3JkCQkweDI3YjcwYTg1LCAweDJlMWIyMTM4LCAweDRkMmM2ZGZj LCAweDUzMzgwZDEzCisJLndvcmQJCTB4NjUwYTczNTQsIDB4NzY2YTBhYmIsIDB4ODFjMmM5MmUs IDB4OTI3MjJjODUKKwkud29yZAkJMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwg MHhjNzZjNTFhMworCS53b3JkCQkweGQxOTJlODE5LCAweGQ2OTkwNjI0LCAweGY0MGUzNTg1LCAw eDEwNmFhMDcwCisJLndvcmQJCTB4MTlhNGMxMTYsIDB4MWUzNzZjMDgsIDB4Mjc0ODc3NGMsIDB4 MzRiMGJjYjUKKwkud29yZAkJMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2 ODJlNmZmMworCS53b3JkCQkweDc0OGY4MmVlLCAweDc4YTU2MzZmLCAweDg0Yzg3ODE0LCAweDhj YzcwMjA4CisJLndvcmQJCTB4OTBiZWZmZmEsIDB4YTQ1MDZjZWIsIDB4YmVmOWEzZjcsIDB4YzY3 MTc4ZjIKKy5zaXplIEsyNTYsIC4gLSBLMjU2Ci0tIAoyLjQzLjAKCgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1yaXNjdiBtYWlsaW5nIGxpc3QK bGludXgtcmlzY3ZAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9y Zy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LXJpc2N2Cg==