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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8A8DC07545 for ; Wed, 25 Oct 2023 18:37:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234762AbjJYShZ (ORCPT ); Wed, 25 Oct 2023 14:37:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234719AbjJYShV (ORCPT ); Wed, 25 Oct 2023 14:37:21 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8842A18D for ; Wed, 25 Oct 2023 11:37:12 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-1c9d407bb15so16125ad.0 for ; Wed, 25 Oct 2023 11:37:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1698259032; x=1698863832; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MWKTD/SWI8njkmgyeeN+5f9jkvLnhIgL7e3VWIYvG8Q=; b=OligZW4ClXoFMTp8YmdWgUfsaapPuy6hpOpQA9zMBmB1EXNnFxE1dd7VV14ml5FDBM yTkYGMcI61LSTl7Z8KwhU/vfP0K5Fb499YEzUqFtA1mx7CxkLOnClJGMhZhsAzx4uQkA Q52tvYCe4x1yD8jOwHskx78991r7AWed5ajzE5wJ62/b4Jp5Xj+R4qYxpHdGIOXlPqop LTww+Rm0tubgnfiO16wIW8Laz9h3xjkI8xR517eoJpA0hiV2h7QKhCVjCbzBqUqzbOwB PfKaB7gIyJymwQMgDF8a1cT5Hf8/PkZDJiGSqKxoxnM+X1nU65G1edz+D4kHz/c9lY2Q +ETA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698259032; x=1698863832; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MWKTD/SWI8njkmgyeeN+5f9jkvLnhIgL7e3VWIYvG8Q=; b=noBiCAkLq9gNka6w3JL4PLTrQ1F3G457pqy3DCkqBUzChhe6sQQPNYyStLITII8WdB gTtHpiD+gTWTfiy70bKyQnH+z2XunjC6AYnpeb6bdWXe6JhWE93EcUmeZdagph9JmJOe yvHm08XsbtFfi0Icqq1NDzAY+wghlXl71LqZjkyMQhhL9fHdxb8ikchqJlQxibJZfLGz BB7WvhYUEKqXmHEf2wmnycWq/DcB/o62oKgXFASHTDQxA0SQDWFecANs+R44XtC9aETo WF40zhVefdEWjB1iUQZKjMY8DvLX9qOgVfaO7m4G8CqjVl18p0FspUt7quUREpgS4tq7 s61A== X-Gm-Message-State: AOJu0YwxLn0b+fH536vIeWPfy2bc90BYL/itJgtsziV/rxq/WTuO3x8H QS15IbDm8l8Ry1kAiSBkn2dA+g== X-Google-Smtp-Source: AGHT+IGRNYQPO/oiPp8ACsYhU0M5aGJ04WqOdeXXrN2GlGvrHQNkylxeMduls440BMus9XknRraQ5g== X-Received: by 2002:a17:90a:7442:b0:27d:9b67:7fa6 with SMTP id o2-20020a17090a744200b0027d9b677fa6mr14293424pjk.3.1698259031716; Wed, 25 Oct 2023 11:37:11 -0700 (PDT) Received: from localhost.localdomain ([49.216.222.119]) by smtp.gmail.com with ESMTPSA id g3-20020a17090adb0300b00278f1512dd9sm212367pjv.32.2023.10.25.11.37.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Oct 2023 11:37:11 -0700 (PDT) From: Jerry Shih To: paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, herbert@gondor.apana.org.au, davem@davemloft.net Cc: andy.chiu@sifive.com, greentime.hu@sifive.com, conor.dooley@microchip.com, guoren@kernel.org, bjorn@rivosinc.com, heiko@sntech.de, ebiggers@kernel.org, ardb@kernel.org, phoebe.chen@sifive.com, hongrong.hsu@sifive.com, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org Subject: [PATCH 04/12] RISC-V: crypto: add Zvkned accelerated AES implementation Date: Thu, 26 Oct 2023 02:36:36 +0800 Message-Id: <20231025183644.8735-5-jerry.shih@sifive.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20231025183644.8735-1-jerry.shih@sifive.com> References: <20231025183644.8735-1-jerry.shih@sifive.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org The AES implementation using the Zvkned vector crypto extension from OpenSSL(openssl/openssl#21923). Co-developed-by: Christoph Müllner Signed-off-by: Christoph Müllner 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 --- arch/riscv/crypto/Kconfig | 12 + arch/riscv/crypto/Makefile | 11 + arch/riscv/crypto/aes-riscv64-glue.c | 163 +++++++++ arch/riscv/crypto/aes-riscv64-glue.h | 28 ++ arch/riscv/crypto/aes-riscv64-zvkned.pl | 451 ++++++++++++++++++++++++ 5 files changed, 665 insertions(+) create mode 100644 arch/riscv/crypto/aes-riscv64-glue.c create mode 100644 arch/riscv/crypto/aes-riscv64-glue.h create mode 100644 arch/riscv/crypto/aes-riscv64-zvkned.pl diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig index 10d60edc0110..500938317e71 100644 --- a/arch/riscv/crypto/Kconfig +++ b/arch/riscv/crypto/Kconfig @@ -2,4 +2,16 @@ menu "Accelerated Cryptographic Algorithms for CPU (riscv)" +config CRYPTO_AES_RISCV64 + default y if RISCV_ISA_V + tristate "Ciphers: AES" + depends on 64BIT && RISCV_ISA_V + select CRYPTO_AES + select CRYPTO_ALGAPI + help + Block ciphers: AES cipher algorithms (FIPS-197) + + Architecture: riscv64 using: + - Zvkned vector crypto extension + endmenu diff --git a/arch/riscv/crypto/Makefile b/arch/riscv/crypto/Makefile index b3b6332c9f6d..90ca91d8df26 100644 --- a/arch/riscv/crypto/Makefile +++ b/arch/riscv/crypto/Makefile @@ -2,3 +2,14 @@ # # linux/arch/riscv/crypto/Makefile # + +obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o +aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o + +quiet_cmd_perlasm = PERLASM $@ + cmd_perlasm = $(PERL) $(<) void $(@) + +$(obj)/aes-riscv64-zvkned.S: $(src)/aes-riscv64-zvkned.pl + $(call cmd,perlasm) + +clean-files += aes-riscv64-zvkned.S diff --git a/arch/riscv/crypto/aes-riscv64-glue.c b/arch/riscv/crypto/aes-riscv64-glue.c new file mode 100644 index 000000000000..5c4f1018d3aa --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-glue.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Port of the OpenSSL AES implementation for RISC-V + * + * 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 "aes-riscv64-glue.h" + +/* + * aes cipher using zvkned vector crypto extension + * + * All zvkned-based functions use encryption expending keys for both encryption + * and decryption. + */ +void rv64i_zvkned_encrypt(const u8 *in, u8 *out, const struct aes_key *key); +void rv64i_zvkned_decrypt(const u8 *in, u8 *out, const struct aes_key *key); + +static inline int aes_round_num(unsigned int keylen) +{ + switch (keylen) { + case AES_KEYSIZE_128: + return 10; + case AES_KEYSIZE_192: + return 12; + case AES_KEYSIZE_256: + return 14; + default: + return 0; + } +} + +int riscv64_aes_setkey(struct riscv64_aes_ctx *ctx, const u8 *key, + unsigned int keylen) +{ + /* + * The RISC-V AES vector crypto key expending doesn't support AES-192. + * We just use the generic software key expending here to simplify the key + * expending flow. + */ + u32 aes_rounds; + u32 key_length; + int ret; + + ret = aes_expandkey(&ctx->fallback_ctx, key, keylen); + if (ret < 0) + return -EINVAL; + + /* + * Copy the key from `crypto_aes_ctx` to `aes_key` for zvkned-based AES + * implementations. + */ + aes_rounds = aes_round_num(keylen); + ctx->key.rounds = aes_rounds; + key_length = AES_BLOCK_SIZE * (aes_rounds + 1); + memcpy(ctx->key.key, ctx->fallback_ctx.key_enc, key_length); + + return 0; +} + +void riscv64_aes_encrypt_zvkned(const struct riscv64_aes_ctx *ctx, u8 *dst, + const u8 *src) +{ + if (crypto_simd_usable()) { + kernel_vector_begin(); + rv64i_zvkned_encrypt(src, dst, &ctx->key); + kernel_vector_end(); + } else { + aes_encrypt(&ctx->fallback_ctx, dst, src); + } +} + +void riscv64_aes_decrypt_zvkned(const struct riscv64_aes_ctx *ctx, u8 *dst, + const u8 *src) +{ + if (crypto_simd_usable()) { + kernel_vector_begin(); + rv64i_zvkned_decrypt(src, dst, &ctx->key); + kernel_vector_end(); + } else { + aes_decrypt(&ctx->fallback_ctx, dst, src); + } +} + +static int aes_setkey(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) +{ + struct riscv64_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + return riscv64_aes_setkey(ctx, key, keylen); +} + +static void aes_encrypt_zvkned(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +{ + const struct riscv64_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + riscv64_aes_encrypt_zvkned(ctx, dst, src); +} + +static void aes_decrypt_zvkned(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +{ + const struct riscv64_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + riscv64_aes_decrypt_zvkned(ctx, dst, src); +} + +static struct crypto_alg riscv64_aes_alg_zvkned = { + .cra_name = "aes", + .cra_driver_name = "aes-riscv64-zvkned", + .cra_module = THIS_MODULE, + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct riscv64_aes_ctx), + .cra_cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_setkey = aes_setkey, + .cia_encrypt = aes_encrypt_zvkned, + .cia_decrypt = aes_decrypt_zvkned, + }, +}; + +static inline bool check_aes_ext(void) +{ + return riscv_isa_extension_available(NULL, ZVKNED) && + riscv_vector_vlen() >= 128; +} + +static int __init riscv64_aes_mod_init(void) +{ + if (check_aes_ext()) + return crypto_register_alg(&riscv64_aes_alg_zvkned); + + return -ENODEV; +} + +static void __exit riscv64_aes_mod_fini(void) +{ + if (check_aes_ext()) + crypto_unregister_alg(&riscv64_aes_alg_zvkned); +} + +module_init(riscv64_aes_mod_init); +module_exit(riscv64_aes_mod_fini); + +MODULE_DESCRIPTION("AES (RISC-V accelerated)"); +MODULE_AUTHOR("Heiko Stuebner "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CRYPTO("aes"); diff --git a/arch/riscv/crypto/aes-riscv64-glue.h b/arch/riscv/crypto/aes-riscv64-glue.h new file mode 100644 index 000000000000..7f1f675aca0d --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-glue.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef AES_RISCV64_GLUE_H +#define AES_RISCV64_GLUE_H + +#include +#include + +struct aes_key { + u32 key[AES_MAX_KEYLENGTH_U32]; + u32 rounds; +}; + +struct riscv64_aes_ctx { + struct aes_key key; + struct crypto_aes_ctx fallback_ctx; +}; + +int riscv64_aes_setkey(struct riscv64_aes_ctx *ctx, const u8 *key, + unsigned int keylen); + +void riscv64_aes_encrypt_zvkned(const struct riscv64_aes_ctx *ctx, u8 *dst, + const u8 *src); + +void riscv64_aes_decrypt_zvkned(const struct riscv64_aes_ctx *ctx, u8 *dst, + const u8 *src); + +#endif /* AES_RISCV64_GLUE_H */ diff --git a/arch/riscv/crypto/aes-riscv64-zvkned.pl b/arch/riscv/crypto/aes-riscv64-zvkned.pl new file mode 100644 index 000000000000..c0ecde77bf56 --- /dev/null +++ b/arch/riscv/crypto/aes-riscv64-zvkned.pl @@ -0,0 +1,451 @@ +#! /usr/bin/env perl +# 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 +# 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. + +# - RV64I +# - RISC-V Vector ('V') with VLEN >= 128 +# - RISC-V Vector AES block cipher extension ('Zvkned') + +use strict; +use warnings; + +use FindBin qw($Bin); +use lib "$Bin"; +use lib "$Bin/../../perlasm"; +use riscv; + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; + +my $code=<<___; +.text +___ + +my ($V0, $V1, $V2, $V3, $V4, $V5, $V6, $V7, + $V8, $V9, $V10, $V11, $V12, $V13, $V14, $V15, + $V16, $V17, $V18, $V19, $V20, $V21, $V22, $V23, + $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31, +) = map("v$_",(0..31)); + +{ +################################################################################ +# void rv64i_zvkned_encrypt(const unsigned char *in, unsigned char *out, +# const AES_KEY *key); +my ($INP, $OUTP, $KEYP) = ("a0", "a1", "a2"); +my ($T0, $T1, $ROUNDS, $T6) = ("a3", "a4", "t5", "t6"); + +$code .= <<___; +.p2align 3 +.globl rv64i_zvkned_encrypt +.type rv64i_zvkned_encrypt,\@function +rv64i_zvkned_encrypt: + # Load number of rounds + lwu $ROUNDS, 240($KEYP) + + # Get proper routine for key size + li $T6, 14 + beq $ROUNDS, $T6, L_enc_256 + li $T6, 10 + beq $ROUNDS, $T6, L_enc_128 + li $T6, 12 + beq $ROUNDS, $T6, L_enc_192 + + j L_fail_m2 +.size rv64i_zvkned_encrypt,.-rv64i_zvkned_encrypt +___ + +$code .= <<___; +.p2align 3 +L_enc_128: + @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]} + + @{[vle32_v $V1, ($INP)]} + + @{[vle32_v $V10, ($KEYP)]} + @{[vaesz_vs $V1, $V10]} # with round key w[ 0, 3] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V11, ($KEYP)]} + @{[vaesem_vs $V1, $V11]} # with round key w[ 4, 7] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V12, ($KEYP)]} + @{[vaesem_vs $V1, $V12]} # with round key w[ 8,11] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V13, ($KEYP)]} + @{[vaesem_vs $V1, $V13]} # with round key w[12,15] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V14, ($KEYP)]} + @{[vaesem_vs $V1, $V14]} # with round key w[16,19] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V15, ($KEYP)]} + @{[vaesem_vs $V1, $V15]} # with round key w[20,23] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V16, ($KEYP)]} + @{[vaesem_vs $V1, $V16]} # with round key w[24,27] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V17, ($KEYP)]} + @{[vaesem_vs $V1, $V17]} # with round key w[28,31] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V18, ($KEYP)]} + @{[vaesem_vs $V1, $V18]} # with round key w[32,35] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V19, ($KEYP)]} + @{[vaesem_vs $V1, $V19]} # with round key w[36,39] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V20, ($KEYP)]} + @{[vaesef_vs $V1, $V20]} # with round key w[40,43] + + @{[vse32_v $V1, ($OUTP)]} + + ret +.size L_enc_128,.-L_enc_128 +___ + +$code .= <<___; +.p2align 3 +L_enc_192: + @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]} + + @{[vle32_v $V1, ($INP)]} + + @{[vle32_v $V10, ($KEYP)]} + @{[vaesz_vs $V1, $V10]} # with round key w[ 0, 3] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V11, ($KEYP)]} + @{[vaesem_vs $V1, $V11]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V12, ($KEYP)]} + @{[vaesem_vs $V1, $V12]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V13, ($KEYP)]} + @{[vaesem_vs $V1, $V13]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V14, ($KEYP)]} + @{[vaesem_vs $V1, $V14]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V15, ($KEYP)]} + @{[vaesem_vs $V1, $V15]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V16, ($KEYP)]} + @{[vaesem_vs $V1, $V16]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V17, ($KEYP)]} + @{[vaesem_vs $V1, $V17]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V18, ($KEYP)]} + @{[vaesem_vs $V1, $V18]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V19, ($KEYP)]} + @{[vaesem_vs $V1, $V19]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V20, ($KEYP)]} + @{[vaesem_vs $V1, $V20]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V21, ($KEYP)]} + @{[vaesem_vs $V1, $V21]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V22, ($KEYP)]} + @{[vaesef_vs $V1, $V22]} + + @{[vse32_v $V1, ($OUTP)]} + ret +.size L_enc_192,.-L_enc_192 +___ + +$code .= <<___; +.p2align 3 +L_enc_256: + @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]} + + @{[vle32_v $V1, ($INP)]} + + @{[vle32_v $V10, ($KEYP)]} + @{[vaesz_vs $V1, $V10]} # with round key w[ 0, 3] + addi $KEYP, $KEYP, 16 + @{[vle32_v $V11, ($KEYP)]} + @{[vaesem_vs $V1, $V11]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V12, ($KEYP)]} + @{[vaesem_vs $V1, $V12]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V13, ($KEYP)]} + @{[vaesem_vs $V1, $V13]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V14, ($KEYP)]} + @{[vaesem_vs $V1, $V14]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V15, ($KEYP)]} + @{[vaesem_vs $V1, $V15]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V16, ($KEYP)]} + @{[vaesem_vs $V1, $V16]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V17, ($KEYP)]} + @{[vaesem_vs $V1, $V17]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V18, ($KEYP)]} + @{[vaesem_vs $V1, $V18]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V19, ($KEYP)]} + @{[vaesem_vs $V1, $V19]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V20, ($KEYP)]} + @{[vaesem_vs $V1, $V20]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V21, ($KEYP)]} + @{[vaesem_vs $V1, $V21]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V22, ($KEYP)]} + @{[vaesem_vs $V1, $V22]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V23, ($KEYP)]} + @{[vaesem_vs $V1, $V23]} + addi $KEYP, $KEYP, 16 + @{[vle32_v $V24, ($KEYP)]} + @{[vaesef_vs $V1, $V24]} + + @{[vse32_v $V1, ($OUTP)]} + ret +.size L_enc_256,.-L_enc_256 +___ + +################################################################################ +# void rv64i_zvkned_decrypt(const unsigned char *in, unsigned char *out, +# const AES_KEY *key); +$code .= <<___; +.p2align 3 +.globl rv64i_zvkned_decrypt +.type rv64i_zvkned_decrypt,\@function +rv64i_zvkned_decrypt: + # Load number of rounds + lwu $ROUNDS, 240($KEYP) + + # Get proper routine for key size + li $T6, 14 + beq $ROUNDS, $T6, L_dec_256 + li $T6, 10 + beq $ROUNDS, $T6, L_dec_128 + li $T6, 12 + beq $ROUNDS, $T6, L_dec_192 + + j L_fail_m2 +.size rv64i_zvkned_decrypt,.-rv64i_zvkned_decrypt +___ + +$code .= <<___; +.p2align 3 +L_dec_128: + @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]} + + @{[vle32_v $V1, ($INP)]} + + addi $KEYP, $KEYP, 160 + @{[vle32_v $V20, ($KEYP)]} + @{[vaesz_vs $V1, $V20]} # with round key w[40,43] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V19, ($KEYP)]} + @{[vaesdm_vs $V1, $V19]} # with round key w[36,39] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V18, ($KEYP)]} + @{[vaesdm_vs $V1, $V18]} # with round key w[32,35] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V17, ($KEYP)]} + @{[vaesdm_vs $V1, $V17]} # with round key w[28,31] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V16, ($KEYP)]} + @{[vaesdm_vs $V1, $V16]} # with round key w[24,27] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V15, ($KEYP)]} + @{[vaesdm_vs $V1, $V15]} # with round key w[20,23] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V14, ($KEYP)]} + @{[vaesdm_vs $V1, $V14]} # with round key w[16,19] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V13, ($KEYP)]} + @{[vaesdm_vs $V1, $V13]} # with round key w[12,15] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V12, ($KEYP)]} + @{[vaesdm_vs $V1, $V12]} # with round key w[ 8,11] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V11, ($KEYP)]} + @{[vaesdm_vs $V1, $V11]} # with round key w[ 4, 7] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V10, ($KEYP)]} + @{[vaesdf_vs $V1, $V10]} # with round key w[ 0, 3] + + @{[vse32_v $V1, ($OUTP)]} + + ret +.size L_dec_128,.-L_dec_128 +___ + +$code .= <<___; +.p2align 3 +L_dec_192: + @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]} + + @{[vle32_v $V1, ($INP)]} + + addi $KEYP, $KEYP, 192 + @{[vle32_v $V22, ($KEYP)]} + @{[vaesz_vs $V1, $V22]} # with round key w[48,51] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V21, ($KEYP)]} + @{[vaesdm_vs $V1, $V21]} # with round key w[44,47] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V20, ($KEYP)]} + @{[vaesdm_vs $V1, $V20]} # with round key w[40,43] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V19, ($KEYP)]} + @{[vaesdm_vs $V1, $V19]} # with round key w[36,39] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V18, ($KEYP)]} + @{[vaesdm_vs $V1, $V18]} # with round key w[32,35] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V17, ($KEYP)]} + @{[vaesdm_vs $V1, $V17]} # with round key w[28,31] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V16, ($KEYP)]} + @{[vaesdm_vs $V1, $V16]} # with round key w[24,27] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V15, ($KEYP)]} + @{[vaesdm_vs $V1, $V15]} # with round key w[20,23] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V14, ($KEYP)]} + @{[vaesdm_vs $V1, $V14]} # with round key w[16,19] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V13, ($KEYP)]} + @{[vaesdm_vs $V1, $V13]} # with round key w[12,15] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V12, ($KEYP)]} + @{[vaesdm_vs $V1, $V12]} # with round key w[ 8,11] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V11, ($KEYP)]} + @{[vaesdm_vs $V1, $V11]} # with round key w[ 4, 7] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V10, ($KEYP)]} + @{[vaesdf_vs $V1, $V10]} # with round key w[ 0, 3] + + @{[vse32_v $V1, ($OUTP)]} + + ret +.size L_dec_192,.-L_dec_192 +___ + +$code .= <<___; +.p2align 3 +L_dec_256: + @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]} + + @{[vle32_v $V1, ($INP)]} + + addi $KEYP, $KEYP, 224 + @{[vle32_v $V24, ($KEYP)]} + @{[vaesz_vs $V1, $V24]} # with round key w[56,59] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V23, ($KEYP)]} + @{[vaesdm_vs $V1, $V23]} # with round key w[52,55] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V22, ($KEYP)]} + @{[vaesdm_vs $V1, $V22]} # with round key w[48,51] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V21, ($KEYP)]} + @{[vaesdm_vs $V1, $V21]} # with round key w[44,47] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V20, ($KEYP)]} + @{[vaesdm_vs $V1, $V20]} # with round key w[40,43] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V19, ($KEYP)]} + @{[vaesdm_vs $V1, $V19]} # with round key w[36,39] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V18, ($KEYP)]} + @{[vaesdm_vs $V1, $V18]} # with round key w[32,35] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V17, ($KEYP)]} + @{[vaesdm_vs $V1, $V17]} # with round key w[28,31] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V16, ($KEYP)]} + @{[vaesdm_vs $V1, $V16]} # with round key w[24,27] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V15, ($KEYP)]} + @{[vaesdm_vs $V1, $V15]} # with round key w[20,23] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V14, ($KEYP)]} + @{[vaesdm_vs $V1, $V14]} # with round key w[16,19] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V13, ($KEYP)]} + @{[vaesdm_vs $V1, $V13]} # with round key w[12,15] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V12, ($KEYP)]} + @{[vaesdm_vs $V1, $V12]} # with round key w[ 8,11] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V11, ($KEYP)]} + @{[vaesdm_vs $V1, $V11]} # with round key w[ 4, 7] + addi $KEYP, $KEYP, -16 + @{[vle32_v $V10, ($KEYP)]} + @{[vaesdf_vs $V1, $V10]} # with round key w[ 0, 3] + + @{[vse32_v $V1, ($OUTP)]} + + ret +.size L_dec_256,.-L_dec_256 +___ +} + +$code .= <<___; +L_fail_m1: + li a0, -1 + ret +.size L_fail_m1,.-L_fail_m1 + +L_fail_m2: + li a0, -2 + ret +.size L_fail_m2,.-L_fail_m2 + +L_end: + ret +.size L_end,.-L_end +___ + +print $code; + +close STDOUT or die "error closing STDOUT: $!"; -- 2.28.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 9A1DDC25B6B for ; Wed, 25 Oct 2023 18:37:24 +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=iopCh14HeORXbMyRf1zindI09wWGUzgItOQXAlwrgmA=; b=2W7p16Ou3RBNXZ dtPI1kqucQyooZpHRB4IvGAWQjuT6Hv2I4XpTOuX1AWwNwt4JH/21uVlbbcm90n2Wiw+Sn6iB5kGH PP2dL8QemXaoDy5URAaF0dlUc3/IJDQ0QR54R70brtIC9F8Vdf/8xIAAGVqfjOxC2yP4ZdwA7+04Z V397sywaz+QgDAkyvOeimHQj3yRmhWSo6fRhpbwTG4exh+CpiiAIRdfVz3REf/Ui+MlrOtQ60OqUK tsBvC3+BB2NdbLuB24guT7QdPtgDVQlC4f+2+U+p5jkhYNmsRh5CFd5rzsgaeGujVT4s0zFCBSikz aQt6RmgekER6n11Ogqgw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qvikp-00CsIk-2p; Wed, 25 Oct 2023 18:37:19 +0000 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qvikk-00CsGO-2x for linux-riscv@lists.infradead.org; Wed, 25 Oct 2023 18:37:18 +0000 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-27d3ede72f6so10686a91.1 for ; Wed, 25 Oct 2023 11:37:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1698259032; x=1698863832; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MWKTD/SWI8njkmgyeeN+5f9jkvLnhIgL7e3VWIYvG8Q=; b=mPvh8/BfMyqKV9Jqa71Q3avHIktcrBkN7lDp3k7Azemfcwf1/AcuYkFLuH9cZcP0D+ 2rEFwG7SzVXhWz7VGtOubRyyM0hp7TcJ5TGnqEJt4UJU35nct67+ol45fBfLb0DlI2YZ y+UzGyzsHyc61vTYqsGPIHSq5ZgHuUeB85UbcrBFACQa5g9skynh2L9NiJd/65rzh/JO G8OyUbPodwtQ0zJUKG33iMnGuh39GhTs4pSKAbZJCYLqgffMmmx5LpLI7BzXD48sB1BZ c7t2WXT2YVF6XjumlCOU1u9Mky3JeoWzB0LKCkRyNaF41EKfzlOsRmyma8jF4I412tmN DKjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698259032; x=1698863832; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MWKTD/SWI8njkmgyeeN+5f9jkvLnhIgL7e3VWIYvG8Q=; b=UyE5bZpjY/qmlwvanu87KCp9h6wZqUoEzTGUUSEmGnlmRWlxY+PovMfikeix9DWgwI aJ/dyqOuGDm4+sOzmqXmY1mwnVSBthTqv4YRfzE/CZFFh5KKJtaze09/H3jNO36RHWUe 6n+qZXDldxhwzqOun9GWL8F1GPDyz4ex4npNVmeUuyt3nwk/O2pZRQiQSa1RPF+ymRNc R+dnosurQsx3/rULZCULDbkCKqes5aCKkfbjX37m0FBdUBiC5ERbQPt5R5wzgadGL9OI avH6WRVXo6lvG4mnE0SHcCM/VhMUFfJ/x1pok8DgWZM7bGvNDC5lso440lRuR0ReeMmK TA1Q== X-Gm-Message-State: AOJu0YxAlAyCtpxQmAnYwsYccSYLCa1PZXx0Ja3pBvyghpl94A6EZHk5 PMV2eUSMUBNDZ35E0x1GGAnZ+w== X-Google-Smtp-Source: AGHT+IGRNYQPO/oiPp8ACsYhU0M5aGJ04WqOdeXXrN2GlGvrHQNkylxeMduls440BMus9XknRraQ5g== X-Received: by 2002:a17:90a:7442:b0:27d:9b67:7fa6 with SMTP id o2-20020a17090a744200b0027d9b677fa6mr14293424pjk.3.1698259031716; Wed, 25 Oct 2023 11:37:11 -0700 (PDT) Received: from localhost.localdomain ([49.216.222.119]) by smtp.gmail.com with ESMTPSA id g3-20020a17090adb0300b00278f1512dd9sm212367pjv.32.2023.10.25.11.37.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Oct 2023 11:37:11 -0700 (PDT) From: Jerry Shih To: paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, herbert@gondor.apana.org.au, davem@davemloft.net Cc: andy.chiu@sifive.com, greentime.hu@sifive.com, conor.dooley@microchip.com, guoren@kernel.org, bjorn@rivosinc.com, heiko@sntech.de, ebiggers@kernel.org, ardb@kernel.org, phoebe.chen@sifive.com, hongrong.hsu@sifive.com, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org Subject: [PATCH 04/12] RISC-V: crypto: add Zvkned accelerated AES implementation Date: Thu, 26 Oct 2023 02:36:36 +0800 Message-Id: <20231025183644.8735-5-jerry.shih@sifive.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20231025183644.8735-1-jerry.shih@sifive.com> References: <20231025183644.8735-1-jerry.shih@sifive.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231025_113714_966195_285CC02C X-CRM114-Status: GOOD ( 29.73 ) 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 VGhlIEFFUyBpbXBsZW1lbnRhdGlvbiB1c2luZyB0aGUgWnZrbmVkIHZlY3RvciBjcnlwdG8gZXh0 ZW5zaW9uIGZyb20KT3BlblNTTChvcGVuc3NsL29wZW5zc2wjMjE5MjMpLgoKQ28tZGV2ZWxvcGVk LWJ5OiBDaHJpc3RvcGggTcO8bGxuZXIgPGNocmlzdG9waC5tdWVsbG5lckB2cnVsbC5ldT4KU2ln bmVkLW9mZi1ieTogQ2hyaXN0b3BoIE3DvGxsbmVyIDxjaHJpc3RvcGgubXVlbGxuZXJAdnJ1bGwu ZXU+CkNvLWRldmVsb3BlZC1ieTogSGVpa28gU3R1ZWJuZXIgPGhlaWtvLnN0dWVibmVyQHZydWxs LmV1PgpTaWduZWQtb2ZmLWJ5OiBIZWlrbyBTdHVlYm5lciA8aGVpa28uc3R1ZWJuZXJAdnJ1bGwu ZXU+CkNvLWRldmVsb3BlZC1ieTogUGhvZWJlIENoZW4gPHBob2ViZS5jaGVuQHNpZml2ZS5jb20+ ClNpZ25lZC1vZmYtYnk6IFBob2ViZSBDaGVuIDxwaG9lYmUuY2hlbkBzaWZpdmUuY29tPgpTaWdu ZWQtb2ZmLWJ5OiBKZXJyeSBTaGloIDxqZXJyeS5zaGloQHNpZml2ZS5jb20+Ci0tLQogYXJjaC9y aXNjdi9jcnlwdG8vS2NvbmZpZyAgICAgICAgICAgICAgIHwgIDEyICsKIGFyY2gvcmlzY3YvY3J5 cHRvL01ha2VmaWxlICAgICAgICAgICAgICB8ICAxMSArCiBhcmNoL3Jpc2N2L2NyeXB0by9hZXMt cmlzY3Y2NC1nbHVlLmMgICAgfCAxNjMgKysrKysrKysrCiBhcmNoL3Jpc2N2L2NyeXB0by9hZXMt cmlzY3Y2NC1nbHVlLmggICAgfCAgMjggKysKIGFyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0 LXp2a25lZC5wbCB8IDQ1MSArKysrKysrKysrKysrKysrKysrKysrKysKIDUgZmlsZXMgY2hhbmdl ZCwgNjY1IGluc2VydGlvbnMoKykKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0 by9hZXMtcmlzY3Y2NC1nbHVlLmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0 by9hZXMtcmlzY3Y2NC1nbHVlLmgKIGNyZWF0ZSBtb2RlIDEwMDY0NCBhcmNoL3Jpc2N2L2NyeXB0 by9hZXMtcmlzY3Y2NC16dmtuZWQucGwKCmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2NyeXB0by9L Y29uZmlnIGIvYXJjaC9yaXNjdi9jcnlwdG8vS2NvbmZpZwppbmRleCAxMGQ2MGVkYzAxMTAuLjUw MDkzODMxN2U3MSAxMDA2NDQKLS0tIGEvYXJjaC9yaXNjdi9jcnlwdG8vS2NvbmZpZworKysgYi9h cmNoL3Jpc2N2L2NyeXB0by9LY29uZmlnCkBAIC0yLDQgKzIsMTYgQEAKIAogbWVudSAiQWNjZWxl cmF0ZWQgQ3J5cHRvZ3JhcGhpYyBBbGdvcml0aG1zIGZvciBDUFUgKHJpc2N2KSIKIAorY29uZmln IENSWVBUT19BRVNfUklTQ1Y2NAorCWRlZmF1bHQgeSBpZiBSSVNDVl9JU0FfVgorCXRyaXN0YXRl ICJDaXBoZXJzOiBBRVMiCisJZGVwZW5kcyBvbiA2NEJJVCAmJiBSSVNDVl9JU0FfVgorCXNlbGVj dCBDUllQVE9fQUVTCisJc2VsZWN0IENSWVBUT19BTEdBUEkKKwloZWxwCisJICBCbG9jayBjaXBo ZXJzOiBBRVMgY2lwaGVyIGFsZ29yaXRobXMgKEZJUFMtMTk3KQorCisJICBBcmNoaXRlY3R1cmU6 IHJpc2N2NjQgdXNpbmc6CisJICAtIFp2a25lZCB2ZWN0b3IgY3J5cHRvIGV4dGVuc2lvbgorCiBl bmRtZW51CmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2NyeXB0by9NYWtlZmlsZSBiL2FyY2gvcmlz Y3YvY3J5cHRvL01ha2VmaWxlCmluZGV4IGIzYjYzMzJjOWY2ZC4uOTBjYTkxZDhkZjI2IDEwMDY0 NAotLS0gYS9hcmNoL3Jpc2N2L2NyeXB0by9NYWtlZmlsZQorKysgYi9hcmNoL3Jpc2N2L2NyeXB0 by9NYWtlZmlsZQpAQCAtMiwzICsyLDE0IEBACiAjCiAjIGxpbnV4L2FyY2gvcmlzY3YvY3J5cHRv L01ha2VmaWxlCiAjCisKK29iai0kKENPTkZJR19DUllQVE9fQUVTX1JJU0NWNjQpICs9IGFlcy1y aXNjdjY0Lm8KK2Flcy1yaXNjdjY0LXkgOj0gYWVzLXJpc2N2NjQtZ2x1ZS5vIGFlcy1yaXNjdjY0 LXp2a25lZC5vCisKK3F1aWV0X2NtZF9wZXJsYXNtID0gUEVSTEFTTSAkQAorICAgICAgY21kX3Bl cmxhc20gPSAkKFBFUkwpICQoPCkgdm9pZCAkKEApCisKKyQob2JqKS9hZXMtcmlzY3Y2NC16dmtu ZWQuUzogJChzcmMpL2Flcy1yaXNjdjY0LXp2a25lZC5wbAorCSQoY2FsbCBjbWQscGVybGFzbSkK KworY2xlYW4tZmlsZXMgKz0gYWVzLXJpc2N2NjQtenZrbmVkLlMKZGlmZiAtLWdpdCBhL2FyY2gv cmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LWdsdWUuYyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1y aXNjdjY0LWdsdWUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjVj NGYxMDE4ZDNhYQotLS0gL2Rldi9udWxsCisrKyBiL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNj djY0LWdsdWUuYwpAQCAtMCwwICsxLDE2MyBAQAorLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6 IEdQTC0yLjAtb25seQorLyoKKyAqIFBvcnQgb2YgdGhlIE9wZW5TU0wgQUVTIGltcGxlbWVudGF0 aW9uIGZvciBSSVNDLVYKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMjMgVlJVTEwgR21iSAorICog QXV0aG9yOiBIZWlrbyBTdHVlYm5lciA8aGVpa28uc3R1ZWJuZXJAdnJ1bGwuZXU+CisgKgorICog Q29weXJpZ2h0IChDKSAyMDIzIFNpRml2ZSwgSW5jLgorICogQXV0aG9yOiBKZXJyeSBTaGloIDxq ZXJyeS5zaGloQHNpZml2ZS5jb20+CisgKi8KKworI2luY2x1ZGUgPGFzbS9zaW1kLmg+CisjaW5j bHVkZSA8YXNtL3ZlY3Rvci5oPgorI2luY2x1ZGUgPGNyeXB0by9hZXMuaD4KKyNpbmNsdWRlIDxj cnlwdG8vaW50ZXJuYWwvY2lwaGVyLmg+CisjaW5jbHVkZSA8Y3J5cHRvL2ludGVybmFsL3NpbWQu aD4KKyNpbmNsdWRlIDxsaW51eC9jcnlwdG8uaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4K KyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgorCisjaW5jbHVkZSAiYWVzLXJpc2N2NjQtZ2x1ZS5o IgorCisvKgorICogYWVzIGNpcGhlciB1c2luZyB6dmtuZWQgdmVjdG9yIGNyeXB0byBleHRlbnNp b24KKyAqCisgKiBBbGwgenZrbmVkLWJhc2VkIGZ1bmN0aW9ucyB1c2UgZW5jcnlwdGlvbiBleHBl bmRpbmcga2V5cyBmb3IgYm90aCBlbmNyeXB0aW9uCisgKiBhbmQgZGVjcnlwdGlvbi4KKyAqLwor dm9pZCBydjY0aV96dmtuZWRfZW5jcnlwdChjb25zdCB1OCAqaW4sIHU4ICpvdXQsIGNvbnN0IHN0 cnVjdCBhZXNfa2V5ICprZXkpOwordm9pZCBydjY0aV96dmtuZWRfZGVjcnlwdChjb25zdCB1OCAq aW4sIHU4ICpvdXQsIGNvbnN0IHN0cnVjdCBhZXNfa2V5ICprZXkpOworCitzdGF0aWMgaW5saW5l IGludCBhZXNfcm91bmRfbnVtKHVuc2lnbmVkIGludCBrZXlsZW4pCit7CisJc3dpdGNoIChrZXls ZW4pIHsKKwljYXNlIEFFU19LRVlTSVpFXzEyODoKKwkJcmV0dXJuIDEwOworCWNhc2UgQUVTX0tF WVNJWkVfMTkyOgorCQlyZXR1cm4gMTI7CisJY2FzZSBBRVNfS0VZU0laRV8yNTY6CisJCXJldHVy biAxNDsKKwlkZWZhdWx0OgorCQlyZXR1cm4gMDsKKwl9Cit9CisKK2ludCByaXNjdjY0X2Flc19z ZXRrZXkoc3RydWN0IHJpc2N2NjRfYWVzX2N0eCAqY3R4LCBjb25zdCB1OCAqa2V5LAorCQkgICAg ICAgdW5zaWduZWQgaW50IGtleWxlbikKK3sKKwkvKgorCSAqIFRoZSBSSVNDLVYgQUVTIHZlY3Rv ciBjcnlwdG8ga2V5IGV4cGVuZGluZyBkb2Vzbid0IHN1cHBvcnQgQUVTLTE5Mi4KKwkgKiBXZSBq dXN0IHVzZSB0aGUgZ2VuZXJpYyBzb2Z0d2FyZSBrZXkgZXhwZW5kaW5nIGhlcmUgdG8gc2ltcGxp ZnkgdGhlIGtleQorCSAqIGV4cGVuZGluZyBmbG93LgorCSAqLworCXUzMiBhZXNfcm91bmRzOwor CXUzMiBrZXlfbGVuZ3RoOworCWludCByZXQ7CisKKwlyZXQgPSBhZXNfZXhwYW5ka2V5KCZjdHgt PmZhbGxiYWNrX2N0eCwga2V5LCBrZXlsZW4pOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gLUVJ TlZBTDsKKworCS8qCisJICogQ29weSB0aGUga2V5IGZyb20gYGNyeXB0b19hZXNfY3R4YCB0byBg YWVzX2tleWAgZm9yIHp2a25lZC1iYXNlZCBBRVMKKwkgKiBpbXBsZW1lbnRhdGlvbnMuCisJICov CisJYWVzX3JvdW5kcyA9IGFlc19yb3VuZF9udW0oa2V5bGVuKTsKKwljdHgtPmtleS5yb3VuZHMg PSBhZXNfcm91bmRzOworCWtleV9sZW5ndGggPSBBRVNfQkxPQ0tfU0laRSAqIChhZXNfcm91bmRz ICsgMSk7CisJbWVtY3B5KGN0eC0+a2V5LmtleSwgY3R4LT5mYWxsYmFja19jdHgua2V5X2VuYywg a2V5X2xlbmd0aCk7CisKKwlyZXR1cm4gMDsKK30KKwordm9pZCByaXNjdjY0X2Flc19lbmNyeXB0 X3p2a25lZChjb25zdCBzdHJ1Y3QgcmlzY3Y2NF9hZXNfY3R4ICpjdHgsIHU4ICpkc3QsCisJCQkJ Y29uc3QgdTggKnNyYykKK3sKKwlpZiAoY3J5cHRvX3NpbWRfdXNhYmxlKCkpIHsKKwkJa2VybmVs X3ZlY3Rvcl9iZWdpbigpOworCQlydjY0aV96dmtuZWRfZW5jcnlwdChzcmMsIGRzdCwgJmN0eC0+ a2V5KTsKKwkJa2VybmVsX3ZlY3Rvcl9lbmQoKTsKKwl9IGVsc2UgeworCQlhZXNfZW5jcnlwdCgm Y3R4LT5mYWxsYmFja19jdHgsIGRzdCwgc3JjKTsKKwl9Cit9CisKK3ZvaWQgcmlzY3Y2NF9hZXNf ZGVjcnlwdF96dmtuZWQoY29uc3Qgc3RydWN0IHJpc2N2NjRfYWVzX2N0eCAqY3R4LCB1OCAqZHN0 LAorCQkJCWNvbnN0IHU4ICpzcmMpCit7CisJaWYgKGNyeXB0b19zaW1kX3VzYWJsZSgpKSB7CisJ CWtlcm5lbF92ZWN0b3JfYmVnaW4oKTsKKwkJcnY2NGlfenZrbmVkX2RlY3J5cHQoc3JjLCBkc3Qs ICZjdHgtPmtleSk7CisJCWtlcm5lbF92ZWN0b3JfZW5kKCk7CisJfSBlbHNlIHsKKwkJYWVzX2Rl Y3J5cHQoJmN0eC0+ZmFsbGJhY2tfY3R4LCBkc3QsIHNyYyk7CisJfQorfQorCitzdGF0aWMgaW50 IGFlc19zZXRrZXkoc3RydWN0IGNyeXB0b190Zm0gKnRmbSwgY29uc3QgdTggKmtleSwKKwkJICAg ICAgdW5zaWduZWQgaW50IGtleWxlbikKK3sKKwlzdHJ1Y3QgcmlzY3Y2NF9hZXNfY3R4ICpjdHgg PSBjcnlwdG9fdGZtX2N0eCh0Zm0pOworCisJcmV0dXJuIHJpc2N2NjRfYWVzX3NldGtleShjdHgs IGtleSwga2V5bGVuKTsKK30KKworc3RhdGljIHZvaWQgYWVzX2VuY3J5cHRfenZrbmVkKHN0cnVj dCBjcnlwdG9fdGZtICp0Zm0sIHU4ICpkc3QsIGNvbnN0IHU4ICpzcmMpCit7CisJY29uc3Qgc3Ry dWN0IHJpc2N2NjRfYWVzX2N0eCAqY3R4ID0gY3J5cHRvX3RmbV9jdHgodGZtKTsKKworCXJpc2N2 NjRfYWVzX2VuY3J5cHRfenZrbmVkKGN0eCwgZHN0LCBzcmMpOworfQorCitzdGF0aWMgdm9pZCBh ZXNfZGVjcnlwdF96dmtuZWQoc3RydWN0IGNyeXB0b190Zm0gKnRmbSwgdTggKmRzdCwgY29uc3Qg dTggKnNyYykKK3sKKwljb25zdCBzdHJ1Y3QgcmlzY3Y2NF9hZXNfY3R4ICpjdHggPSBjcnlwdG9f dGZtX2N0eCh0Zm0pOworCisJcmlzY3Y2NF9hZXNfZGVjcnlwdF96dmtuZWQoY3R4LCBkc3QsIHNy Yyk7Cit9CisKK3N0YXRpYyBzdHJ1Y3QgY3J5cHRvX2FsZyByaXNjdjY0X2Flc19hbGdfenZrbmVk ID0geworCS5jcmFfbmFtZSA9ICJhZXMiLAorCS5jcmFfZHJpdmVyX25hbWUgPSAiYWVzLXJpc2N2 NjQtenZrbmVkIiwKKwkuY3JhX21vZHVsZSA9IFRISVNfTU9EVUxFLAorCS5jcmFfcHJpb3JpdHkg PSAzMDAsCisJLmNyYV9mbGFncyA9IENSWVBUT19BTEdfVFlQRV9DSVBIRVIsCisJLmNyYV9ibG9j a3NpemUgPSBBRVNfQkxPQ0tfU0laRSwKKwkuY3JhX2N0eHNpemUgPSBzaXplb2Yoc3RydWN0IHJp c2N2NjRfYWVzX2N0eCksCisJLmNyYV9jaXBoZXIgPSB7CisJCS5jaWFfbWluX2tleXNpemUgPSBB RVNfTUlOX0tFWV9TSVpFLAorCQkuY2lhX21heF9rZXlzaXplID0gQUVTX01BWF9LRVlfU0laRSwK KwkJLmNpYV9zZXRrZXkgPSBhZXNfc2V0a2V5LAorCQkuY2lhX2VuY3J5cHQgPSBhZXNfZW5jcnlw dF96dmtuZWQsCisJCS5jaWFfZGVjcnlwdCA9IGFlc19kZWNyeXB0X3p2a25lZCwKKwl9LAorfTsK Kworc3RhdGljIGlubGluZSBib29sIGNoZWNrX2Flc19leHQodm9pZCkKK3sKKwlyZXR1cm4gcmlz Y3ZfaXNhX2V4dGVuc2lvbl9hdmFpbGFibGUoTlVMTCwgWlZLTkVEKSAmJgorCSAgICAgICByaXNj dl92ZWN0b3JfdmxlbigpID49IDEyODsKK30KKworc3RhdGljIGludCBfX2luaXQgcmlzY3Y2NF9h ZXNfbW9kX2luaXQodm9pZCkKK3sKKwlpZiAoY2hlY2tfYWVzX2V4dCgpKQorCQlyZXR1cm4gY3J5 cHRvX3JlZ2lzdGVyX2FsZygmcmlzY3Y2NF9hZXNfYWxnX3p2a25lZCk7CisKKwlyZXR1cm4gLUVO T0RFVjsKK30KKworc3RhdGljIHZvaWQgX19leGl0IHJpc2N2NjRfYWVzX21vZF9maW5pKHZvaWQp Cit7CisJaWYgKGNoZWNrX2Flc19leHQoKSkKKwkJY3J5cHRvX3VucmVnaXN0ZXJfYWxnKCZyaXNj djY0X2Flc19hbGdfenZrbmVkKTsKK30KKworbW9kdWxlX2luaXQocmlzY3Y2NF9hZXNfbW9kX2lu aXQpOworbW9kdWxlX2V4aXQocmlzY3Y2NF9hZXNfbW9kX2ZpbmkpOworCitNT0RVTEVfREVTQ1JJ UFRJT04oIkFFUyAoUklTQy1WIGFjY2VsZXJhdGVkKSIpOworTU9EVUxFX0FVVEhPUigiSGVpa28g U3R1ZWJuZXIgPGhlaWtvLnN0dWVibmVyQHZydWxsLmV1PiIpOworTU9EVUxFX0xJQ0VOU0UoIkdQ TCIpOworTU9EVUxFX0FMSUFTX0NSWVBUTygiYWVzIik7CmRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2 L2NyeXB0by9hZXMtcmlzY3Y2NC1nbHVlLmggYi9hcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlzY3Y2 NC1nbHVlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi43ZjFmNjc1 YWNhMGQKLS0tIC9kZXYvbnVsbAorKysgYi9hcmNoL3Jpc2N2L2NyeXB0by9hZXMtcmlzY3Y2NC1n bHVlLmgKQEAgLTAsMCArMSwyOCBAQAorLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjAgKi8KKworI2lmbmRlZiBBRVNfUklTQ1Y2NF9HTFVFX0gKKyNkZWZpbmUgQUVTX1JJU0NWNjRf R0xVRV9ICisKKyNpbmNsdWRlIDxjcnlwdG8vYWVzLmg+CisjaW5jbHVkZSA8bGludXgvdHlwZXMu aD4KKworc3RydWN0IGFlc19rZXkgeworCXUzMiBrZXlbQUVTX01BWF9LRVlMRU5HVEhfVTMyXTsK Kwl1MzIgcm91bmRzOworfTsKKworc3RydWN0IHJpc2N2NjRfYWVzX2N0eCB7CisJc3RydWN0IGFl c19rZXkga2V5OworCXN0cnVjdCBjcnlwdG9fYWVzX2N0eCBmYWxsYmFja19jdHg7Cit9OworCitp bnQgcmlzY3Y2NF9hZXNfc2V0a2V5KHN0cnVjdCByaXNjdjY0X2Flc19jdHggKmN0eCwgY29uc3Qg dTggKmtleSwKKwkJICAgICAgIHVuc2lnbmVkIGludCBrZXlsZW4pOworCit2b2lkIHJpc2N2NjRf YWVzX2VuY3J5cHRfenZrbmVkKGNvbnN0IHN0cnVjdCByaXNjdjY0X2Flc19jdHggKmN0eCwgdTgg KmRzdCwKKwkJCQljb25zdCB1OCAqc3JjKTsKKwordm9pZCByaXNjdjY0X2Flc19kZWNyeXB0X3p2 a25lZChjb25zdCBzdHJ1Y3QgcmlzY3Y2NF9hZXNfY3R4ICpjdHgsIHU4ICpkc3QsCisJCQkJY29u c3QgdTggKnNyYyk7CisKKyNlbmRpZiAvKiBBRVNfUklTQ1Y2NF9HTFVFX0ggKi8KZGlmZiAtLWdp dCBhL2FyY2gvcmlzY3YvY3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC5wbCBiL2FyY2gvcmlzY3Yv Y3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC5wbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAw MDAwMDAwMDAwMDAuLmMwZWNkZTc3YmY1NgotLS0gL2Rldi9udWxsCisrKyBiL2FyY2gvcmlzY3Yv Y3J5cHRvL2Flcy1yaXNjdjY0LXp2a25lZC5wbApAQCAtMCwwICsxLDQ1MSBAQAorIyEgL3Vzci9i aW4vZW52IHBlcmwKKyMgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAgT1IgQlNE LTItQ2xhdXNlCisjCisjIFRoaXMgZmlsZSBpcyBkdWFsLWxpY2Vuc2VkLCBtZWFuaW5nIHRoYXQg eW91IGNhbiB1c2UgaXQgdW5kZXIgeW91cgorIyBjaG9pY2Ugb2YgZWl0aGVyIG9mIHRoZSBmb2xs b3dpbmcgdHdvIGxpY2Vuc2VzOgorIworIyBDb3B5cmlnaHQgMjAyMyBUaGUgT3BlblNTTCBQcm9q ZWN0IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisjCisjIExpY2Vuc2VkIHVuZGVyIHRo ZSBBcGFjaGUgTGljZW5zZSAyLjAgKHRoZSAiTGljZW5zZSIpLiBZb3UgY2FuIG9idGFpbgorIyBh IGNvcHkgaW4gdGhlIGZpbGUgTElDRU5TRSBpbiB0aGUgc291cmNlIGRpc3RyaWJ1dGlvbiBvciBh dAorIyBodHRwczovL3d3dy5vcGVuc3NsLm9yZy9zb3VyY2UvbGljZW5zZS5odG1sCisjCisjIG9y CisjCisjIENvcHlyaWdodCAoYykgMjAyMywgQ2hyaXN0b3BoIE3DvGxsbmVyIDxjaHJpc3RvcGgu bXVlbGxuZXJAdnJ1bGwuZXU+CisjIENvcHlyaWdodCAoYykgMjAyMywgUGhvZWJlIENoZW4gPHBo b2ViZS5jaGVuQHNpZml2ZS5jb20+CisjIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisjCisjIFJlZGlz dHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0 aG91dAorIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9s bG93aW5nIGNvbmRpdGlvbnMKKyMgYXJlIG1ldDoKKyMgMS4gUmVkaXN0cmlidXRpb25zIG9mIHNv dXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyMgICAgbm90aWNlLCB0 aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorIyAy LiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3Zl IGNvcHlyaWdodAorIyAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUg Zm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisjICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90 aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisjCisjIFRISVMg U09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklC VVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJ TkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBP RiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NF IEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVS IE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJ REVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAo SU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRV VEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBP UiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhF T1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwg T1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElO IEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJ U0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIyAtIFJWNjRJCisjIC0g UklTQy1WIFZlY3RvciAoJ1YnKSB3aXRoIFZMRU4gPj0gMTI4CisjIC0gUklTQy1WIFZlY3RvciBB RVMgYmxvY2sgY2lwaGVyIGV4dGVuc2lvbiAoJ1p2a25lZCcpCisKK3VzZSBzdHJpY3Q7Cit1c2Ug d2FybmluZ3M7CisKK3VzZSBGaW5kQmluIHF3KCRCaW4pOwordXNlIGxpYiAiJEJpbiI7Cit1c2Ug bGliICIkQmluLy4uLy4uL3Blcmxhc20iOwordXNlIHJpc2N2OworCisjICRvdXRwdXQgaXMgdGhl IGxhc3QgYXJndW1lbnQgaWYgaXQgbG9va3MgbGlrZSBhIGZpbGUgKGl0IGhhcyBhbiBleHRlbnNp b24pCisjICRmbGF2b3VyIGlzIHRoZSBmaXJzdCBhcmd1bWVudCBpZiBpdCBkb2Vzbid0IGxvb2sg bGlrZSBhIGZpbGUKK215ICRvdXRwdXQgPSAkI0FSR1YgPj0gMCAmJiAkQVJHVlskI0FSR1ZdID1+ IG18XC5cdyskfCA/IHBvcCA6IHVuZGVmOworbXkgJGZsYXZvdXIgPSAkI0FSR1YgPj0gMCAmJiAk QVJHVlswXSAhfiBtfFwufCA/IHNoaWZ0IDogdW5kZWY7CisKKyRvdXRwdXQgYW5kIG9wZW4gU1RE T1VULCI+JG91dHB1dCI7CisKK215ICRjb2RlPTw8X19fOworLnRleHQKK19fXworCitteSAoJFYw LCAkVjEsICRWMiwgJFYzLCAkVjQsICRWNSwgJFY2LCAkVjcsCisgICAgJFY4LCAkVjksICRWMTAs ICRWMTEsICRWMTIsICRWMTMsICRWMTQsICRWMTUsCisgICAgJFYxNiwgJFYxNywgJFYxOCwgJFYx OSwgJFYyMCwgJFYyMSwgJFYyMiwgJFYyMywKKyAgICAkVjI0LCAkVjI1LCAkVjI2LCAkVjI3LCAk VjI4LCAkVjI5LCAkVjMwLCAkVjMxLAorKSA9IG1hcCgidiRfIiwoMC4uMzEpKTsKKworeworIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMKKyMgdm9pZCBydjY0aV96dmtuZWRfZW5jcnlwdChjb25zdCB1 bnNpZ25lZCBjaGFyICppbiwgdW5zaWduZWQgY2hhciAqb3V0LAorIyAgICAgICAgICAgICAgICAg ICAgICAgICAgIGNvbnN0IEFFU19LRVkgKmtleSk7CitteSAoJElOUCwgJE9VVFAsICRLRVlQKSA9 ICgiYTAiLCAiYTEiLCAiYTIiKTsKK215ICgkVDAsICRUMSwgJFJPVU5EUywgJFQ2KSA9ICgiYTMi LCAiYTQiLCAidDUiLCAidDYiKTsKKworJGNvZGUgLj0gPDxfX187CisucDJhbGlnbiAzCisuZ2xv YmwgcnY2NGlfenZrbmVkX2VuY3J5cHQKKy50eXBlIHJ2NjRpX3p2a25lZF9lbmNyeXB0LFxAZnVu Y3Rpb24KK3J2NjRpX3p2a25lZF9lbmNyeXB0OgorICAgICMgTG9hZCBudW1iZXIgb2Ygcm91bmRz CisgICAgbHd1ICRST1VORFMsIDI0MCgkS0VZUCkKKworICAgICMgR2V0IHByb3BlciByb3V0aW5l IGZvciBrZXkgc2l6ZQorICAgIGxpICRUNiwgMTQKKyAgICBiZXEgJFJPVU5EUywgJFQ2LCBMX2Vu Y18yNTYKKyAgICBsaSAkVDYsIDEwCisgICAgYmVxICRST1VORFMsICRUNiwgTF9lbmNfMTI4Cisg ICAgbGkgJFQ2LCAxMgorICAgIGJlcSAkUk9VTkRTLCAkVDYsIExfZW5jXzE5MgorCisgICAgaiBM X2ZhaWxfbTIKKy5zaXplIHJ2NjRpX3p2a25lZF9lbmNyeXB0LC4tcnY2NGlfenZrbmVkX2VuY3J5 cHQKK19fXworCiskY29kZSAuPSA8PF9fXzsKKy5wMmFsaWduIDMKK0xfZW5jXzEyODoKKyAgICBA e1t2c2V0aXZsaSAiemVybyIsIDQsICJlMzIiLCAibTEiLCAidGEiLCAibWEiXX0KKworICAgIEB7 W3ZsZTMyX3YgJFYxLCAoJElOUCldfQorCisgICAgQHtbdmxlMzJfdiAkVjEwLCAoJEtFWVApXX0K KyAgICBAe1t2YWVzel92cyAkVjEsICRWMTBdfSAgICAjIHdpdGggcm91bmQga2V5IHdbIDAsIDNd CisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjExLCAoJEtFWVAp XX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjExXX0gICAjIHdpdGggcm91bmQga2V5IHdbIDQs IDddCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjEyLCAoJEtF WVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjEyXX0gICAjIHdpdGggcm91bmQga2V5IHdb IDgsMTFdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjEzLCAo JEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjEzXX0gICAjIHdpdGggcm91bmQga2V5 IHdbMTIsMTVdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjE0 LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE0XX0gICAjIHdpdGggcm91bmQg a2V5IHdbMTYsMTldCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAk VjE1LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE1XX0gICAjIHdpdGggcm91 bmQga2V5IHdbMjAsMjNdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJf diAkVjE2LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE2XX0gICAjIHdpdGgg cm91bmQga2V5IHdbMjQsMjddCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxl MzJfdiAkVjE3LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE3XX0gICAjIHdp dGggcm91bmQga2V5IHdbMjgsMzFdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtb dmxlMzJfdiAkVjE4LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE4XX0gICAj IHdpdGggcm91bmQga2V5IHdbMzIsMzVdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAg QHtbdmxlMzJfdiAkVjE5LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE5XX0g ICAjIHdpdGggcm91bmQga2V5IHdbMzYsMzldCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2Cisg ICAgQHtbdmxlMzJfdiAkVjIwLCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZWZfdnMgJFYxLCAkVjIw XX0gICAjIHdpdGggcm91bmQga2V5IHdbNDAsNDNdCisKKyAgICBAe1t2c2UzMl92ICRWMSwgKCRP VVRQKV19CisKKyAgICByZXQKKy5zaXplIExfZW5jXzEyOCwuLUxfZW5jXzEyOAorX19fCisKKyRj b2RlIC49IDw8X19fOworLnAyYWxpZ24gMworTF9lbmNfMTkyOgorICAgIEB7W3ZzZXRpdmxpICJ6 ZXJvIiwgNCwgImUzMiIsICJtMSIsICJ0YSIsICJtYSJdfQorCisgICAgQHtbdmxlMzJfdiAkVjEs ICgkSU5QKV19CisKKyAgICBAe1t2bGUzMl92ICRWMTAsICgkS0VZUCldfQorICAgIEB7W3ZhZXN6 X3ZzICRWMSwgJFYxMF19ICAgICAjIHdpdGggcm91bmQga2V5IHdbIDAsIDNdCisgICAgYWRkaSAk S0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjExLCAoJEtFWVApXX0KKyAgICBAe1t2 YWVzZW1fdnMgJFYxLCAkVjExXX0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgMTYKKyAgICBAe1t2 bGUzMl92ICRWMTIsICgkS0VZUCldfQorICAgIEB7W3ZhZXNlbV92cyAkVjEsICRWMTJdfQorICAg IGFkZGkgJEtFWVAsICRLRVlQLCAxNgorICAgIEB7W3ZsZTMyX3YgJFYxMywgKCRLRVlQKV19Cisg ICAgQHtbdmFlc2VtX3ZzICRWMSwgJFYxM119CisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2Cisg ICAgQHtbdmxlMzJfdiAkVjE0LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE0 XX0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgMTYKKyAgICBAe1t2bGUzMl92ICRWMTUsICgkS0VZ UCldfQorICAgIEB7W3ZhZXNlbV92cyAkVjEsICRWMTVdfQorICAgIGFkZGkgJEtFWVAsICRLRVlQ LCAxNgorICAgIEB7W3ZsZTMyX3YgJFYxNiwgKCRLRVlQKV19CisgICAgQHtbdmFlc2VtX3ZzICRW MSwgJFYxNl19CisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjE3 LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE3XX0KKyAgICBhZGRpICRLRVlQ LCAkS0VZUCwgMTYKKyAgICBAe1t2bGUzMl92ICRWMTgsICgkS0VZUCldfQorICAgIEB7W3ZhZXNl bV92cyAkVjEsICRWMThdfQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAxNgorICAgIEB7W3ZsZTMy X3YgJFYxOSwgKCRLRVlQKV19CisgICAgQHtbdmFlc2VtX3ZzICRWMSwgJFYxOV19CisgICAgYWRk aSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjIwLCAoJEtFWVApXX0KKyAgICBA e1t2YWVzZW1fdnMgJFYxLCAkVjIwXX0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgMTYKKyAgICBA e1t2bGUzMl92ICRWMjEsICgkS0VZUCldfQorICAgIEB7W3ZhZXNlbV92cyAkVjEsICRWMjFdfQor ICAgIGFkZGkgJEtFWVAsICRLRVlQLCAxNgorICAgIEB7W3ZsZTMyX3YgJFYyMiwgKCRLRVlQKV19 CisgICAgQHtbdmFlc2VmX3ZzICRWMSwgJFYyMl19CisKKyAgICBAe1t2c2UzMl92ICRWMSwgKCRP VVRQKV19CisgICAgcmV0Cisuc2l6ZSBMX2VuY18xOTIsLi1MX2VuY18xOTIKK19fXworCiskY29k ZSAuPSA8PF9fXzsKKy5wMmFsaWduIDMKK0xfZW5jXzI1NjoKKyAgICBAe1t2c2V0aXZsaSAiemVy byIsIDQsICJlMzIiLCAibTEiLCAidGEiLCAibWEiXX0KKworICAgIEB7W3ZsZTMyX3YgJFYxLCAo JElOUCldfQorCisgICAgQHtbdmxlMzJfdiAkVjEwLCAoJEtFWVApXX0KKyAgICBAe1t2YWVzel92 cyAkVjEsICRWMTBdfSAgICAgIyB3aXRoIHJvdW5kIGtleSB3WyAwLCAzXQorICAgIGFkZGkgJEtF WVAsICRLRVlQLCAxNgorICAgIEB7W3ZsZTMyX3YgJFYxMSwgKCRLRVlQKV19CisgICAgQHtbdmFl c2VtX3ZzICRWMSwgJFYxMV19CisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxl MzJfdiAkVjEyLCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjEyXX0KKyAgICBh ZGRpICRLRVlQLCAkS0VZUCwgMTYKKyAgICBAe1t2bGUzMl92ICRWMTMsICgkS0VZUCldfQorICAg IEB7W3ZhZXNlbV92cyAkVjEsICRWMTNdfQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAxNgorICAg IEB7W3ZsZTMyX3YgJFYxNCwgKCRLRVlQKV19CisgICAgQHtbdmFlc2VtX3ZzICRWMSwgJFYxNF19 CisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjE1LCAoJEtFWVAp XX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjE1XX0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwg MTYKKyAgICBAe1t2bGUzMl92ICRWMTYsICgkS0VZUCldfQorICAgIEB7W3ZhZXNlbV92cyAkVjEs ICRWMTZdfQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAxNgorICAgIEB7W3ZsZTMyX3YgJFYxNywg KCRLRVlQKV19CisgICAgQHtbdmFlc2VtX3ZzICRWMSwgJFYxN119CisgICAgYWRkaSAkS0VZUCwg JEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjE4LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1f dnMgJFYxLCAkVjE4XX0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgMTYKKyAgICBAe1t2bGUzMl92 ICRWMTksICgkS0VZUCldfQorICAgIEB7W3ZhZXNlbV92cyAkVjEsICRWMTldfQorICAgIGFkZGkg JEtFWVAsICRLRVlQLCAxNgorICAgIEB7W3ZsZTMyX3YgJFYyMCwgKCRLRVlQKV19CisgICAgQHtb dmFlc2VtX3ZzICRWMSwgJFYyMF19CisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtb dmxlMzJfdiAkVjIxLCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZW1fdnMgJFYxLCAkVjIxXX0KKyAg ICBhZGRpICRLRVlQLCAkS0VZUCwgMTYKKyAgICBAe1t2bGUzMl92ICRWMjIsICgkS0VZUCldfQor ICAgIEB7W3ZhZXNlbV92cyAkVjEsICRWMjJdfQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAxNgor ICAgIEB7W3ZsZTMyX3YgJFYyMywgKCRLRVlQKV19CisgICAgQHtbdmFlc2VtX3ZzICRWMSwgJFYy M119CisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIDE2CisgICAgQHtbdmxlMzJfdiAkVjI0LCAoJEtF WVApXX0KKyAgICBAe1t2YWVzZWZfdnMgJFYxLCAkVjI0XX0KKworICAgIEB7W3ZzZTMyX3YgJFYx LCAoJE9VVFApXX0KKyAgICByZXQKKy5zaXplIExfZW5jXzI1NiwuLUxfZW5jXzI1NgorX19fCisK KyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisjIHZvaWQgcnY2NGlfenZrbmVkX2RlY3J5cHQoY29u c3QgdW5zaWduZWQgY2hhciAqaW4sIHVuc2lnbmVkIGNoYXIgKm91dCwKKyMgICAgICAgICAgICAg ICAgICAgICAgICAgICBjb25zdCBBRVNfS0VZICprZXkpOworJGNvZGUgLj0gPDxfX187CisucDJh bGlnbiAzCisuZ2xvYmwgcnY2NGlfenZrbmVkX2RlY3J5cHQKKy50eXBlIHJ2NjRpX3p2a25lZF9k ZWNyeXB0LFxAZnVuY3Rpb24KK3J2NjRpX3p2a25lZF9kZWNyeXB0OgorICAgICMgTG9hZCBudW1i ZXIgb2Ygcm91bmRzCisgICAgbHd1ICRST1VORFMsIDI0MCgkS0VZUCkKKworICAgICMgR2V0IHBy b3BlciByb3V0aW5lIGZvciBrZXkgc2l6ZQorICAgIGxpICRUNiwgMTQKKyAgICBiZXEgJFJPVU5E UywgJFQ2LCBMX2RlY18yNTYKKyAgICBsaSAkVDYsIDEwCisgICAgYmVxICRST1VORFMsICRUNiwg TF9kZWNfMTI4CisgICAgbGkgJFQ2LCAxMgorICAgIGJlcSAkUk9VTkRTLCAkVDYsIExfZGVjXzE5 MgorCisgICAgaiBMX2ZhaWxfbTIKKy5zaXplIHJ2NjRpX3p2a25lZF9kZWNyeXB0LC4tcnY2NGlf enZrbmVkX2RlY3J5cHQKK19fXworCiskY29kZSAuPSA8PF9fXzsKKy5wMmFsaWduIDMKK0xfZGVj XzEyODoKKyAgICBAe1t2c2V0aXZsaSAiemVybyIsIDQsICJlMzIiLCAibTEiLCAidGEiLCAibWEi XX0KKworICAgIEB7W3ZsZTMyX3YgJFYxLCAoJElOUCldfQorCisgICAgYWRkaSAkS0VZUCwgJEtF WVAsIDE2MAorICAgIEB7W3ZsZTMyX3YgJFYyMCwgKCRLRVlQKV19CisgICAgQHtbdmFlc3pfdnMg JFYxLCAkVjIwXX0gICAgIyB3aXRoIHJvdW5kIGtleSB3WzQwLDQzXQorICAgIGFkZGkgJEtFWVAs ICRLRVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMTksICgkS0VZUCldfQorICAgIEB7W3ZhZXNk bV92cyAkVjEsICRWMTldfSAgICMgd2l0aCByb3VuZCBrZXkgd1szNiwzOV0KKyAgICBhZGRpICRL RVlQLCAkS0VZUCwgLTE2CisgICAgQHtbdmxlMzJfdiAkVjE4LCAoJEtFWVApXX0KKyAgICBAe1t2 YWVzZG1fdnMgJFYxLCAkVjE4XX0gICAjIHdpdGggcm91bmQga2V5IHdbMzIsMzVdCisgICAgYWRk aSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3YgJFYxNywgKCRLRVlQKV19CisgICAg QHtbdmFlc2RtX3ZzICRWMSwgJFYxN119ICAgIyB3aXRoIHJvdW5kIGtleSB3WzI4LDMxXQorICAg IGFkZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMTYsICgkS0VZUCldfQor ICAgIEB7W3ZhZXNkbV92cyAkVjEsICRWMTZdfSAgICMgd2l0aCByb3VuZCBrZXkgd1syNCwyN10K KyAgICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2CisgICAgQHtbdmxlMzJfdiAkVjE1LCAoJEtFWVAp XX0KKyAgICBAe1t2YWVzZG1fdnMgJFYxLCAkVjE1XX0gICAjIHdpdGggcm91bmQga2V5IHdbMjAs MjNdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3YgJFYxNCwgKCRL RVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYxNF19ICAgIyB3aXRoIHJvdW5kIGtleSB3 WzE2LDE5XQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMTMs ICgkS0VZUCldfQorICAgIEB7W3ZhZXNkbV92cyAkVjEsICRWMTNdfSAgICMgd2l0aCByb3VuZCBr ZXkgd1sxMiwxNV0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2CisgICAgQHtbdmxlMzJfdiAk VjEyLCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZG1fdnMgJFYxLCAkVjEyXX0gICAjIHdpdGggcm91 bmQga2V5IHdbIDgsMTFdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMy X3YgJFYxMSwgKCRLRVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYxMV19ICAgIyB3aXRo IHJvdW5kIGtleSB3WyA0LCA3XQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2 bGUzMl92ICRWMTAsICgkS0VZUCldfQorICAgIEB7W3ZhZXNkZl92cyAkVjEsICRWMTBdfSAgICMg d2l0aCByb3VuZCBrZXkgd1sgMCwgM10KKworICAgIEB7W3ZzZTMyX3YgJFYxLCAoJE9VVFApXX0K KworICAgIHJldAorLnNpemUgTF9kZWNfMTI4LC4tTF9kZWNfMTI4CitfX18KKworJGNvZGUgLj0g PDxfX187CisucDJhbGlnbiAzCitMX2RlY18xOTI6CisgICAgQHtbdnNldGl2bGkgInplcm8iLCA0 LCAiZTMyIiwgIm0xIiwgInRhIiwgIm1hIl19CisKKyAgICBAe1t2bGUzMl92ICRWMSwgKCRJTlAp XX0KKworICAgIGFkZGkgJEtFWVAsICRLRVlQLCAxOTIKKyAgICBAe1t2bGUzMl92ICRWMjIsICgk S0VZUCldfQorICAgIEB7W3ZhZXN6X3ZzICRWMSwgJFYyMl19ICAgICMgd2l0aCByb3VuZCBrZXkg d1s0OCw1MV0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2CisgICAgQHtbdmxlMzJfdiAkVjIx LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZG1fdnMgJFYxLCAkVjIxXX0gICAjIHdpdGggcm91bmQg a2V5IHdbNDQsNDddCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3Yg JFYyMCwgKCRLRVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYyMF19ICAgICMgd2l0aCBy b3VuZCBrZXkgd1s0MCw0M10KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2CisgICAgQHtbdmxl MzJfdiAkVjE5LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZG1fdnMgJFYxLCAkVjE5XX0gICAjIHdp dGggcm91bmQga2V5IHdbMzYsMzldCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7 W3ZsZTMyX3YgJFYxOCwgKCRLRVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYxOF19ICAg IyB3aXRoIHJvdW5kIGtleSB3WzMyLDM1XQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAg ICBAe1t2bGUzMl92ICRWMTcsICgkS0VZUCldfQorICAgIEB7W3ZhZXNkbV92cyAkVjEsICRWMTdd fSAgICMgd2l0aCByb3VuZCBrZXkgd1syOCwzMV0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2 CisgICAgQHtbdmxlMzJfdiAkVjE2LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZG1fdnMgJFYxLCAk VjE2XX0gICAjIHdpdGggcm91bmQga2V5IHdbMjQsMjddCisgICAgYWRkaSAkS0VZUCwgJEtFWVAs IC0xNgorICAgIEB7W3ZsZTMyX3YgJFYxNSwgKCRLRVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRW MSwgJFYxNV19ICAgIyB3aXRoIHJvdW5kIGtleSB3WzIwLDIzXQorICAgIGFkZGkgJEtFWVAsICRL RVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMTQsICgkS0VZUCldfQorICAgIEB7W3ZhZXNkbV92 cyAkVjEsICRWMTRdfSAgICMgd2l0aCByb3VuZCBrZXkgd1sxNiwxOV0KKyAgICBhZGRpICRLRVlQ LCAkS0VZUCwgLTE2CisgICAgQHtbdmxlMzJfdiAkVjEzLCAoJEtFWVApXX0KKyAgICBAe1t2YWVz ZG1fdnMgJFYxLCAkVjEzXX0gICAjIHdpdGggcm91bmQga2V5IHdbMTIsMTVdCisgICAgYWRkaSAk S0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3YgJFYxMiwgKCRLRVlQKV19CisgICAgQHtb dmFlc2RtX3ZzICRWMSwgJFYxMl19ICAgIyB3aXRoIHJvdW5kIGtleSB3WyA4LDExXQorICAgIGFk ZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMTEsICgkS0VZUCldfQorICAg IEB7W3ZhZXNkbV92cyAkVjEsICRWMTFdfSAgICMgd2l0aCByb3VuZCBrZXkgd1sgNCwgN10KKyAg ICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2CisgICAgQHtbdmxlMzJfdiAkVjEwLCAoJEtFWVApXX0K KyAgICBAe1t2YWVzZGZfdnMgJFYxLCAkVjEwXX0gICAjIHdpdGggcm91bmQga2V5IHdbIDAsIDNd CisKKyAgICBAe1t2c2UzMl92ICRWMSwgKCRPVVRQKV19CisKKyAgICByZXQKKy5zaXplIExfZGVj XzE5MiwuLUxfZGVjXzE5MgorX19fCisKKyRjb2RlIC49IDw8X19fOworLnAyYWxpZ24gMworTF9k ZWNfMjU2OgorICAgIEB7W3ZzZXRpdmxpICJ6ZXJvIiwgNCwgImUzMiIsICJtMSIsICJ0YSIsICJt YSJdfQorCisgICAgQHtbdmxlMzJfdiAkVjEsICgkSU5QKV19CisKKyAgICBhZGRpICRLRVlQLCAk S0VZUCwgMjI0CisgICAgQHtbdmxlMzJfdiAkVjI0LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzel92 cyAkVjEsICRWMjRdfSAgICAjIHdpdGggcm91bmQga2V5IHdbNTYsNTldCisgICAgYWRkaSAkS0VZ UCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3YgJFYyMywgKCRLRVlQKV19CisgICAgQHtbdmFl c2RtX3ZzICRWMSwgJFYyM119ICAgIyB3aXRoIHJvdW5kIGtleSB3WzUyLDU1XQorICAgIGFkZGkg JEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMjIsICgkS0VZUCldfQorICAgIEB7 W3ZhZXNkbV92cyAkVjEsICRWMjJdfSAgICAjIHdpdGggcm91bmQga2V5IHdbNDgsNTFdCisgICAg YWRkaSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3YgJFYyMSwgKCRLRVlQKV19Cisg ICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYyMV19ICAgIyB3aXRoIHJvdW5kIGtleSB3WzQ0LDQ3XQor ICAgIGFkZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMjAsICgkS0VZUCld fQorICAgIEB7W3ZhZXNkbV92cyAkVjEsICRWMjBdfSAgICAjIHdpdGggcm91bmQga2V5IHdbNDAs NDNdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3YgJFYxOSwgKCRL RVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYxOV19ICAgIyB3aXRoIHJvdW5kIGtleSB3 WzM2LDM5XQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2bGUzMl92ICRWMTgs ICgkS0VZUCldfQorICAgIEB7W3ZhZXNkbV92cyAkVjEsICRWMThdfSAgICMgd2l0aCByb3VuZCBr ZXkgd1szMiwzNV0KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2CisgICAgQHtbdmxlMzJfdiAk VjE3LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZG1fdnMgJFYxLCAkVjE3XX0gICAjIHdpdGggcm91 bmQga2V5IHdbMjgsMzFdCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIC0xNgorICAgIEB7W3ZsZTMy X3YgJFYxNiwgKCRLRVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYxNl19ICAgIyB3aXRo IHJvdW5kIGtleSB3WzI0LDI3XQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAtMTYKKyAgICBAe1t2 bGUzMl92ICRWMTUsICgkS0VZUCldfQorICAgIEB7W3ZhZXNkbV92cyAkVjEsICRWMTVdfSAgICMg d2l0aCByb3VuZCBrZXkgd1syMCwyM10KKyAgICBhZGRpICRLRVlQLCAkS0VZUCwgLTE2CisgICAg QHtbdmxlMzJfdiAkVjE0LCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZG1fdnMgJFYxLCAkVjE0XX0g ICAjIHdpdGggcm91bmQga2V5IHdbMTYsMTldCisgICAgYWRkaSAkS0VZUCwgJEtFWVAsIC0xNgor ICAgIEB7W3ZsZTMyX3YgJFYxMywgKCRLRVlQKV19CisgICAgQHtbdmFlc2RtX3ZzICRWMSwgJFYx M119ICAgIyB3aXRoIHJvdW5kIGtleSB3WzEyLDE1XQorICAgIGFkZGkgJEtFWVAsICRLRVlQLCAt MTYKKyAgICBAe1t2bGUzMl92ICRWMTIsICgkS0VZUCldfQorICAgIEB7W3ZhZXNkbV92cyAkVjEs ICRWMTJdfSAgICMgd2l0aCByb3VuZCBrZXkgd1sgOCwxMV0KKyAgICBhZGRpICRLRVlQLCAkS0VZ UCwgLTE2CisgICAgQHtbdmxlMzJfdiAkVjExLCAoJEtFWVApXX0KKyAgICBAe1t2YWVzZG1fdnMg JFYxLCAkVjExXX0gICAjIHdpdGggcm91bmQga2V5IHdbIDQsIDddCisgICAgYWRkaSAkS0VZUCwg JEtFWVAsIC0xNgorICAgIEB7W3ZsZTMyX3YgJFYxMCwgKCRLRVlQKV19CisgICAgQHtbdmFlc2Rm X3ZzICRWMSwgJFYxMF19ICAgIyB3aXRoIHJvdW5kIGtleSB3WyAwLCAzXQorCisgICAgQHtbdnNl MzJfdiAkVjEsICgkT1VUUCldfQorCisgICAgcmV0Cisuc2l6ZSBMX2RlY18yNTYsLi1MX2RlY18y NTYKK19fXworfQorCiskY29kZSAuPSA8PF9fXzsKK0xfZmFpbF9tMToKKyAgICBsaSBhMCwgLTEK KyAgICByZXQKKy5zaXplIExfZmFpbF9tMSwuLUxfZmFpbF9tMQorCitMX2ZhaWxfbTI6CisgICAg bGkgYTAsIC0yCisgICAgcmV0Cisuc2l6ZSBMX2ZhaWxfbTIsLi1MX2ZhaWxfbTIKKworTF9lbmQ6 CisgIHJldAorLnNpemUgTF9lbmQsLi1MX2VuZAorX19fCisKK3ByaW50ICRjb2RlOworCitjbG9z ZSBTVERPVVQgb3IgZGllICJlcnJvciBjbG9zaW5nIFNURE9VVDogJCEiOwotLSAKMi4yOC4wCgoK X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtcmlz Y3YgbWFpbGluZyBsaXN0CmxpbnV4LXJpc2N2QGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xp c3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1yaXNjdgo=