grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v18 00/25] Automatic Disk Unlock with TPM2


From: Gary Lin
Subject: [PATCH v18 00/25] Automatic Disk Unlock with TPM2
Date: Fri, 28 Jun 2024 16:18:43 +0800

GIT repo for v18: https://github.com/lcp/grub2/tree/tpm2-unlock-v18

This patch series is based on "Automatic TPM Disk Unlock"(*1) posted by
Hernan Gatta to introduce the key protector framework and TPM2 stack
to GRUB2, and this could be a useful feature for the systems to
implement full disk encryption.

To support TPM 2.0 Key File format(*2), patch 1~6,8-10 are grabbed from
Daniel Axtens's "appended signature secure boot support" (*3) to import
libtasn1 into grub2. Besides, the libtasn1 version is upgraded to
4.19.0 instead of 4.16.0 in the original patch.

Patch 7 fixes a potential buffer overrun in libtasn1.
(https://gitlab.com/gnutls/libtasn1/-/issues/49)

Patch 11 adds the document for libtasn1 and the steps to upgrade the
library.

Patch 12~18 are based on Hernan Gatta's patches with the follow-up fixes
and improvements:
- Converting 8 spaces into 1 tab
- Merging the minor build fix from Michael Chang
  - Replacing "lu" with "PRIuGRUB_SIZE" for grub_dprintf
  - Adding "enable = efi" to the tpm2 module in grub-core/Makefile.core.def
- Rebasing "cryptodisk: Support key protectors" to the git master
- Removing the measurement on the sealed key
  - Based on the patch from Olaf Kirch <OKir@suse.com>
- Adjusting the input parameters of TPM2_EvictControl to match the order
  in "TCG TPM2 Part3 Commands"
- Declaring the input arguments of TPM2 functions as const
- Resending TPM2 commands on TPM_RC_RETRY
- Adding checks for the parameters of TPM2 commands
- Packing the missing authorization command for TPM2_PCR_Read
- Tweaking the TPM2 command functions to allow some parameters to be
  NULL so that we don't have to declare empty variables
- Using grub_cpu_to_be*() in the TPM2 stack instead of grub_swap_bytes*()
  which may cause problems in big-indian machines
- Changing the short name of "--protector" of "cryptomount" from "-k" to
  "-P" to avoid the conflict with "--key-file"
- Supporting TPM 2.0 Key File Format besides the raw sealed key
- Adding the external libtasn1 dependency to grub-protect to write the
  TPM 2.0 Key files
- Extending the TPM2 TSS stack to support authorized policy

Patch 19 implements the authorized policy support.

Patch 20 implements the missing NV index mode. (Thanks to Patrick Colp)

Patch 21 improves the 'cryptomount' command to fall back to the
passphrase mode when the key protector fails to unlock the encrypted
partition. (Another patch from Patrick Colp)

Patch 22 and 23 fix the potential security issues spotted by Fabian Vogt.

Patch 24 and 25 implement the TPM2 key unsealing testcases.

To utilize the TPM2 key protector to unlock the encrypted partition
(sdb1), here are the sample steps:

1. Add an extra random key for LUKS (luks-key)
   $ dd if=/dev/urandom of=luks-key bs=1 count=32
   $ sudo cryptsetup luksAddKey /dev/sdb1 luks-key --pbkdf=pbkdf2

2. Seal the key
   $ sudo grub-protect --action=add \
                       --protector=tpm2 \
                       --tpm2key \
                       --tpm2-keyfile=luks-key \
                       --tpm2-outfile=/boot/efi/boot/grub2/sealed.tpm

3. Unseal the key with the proper commands in grub.cfg:
   tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
   cryptomount -u <SDB1_UUID> -P tpm2

(*1) https://lists.gnu.org/archive/html/grub-devel/2022-02/msg00006.html
(*2) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
(*3) https://lists.gnu.org/archive/html/grub-devel/2021-06/msg00044.html

v18:
- Updating the steps to import libtasn1
  - Importing test cases from libtasn1 and then applying the follow-up
    patch by autogen.sh
  - The patch files in patch 3~8 are created with the following repo
    against the libtasn1-4.19.0-base-v2 tag:
    https://github.com/lcp/grub2/tree/import-libtasn1-4.19.0-v2
- Splitting the grub compatibility patch for libtasn1
- Moving the TSS2 code to grub-core/lib/tss2 and renaming
  grub_tpm2_mu_*() functions to grub_Tss2_MU_*()
- Splitting the TSS2 patch into 3 patches
- Fixing the types of TPMA_SESSION, TPMA_OBJECT, and TPMA_LOCALITY 
- Renaming the tpm2 module to tpm2_key_protector
- Adding more comments to asn1_read_uint32() and defining the lower and
  upper bounds for tpm2key elements
  - Also fixing a bug that allows 100 elements in the key file
- Fixing the copyright headers
- Fixing the coding style

v17:
- https://lists.gnu.org/archive/html/grub-devel/2024-06/msg00108.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v17
- Fixing the missing space in strncat()
- Updating the steps to import libtasn1
- Moving libtasn1.h to grub-core/lib/libtasn1/ and fixing the affected
  patches
  - libtasn1.h is included in tpm2key.h, so there is no need to include
    the header again in module.c and tpm2key.c. 
- Applying the libtasn1 patches in a different way
  - Instead of applying the patches directly in the grub2 source code,
    libtasn1 is copied to grub-core/lib/libtasn1-grub by autogen.sh and
    then the script applies the libtasn1 patches to libtasn1-grub.
  - The patch files in patch 3, 4, and 5 are created by the following
    repo against the libtasn1-4.19.0-base tag.
    https://github.com/lcp/grub2/tree/import-libtasn1-4.19.0
- Correcting the description of the tpm2_test commit to replace
  swtpm_cuse with "swtpm chardev"

v16:
- https://lists.gnu.org/archive/html/grub-devel/2024-05/msg00093.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v16
- Rebasing patch 6, 12, and 16 to fix the conflicts with the latest
  master branch
- Changes in cryptodisk:
  - Disallowing that both OPTION_KEYFILE and OPTION_PROTECTOR are set
    since the key data for "--key-file" would be overwritten by the key
    protectors
  - Resetting the cargs key data when the key from a key protector
    doesn't work for the disk to ensure the passphrase prompt will be
    triggered later
  - Adding the comment to address why grub_errno is only cleared for
    cargs->key_len == 0

v15:
- https://lists.gnu.org/archive/html/grub-devel/2024-05/msg00059.html 
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v15
- Changes in tpm2_test
  - Quoting the variables which contain file paths
  - Correcting the exit code for several commands
  - Writing the verification text directly into the LUKS device
  - Amending the waiting loop for swtpm
  - Replacing exit with return in tpm2_seal_unseal() and
    tpm2_seal_unseal_nv()
  - Collecting the parameters for the SRK mode testcases in an array
    and invoking tpm2_seal_unseal() with a for loop
  - Moving the tpm2-tools commands for the NV index mode to a separate
    function  
  - Using tpm2_evictcontrol to remove the object from the NV index to
    match the key sealing commands
  - Printing the test results
  - Printing error messages to stderr

v14:
- https://lists.gnu.org/archive/html/grub-devel/2024-05/msg00011.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v14
- Addressing the libtasn1 patches more in the document
- Various improvements in tpm2_test
  - Verifying the test inside the LUKS device
  - Improving the return status checks and the waiting loop for swtpm
  - Fixing the portability issues
  - Making all variables braced
- Renaming grub-emu-opts to --emu-opts (grub-shell)

v13:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00155.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v13
- Fixing typos and a few multi-line comments
- Improving the conditional checks for the arguments of
  tpm2_key_protector_init 
- Updating to the latest TPM 2.0 Key File format
  - Adding the new optional fields: description and rsaParent
  - Handling "rsaParent == TRUE" when unsealing the tpm2key
  - Setting "rsaParent" to "TRUE" when sealing the key with RSA SRK
- Removing non-standard SRKs: RSA3072, RSA4096, ECC_NIST_P384,
  ECC_NIST_P521, and ECC_SM2_P256
- Adding more error messages to grub-protect
- Improving the error checking for the swtpm chardev instance
- Exiting the tpm2_test script if grub-protect failed to seal the key   

v12:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00108.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v12
- Fixing typos and indentation
- Removing the unused TPM commands: TPM2_HashSequenceStart,
  TPM2_SequenceUpdate, and TPM2_SequenceComplete,
- Following the TCG EK templates to set the parameters of SRK
- Removing ECC_BN_P256 and ECC_BN_P638 from the SRK algorithm list since
  those two algorithms are not mentioned in the TCG EK templates
- Updating the help messages of the tpm2 module and grub-protect
- Removing the unnecessary NULL checks
- Adding the manpage for grub-protect
- Replacing grub_crypto_hash() with TPM2_Hash() in grub-protect to
  support SHA384 PCR banks
- Using 'swtpm chardev' to start swtpm instead of 'swtpm_cuse' since
  some distros may not build swtpm with cuse
- Adding a new testcase without specifying the SRK type to test the
  default SRK settings
- Amending tpm2_test to remove the duplicate error checking code
- Silencing the tpm2-tools commands in tpm2_test
- Fixing the exit trap of tpm2_test to removing the working directory
  on success

v11:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00052.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v11
- Adding the missing default: handlers in grub-core/tpm2/mu.c
- Updating the help messages and commit messages to reflect the change
  of the default SRK algorithm (RSA2048 -> ECC_NIST_P256)
- Adding the testcase for the NV index mode

v10:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00019.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v10
- Fixing the coverity issues: CID 435775, CID 435771, CID 435770, CID
  435769, CID 435767, CID 435761
  https://lists.gnu.org/archive/html/grub-devel/2024-02/txtKIuUb5lf3O.txt
  - Fixing the potential memory leak (CID 435775)
  - Removing the unnecessary grub_protect_get_grub_drive_for_file() from
    util/grub-protect.c (CID 435771)
  - Using the grub_tpm2_mu_TPM2B_*_Unmarshal functions to unmarshal the
    TPM2B structs instead of a generic grub_tpm2_mu_TPM2B_Unmarshal
    (CID 435770)
  - Fixing Null pointer dereference (CID 435769)
  - Adding bound checks to grub_tpm2_mu_TPML_DIGEST_Unmarshal()
    (CID 435767)
  - Improving the check for the return value of ftell() (CID 435761)
- Adding a quick fix for CID 435762
- Removing the empty ending line in tests/asn1_test.in
- Fixing docs/grub-dev.texi and updating the libtasn1 patches in
  grub-core/lib/libtasn1-patches/
- Merging all the TPM2 TSS stack patches into one to reduce the total
  patch number
- Switching the default asymmetric algorithm from RSA2048 to
  TPM_ECC_NIST_P256 for the faster key generation
- Adding the fallback SRK templates to try a few more SRK types in case
  grub2 failed to associate the sealed key with the SRK in the persistent
  handle or the default SRK
- Improving the test script to add tests for the persistent handle and
  the fallback SRKs

v9:
- https://lists.gnu.org/archive/html/grub-devel/2024-02/msg00007.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v9
- Introducing c-ctype.h to posix_wrap and implementing strncat
- Adding the descriptive comments to the disabled code in libtasn1
- Replacing strcat with the bound-checked _asn1_str_cat in libtasn1 and
  including c-ctype.h directly
- Integrating the asn1 testcases into "functional_test"
- Updating the libtasn1 patches mentioned in the documentation 
- Moving the key protector to a module
- Amending configure.ac to enable/disable grub-protect
- Fixing an timeout issue in the tpm2_test script by feeding the config
  through stdin

v8:
- https://lists.gnu.org/archive/html/grub-devel/2024-01/msg00013.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v8
- Introducing TPM device support to grub-emu and adding the TPM key
  unsealing testcase

v7:
- https://lists.gnu.org/archive/html/grub-devel/2023-11/msg00127.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v7
- Stopping reading SRK from the well-known persistent handle (TPM2_SRK_HANDLE,
  i.e. 0x81000001) by default since the persistent handle may be created
  by other OS and causes unsealing failure due to SRK mismatching
  - The user now has to specify the persistent handle with "--srk"
    explicitly.
- Utilizing grub_error() to print more error messages 
- Unifying the format of the error messages from TPM2 commands

v6:
- https://lists.gnu.org/archive/html/grub-devel/2023-10/msg00026.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v6
- Supporting more SRK types than RSA2048 and ECC_NIST_P256
- Documenting SHA512 as the supported PCR bank type in the tpm2
  protector
- Removing the redundant error message for grub_tpm2_protector_srk_get()
  since it may overwrite the real error message.
- Updating the supported SRK types and PCR bank types in grub-protect 
- Removing the unused type: TPM2_ECC_CURVE

v5:
- https://lists.gnu.org/archive/html/grub-devel/2023-08/msg00113.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v5
- Rebasing to the latest git HEAD and improving the commit messages
- Implementing authorized poilcy support
- Implementing NV index mode
- Improving the 'cryptomount' command to fall back to the passphrase
  mode when the key protector fails to unlock the encrypted partition
- Fixing the potential security issues

v4:
- https://lists.gnu.org/archive/html/grub-devel/2023-04/msg00104.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v4
- Improving the error condition checks in cryptodisk.c
- Moving the code to unseal with the standalone policy sequence below
  the code for authpolicy sequence
  - The standalone policy sequence was mistakenly prepended to to the
    authpolicy sequence with grub_list_push() while it should be
    appended.
- Pushing the error messages from the authpolicy sequence into the
  grub_error stack so that we can list all errors from the sequence
- Improving the error messages in the TPM2 protector
- Amending the calculation of the max string lengths of 'Policy',
  'CommandCode' and 'CommandPolicy'
- Skipping the error path in grub_tpm2key_get_authpolicy_seq() on
  success to avoid freeing the authpolicy sequence

v3:
- https://lists.gnu.org/archive/html/grub-devel/2023-04/msg00055.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v3
- Adding the document for libtasn1
- Improving the error condition checks
  ex: "if (!ptr)" ==> "if (ptr == NULL)"
      "if (err)" ==> "if (err != GRUB_ERR_NONE)"
      "if (rc)" ==> "if (rc != TPM_RC_SUCCESS)"
- Supporting the "TPMPolicy" and "TPMAuthPolicy" sequence in the TPM 2.0
  key File
- Refactoring the key recover function to support "TPMPolicy" and
  "TPMAuthPolicy" sequence
- Using TPMS_PCR_SELECTION_SelectPCR() to set the PCR bit mask
  - Also dropping TPM2_PCR_TO_SELECT() and TPM2_PCR_TO_BIT() which are
    not necessary anymore
- Removing the redundant variable, 'crd', from
  grub_cryptodisk_scan_device_real()
- Fixing the spaces/tabs in cryptodisk.c
- Fixing the comment format in cryptodisk.h
- Adding the defensive check for "cargs->protectors" in
  grub_cryptodisk_scan_device()
- Improving 'grub-protect' for the better support of TPM 2.0 Key File
- Adding more comments

v2:
- https://lists.gnu.org/archive/html/grub-devel/2023-03/msg00094.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v2

v1:
- https://lists.gnu.org/archive/html/grub-devel/2023-02/msg00130.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock

*********************************************
* Anaylses for Coverity issuses on libtasn1 *
*********************************************

2 Memory corruptions: CID 435762, CID 435766

________________________________________________________________________________________________________
*** CID 435762:  Memory - corruptions  (OVERRUN)
/grub-core/lib/libtasn1/lib/coding.c: 152 in _asn1_tag_der()
146               if (k > ASN1_MAX_TAG_SIZE - 1)
147                 break;              /* will not encode larger tags */
148             }
149           *ans_len = k + 1;
150           while (k--)
151             ans[*ans_len - 1 - k] = temp[k] + 128;
>>>     CID 435762:  Memory - corruptions  (OVERRUN)
>>>     Overrunning array of 4 bytes at byte offset 4 by dereferencing pointer 
>>> "ans + (*ans_len - 1)".
152           ans[*ans_len - 1] -= 128;
153         }
154     }
155     
156     /**
157      * asn1_octet_der:

Reported to upstream: https://gitlab.com/gnutls/libtasn1/-/issues/49
A quick fix is also provided in patch 7.

________________________________________________________________________________________________________
*** CID 435766:  Memory - corruptions  (OVERRUN)
/grub-core/lib/libtasn1/lib/decoding.c: 1204 in asn1_der_decoding2()
1198                    }
1199     
1200                  DECR_LEN (ider_len, len2);
1201     
1202                  tlen = strlen (temp);
1203                  if (tlen > 0)
>>>     CID 435766:  Memory - corruptions  (OVERRUN)
>>>     Allocating insufficient memory for the terminating null of the string.
1204                    _asn1_set_value (p, temp, tlen);
1205     
1206                  counter += len2;
1207                  move = RIGHT;
1208                  break;
1209                case ASN1_ETYPE_OCTET_STRING:

It's likely to be false positive. See the upstream report:
https://gitlab.com/gnutls/libtasn1/-/issues/50

==
7 Integer handling issues:
CID 435774, CID 435773, CID 435772, CID 435768, CID 435765, CID 435764, CID 
435763    

Those are related to Gnulib macros and false positive.
Here are the analyses:

________________________________________________________________________________________________________
*** CID 435774:  Integer handling issues  (CONSTANT_EXPRESSION_RESULT)
/grub-core/lib/libtasn1/lib/decoding.c: 481 in asn1_get_object_id_der()
475            */
476           if (leading != 0 && der[len_len + k] == 0x80)
477             return ASN1_DER_ERROR;
478           leading = 0;
479     
480           /* check for wrap around */
>>>     CID 435774:  Integer handling issues  (CONSTANT_EXPRESSION_RESULT)
>>>     "val < ((((1 ? 0 : val) - 1 < 0) ? ~((((1 ? 0 : val) + 1 << 62UL /* 
>>> sizeof (+val) * 8 - 2 */) - 1) * 2 + 1) : ((1 ? 0 : val) + 0)) >> 7)" is 
>>> always false regardless of the values of its operands. This occurs as the 
>>> second operand of "?:".
481           if (INT_LEFT_SHIFT_OVERFLOW (val, 7))
482             return ASN1_DER_ERROR;
483     
484           val = val << 7;
485           val |= der[len_len + k] & 0x7F;
486     

/grub-core/lib/libtasn1/lib/decoding.c: 481 in asn1_get_object_id_der()

Here are the related macros:

#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))

#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))

#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)

#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))

#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))

#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max)   \
  ((a) < 0                                              \
   ? (a) < (min) >> (b)                                 \
   : (max) >> (b) < (a))

#define INT_LEFT_SHIFT_OVERFLOW(a, b) \
  INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \
                                 _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))

The statement in question is expanded "(a) < (min) >> (b)" of 
INT_LEFT_SHIFT_RANGE_OVERFLOW.

'(a) < (min) >> (b)'
=> '(val) < _GL_INT_MINIMUM (val) >> (7)'
=> '(val) < \
     (EXPR_SIGNED (val) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (val) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((_GL_INT_NEGATE_CONVERT (val, 1) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (val) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (val) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((_GL_INT_CONVERT (val, 1) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * 2 + 
1) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((((1 ? 0 : (val)) + (1)) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * 2 + 
1) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (val) * CHAR_BIT) - 2)) - 1) * 
2 + 1) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (val) * CHAR_BIT) - 2)) - 1) * 
2 + 1) \
      : ((1 ? 0 : (val)) + (0))) \
     >> (7)'

'_GL_INT_MINIMUM' returns the minimum value of the given type. Since 'val' is
'uint64_t', '_GL_INT_MINIMUM (val)' is 0, thus '(val) < 0 >> (7)' is always 
false.
Besides, '(val) < 0' is false, so "(max) >> (b) < (a))" becomes the only valid
statement to check if 'a' overflows after left shift.

________________________________________________________________________________________________________
*** CID 435773:  Integer handling issues  (NO_EFFECT)
/grub-core/lib/libtasn1/lib/decoding.c: 439 in asn1_get_object_id_der()
433         return ASN1_DER_ERROR;
434     
435       val0 = 0;
436     
437       for (k = 0; k < len; k++)
438         {
>>>     CID 435773:  Integer handling issues  (NO_EFFECT)
>>>     This less-than-zero comparison of an unsigned value is never true. "(1 
>>> ? 0UL : val0) - 1UL < 0UL".
439           if (INT_LEFT_SHIFT_OVERFLOW (val0, 7))
440             return ASN1_DER_ERROR;
441     
442           val0 <<= 7;
443           val0 |= der[len_len + k] & 0x7F;
444           if (!(der[len_len + k] & 0x80))

Here are the related macros:

#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))

#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))

#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)

#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))

#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))

#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max)   \
  ((a) < 0                                              \
   ? (a) < (min) >> (b)                                 \
   : (max) >> (b) < (a))

#define INT_LEFT_SHIFT_OVERFLOW(a, b) \
  INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \
                                 _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))

The statement in question is the expanded 'EXPR_SIGNED (val0)' from either
'_GL_INT_MAXIMUM' or '_GL_INT_MINIMUM'

'EXPR_SIGNED (val0)'
=> '(_GL_INT_NEGATE_CONVERT (val0, 1) < 0)'
=> '(((1 ? 0 : (val0)) - (1)) < 0)'

Since 'EXPR_SIGNED' is to test if the given expression is signed or not. For
'uint64_t val0', it's expected to be false, and '_GL_INT_MINIMUM' returns the
minimum value of 'uint64_t' while '_GL_INT_MAXIMUM' returns the maximum
value of 'uint64_t'. 

________________________________________________________________________________________________________
*** CID 435772:  Integer handling issues  (NO_EFFECT)
/grub-core/lib/libtasn1/lib/decoding.c: 204 in asn1_get_tag_der()
198           /* Long form */
199           punt = 1;
200           ris = 0;
201           while (punt < der_len && der[punt] & 128)
202             {
203     
>>>     CID 435772:  Integer handling issues  (NO_EFFECT)
>>>     This less-than-zero comparison of an unsigned value is never true. "(1 
>>> ? 0U : ((1 ? 0U : ris) + 128U)) - 1U < 0U".
204               if (INT_MULTIPLY_OVERFLOW (ris, 128))
205                 return ASN1_DER_ERROR;
206               ris *= 128;
207     
208               if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
209                 return ASN1_DER_ERROR;

Here are the related macros:

#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))

#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))

#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)

#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))

#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))

#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \
  ((b) < 0                                              \
   ? ((a) < 0                                           \
      ? (a) < (max) / (b)                               \
      : (b) == -1                                       \
      ? 0                                               \
      : (min) / (b) < (a))                              \
   : (b) == 0                                           \
   ? 0                                                  \
   : ((a) < 0                                           \
      ? (a) < (min) / (b)                               \
      : (max) / (b) < (a)))

# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                           \
   (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a))))       \
    || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))

#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \
  op_result_overflow (a, b,                                     \
                      _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
                      _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))

#define INT_MULTIPLY_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)

The statement in question is the expanded 'EXPR_SIGNED (_GL_INT_CONVERT (ris, 
128))'
from either '_GL_INT_MINIMUM' or '_GL_INT_MAXIMUM'.

'EXPR_SIGNED (_GL_INT_CONVERT (ris, 128))'
=> 'EXPR_SIGNED ((1 ? 0 : (ris)) + (128))'
=> '(_GL_INT_NEGATE_CONVERT (((1 ? 0 : (ris)) + (128), 1) < 0))'
=> '((1 ? 0 : ((1 ? 0 : ris) + 128)) - 1 < 0)'

Since 'ris' is 'unsigned int', the compiler treats 128 as 'unsigned int' too.
'EXPR_SIGNED' is designed to check if the given expression is signed or not.
Thus, the result is expected to be false and '_GL_INT_MINIMUM' returns the
minimum value of 'unsigned int' while '_GL_INT_MAXIMUM' returns the maximum
value of 'unsigned int'.

________________________________________________________________________________________________________
*** CID 435768:    (CONSTANT_EXPRESSION_RESULT)
/grub-core/lib/libtasn1/lib/decoding.c: 204 in asn1_get_tag_der()
198           /* Long form */
199           punt = 1;
200           ris = 0;
201           while (punt < der_len && der[punt] & 128)
202             {
203     
>>>     CID 435768:    (CONSTANT_EXPRESSION_RESULT)
>>>     "ris < (((1 ? 0 : ((1 ? 0 : ris) + 128)) - 1 < 0) ? ~((((1 ? 0 : ((1 ? 
>>> 0 : ris) + 128)) + 1 << 30UL /* sizeof (+((1 ? 0 : ris) + 128)) * 8 - 2 */) 
>>> - 1) * 2 + 1) : ((1 ? 0 : ((1 ? 0 : ris) + 128)) + 0)) / 128" is always 
>>> false regardless of the values of its operands. This occurs as the second 
>>> operand of "?:".
204               if (INT_MULTIPLY_OVERFLOW (ris, 128))
205                 return ASN1_DER_ERROR;
206               ris *= 128;
207     
208               if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
209                 return ASN1_DER_ERROR;
/grub-core/lib/libtasn1/lib/decoding.c: 217 in asn1_get_tag_der()
211               punt++;
212             }
213     
214           if (punt >= der_len)
215             return ASN1_DER_ERROR;
216     
>>>     CID 435768:    (CONSTANT_EXPRESSION_RESULT)
>>>     "ris < (((1 ? 0 : ((1 ? 0 : ris) + 128)) - 1 < 0) ? ~((((1 ? 0 : ((1 ? 
>>> 0 : ris) + 128)) + 1 << 30UL /* sizeof (+((1 ? 0 : ris) + 128)) * 8 - 2 */) 
>>> - 1) * 2 + 1) : ((1 ? 0 : ((1 ? 0 : ris) + 128)) + 0)) / 128" is always 
>>> false regardless of the values of its operands. This occurs as the second 
>>> operand of "?:".
217           if (INT_MULTIPLY_OVERFLOW (ris, 128))
218             return ASN1_DER_ERROR;
219           ris *= 128;
220     
221           if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
222             return ASN1_DER_ERROR;

Here are the related macros:

#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))

#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))

#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)

#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))

#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))

#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \
  ((b) < 0                                              \
   ? ((a) < 0                                           \
      ? (a) < (max) / (b)                               \
      : (b) == -1                                       \
      ? 0                                               \
      : (min) / (b) < (a))                              \
   : (b) == 0                                           \
   ? 0                                                  \
   : ((a) < 0                                           \
      ? (a) < (min) / (b)                               \
      : (max) / (b) < (a)))

# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                           \
   (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a))))       \
    || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))

#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \
  op_result_overflow (a, b,                                     \
                      _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
                      _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))

#define INT_MULTIPLY_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)

The statement in question is expanded from '(a) < (min) / (b)' in
INT_MULTIPLY_RANGE_OVERFLOW.

'(a) < (min) / (b)'
=> '(a) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (a, b))) / (b)'
=> '(ris) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (ris, 128))) / (128)'
=> '(ris) < \
     (EXPR_SIGNED (_GL_INT_CONVERT (ris, 128)) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((_GL_INT_NEGATE_CONVERT (_GL_INT_CONVERT (ris, 128), 1) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : (_GL_INT_CONVERT (ris, 128))) - (1)) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((_GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 1) << (TYPE_WIDTH (+ 
(_GL_INT_CONVERT (ris, 128))) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((((1 ? 0 : (_GL_INT_CONVERT (ris, 128))) + (1)) << (TYPE_WIDTH (+ 
(_GL_INT_CONVERT (ris, 128))) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << (TYPE_WIDTH (+ 
(_GL_INT_CONVERT (ris, 128))) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ 
(_GL_INT_CONVERT (ris, 128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 ? 0 
: (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 ? 0 
: (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 ? 0 
: (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : ((1 ? 0 : (_GL_INT_CONVERT (ris, 128)) + (0)) \
     / (128)'
=> '(ris) < \
     ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \
      ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 ? 0 
: (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : ((1 ? 0 : ((1 ? 0 : (ris)) + (128)) + (0)) \
     / (128)'

Since 'ris' is 'unsigned int', and the compiler also treats '128' as 'unsigned 
int',
thus '_GL_INT_CONVERT (ris, 128)' is '128U' and '_GL_INT_MINIMUM (128U)' is 0. 
So,
'(ris) < 0 / (128)' is expected to be false. Besides, '(ris) < 0' is false, so 
the
result of '(a) < (min) / (b)' is always skipped, and '(max) / (b) < (a)' becomes
the only valid statement to check if 'ris' overflows after multiplying the 128.

________________________________________________________________________________________________________
*** CID 435765:  Integer handling issues  (CONSTANT_EXPRESSION_RESULT)
/grub-core/lib/libtasn1/lib/decoding.c: 439 in asn1_get_object_id_der()
433         return ASN1_DER_ERROR;
434     
435       val0 = 0;
436     
437       for (k = 0; k < len; k++)
438         {
>>>     CID 435765:  Integer handling issues  (CONSTANT_EXPRESSION_RESULT)
>>>     "val0 < ((((1 ? 0 : val0) - 1 < 0) ? ~((((1 ? 0 : val0) + 1 << 62UL /* 
>>> sizeof (+val0) * 8 - 2 */) - 1) * 2 + 1) : ((1 ? 0 : val0) + 0)) >> 7)" is 
>>> always false regardless of the values of its operands. This occurs as the 
>>> second operand of "?:".
439           if (INT_LEFT_SHIFT_OVERFLOW (val0, 7))
440             return ASN1_DER_ERROR;
441     
442           val0 <<= 7;
443           val0 |= der[len_len + k] & 0x7F;
444           if (!(der[len_len + k] & 0x80))

Here are the related macros:

#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))

#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))

#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)

#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))

#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))

#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max)   \
  ((a) < 0                                              \
   ? (a) < (min) >> (b)                                 \
   : (max) >> (b) < (a))

#define INT_LEFT_SHIFT_OVERFLOW(a, b) \
  INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \
                                 _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))

The statement in question is expanded '(a) < (min) >> (b)' from
INT_LEFT_SHIFT_RANGE_OVERFLOW.

'(a) < (min) >> (b)'
=> '(val) < (_GL_INT_MINIMUM (val)) >> (7)'
=> '(val) < \
     (EXPR_SIGNED (val) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (val) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((_GL_INT_NEGATE_CONVERT (val, 1) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (val) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (val) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((_GL_INT_CONVERT (val, 1) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * 2 + 
1) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((((1 ? 0 : (val)) + (1)) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * 2 + 
1) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (+ (val)) * CHAR_BIT) - 2)) - 
1) * 2 + 1) \
      : _GL_INT_CONVERT (val, 0)) \
     >> (7)'
=> '(val) < \
     ((((1 ? 0 : (val)) - (1)) < 0) \
      ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (+ (val)) * CHAR_BIT) - 2)) - 
1) * 2 + 1) \
      : ((1 ? 0 : (val)) + (0))) \
     >> (7)'

'_GL_INT_MINIMUM' returns the minimum value of the given type. Since 'val' is
'uint64_t', '_GL_INT_MINIMUM (val)' is 0, thus '(val) < 0 >> (7)' is expected to
be false. Besides, '(val) < 0' is false, so "(max) >> (b) < (a))" becomes the
only valid statement to check if 'a' overflows after left shift.

________________________________________________________________________________________________________
*** CID 435764:  Integer handling issues  (NO_EFFECT)
/grub-core/lib/libtasn1/lib/decoding.c: 137 in asn1_get_length_der()
131           punt = 1;
132           if (k)
133             {                       /* definite length method */
134               ans = 0;
135               while (punt <= k && punt < der_len)
136                 {
>>>     CID 435764:  Integer handling issues  (NO_EFFECT)
>>>     This less-than-zero comparison of an unsigned value is never true. "(1 
>>> ? 0U : ((1 ? 0U : ans) + 256U)) - 1U < 0U".
137                   if (INT_MULTIPLY_OVERFLOW (ans, 256))
138                     return -2;
139                   ans *= 256;
140     
141                   if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
142                     return -2;

Here are the related macros:

#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))

#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))

#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)

#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))

#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))

#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \
  ((b) < 0                                              \
   ? ((a) < 0                                           \
      ? (a) < (max) / (b)                               \
      : (b) == -1                                       \
      ? 0                                               \
      : (min) / (b) < (a))                              \
   : (b) == 0                                           \
   ? 0                                                  \
   : ((a) < 0                                           \
      ? (a) < (min) / (b)                               \
      : (max) / (b) < (a)))

# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                           \
   (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a))))       \
    || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))

#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \
  op_result_overflow (a, b,                                     \
                      _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
                      _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))

#define INT_MULTIPLY_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)

The statement in question is expanded 'EXPR_SIGNED (_GL_INT_CONVERT (ans, 256))'
from either '_GL_INT_MINIMUM' or '_GL_INT_MAXIMUM'.

'EXPR_SIGNED (_GL_INT_CONVERT (ans, 256))'
=> 'EXPR_SIGNED ((1 ? 0 : (ans)) + (256))'
=> '(_GL_INT_NEGATE_CONVERT (((1 ? 0 : (ans)) + (256)), 1) < 0)'
=> '((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1))'

Since 'ans' is 'unsigned int', the compiler treats '256' as 'unsigned int',
thus '_GL_INT_CONVERT (ans, 256)' is '256U'. 'EXPR_SIGNED' is designed to
check if the given expression is signed, so 'EXPR_SIGNED (256U)' is expected
to be false and '_GL_INT_MINIMUM' returns the minimum value of 'unsigned int'
while '_GL_INT_MAXIMUM' returns the maximum of 'unsigned int'.

________________________________________________________________________________________________________
*** CID 435763:  Integer handling issues  (CONSTANT_EXPRESSION_RESULT)
/grub-core/lib/libtasn1/lib/decoding.c: 137 in asn1_get_length_der()
131           punt = 1;
132           if (k)
133             {                       /* definite length method */
134               ans = 0;
135               while (punt <= k && punt < der_len)
136                 {
>>>     CID 435763:  Integer handling issues  (CONSTANT_EXPRESSION_RESULT)
>>>     "ans < (((1 ? 0 : ((1 ? 0 : ans) + 256)) - 1 < 0) ? ~((((1 ? 0 : ((1 ? 
>>> 0 : ans) + 256)) + 1 << 30UL /* sizeof (+((1 ? 0 : ans) + 256)) * 8 - 2 */) 
>>> - 1) * 2 + 1) : ((1 ? 0 : ((1 ? 0 : ans) + 256)) + 0)) / 256" is always 
>>> false regardless of the values of its operands. This occurs as the second 
>>> operand of "?:".
137                   if (INT_MULTIPLY_OVERFLOW (ans, 256))
138                     return -2;
139                   ans *= 256;
140     
141                   if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
142                     return -2;

Here are the related macros:

#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))

#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))

#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)

#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)

#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)

#define _GL_INT_MINIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
   : _GL_INT_CONVERT (e, 0))

#define _GL_INT_MAXIMUM(e)                                              \
  (EXPR_SIGNED (e)                                                      \
   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
   : _GL_INT_NEGATE_CONVERT (e, 1))

#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \
  ((b) < 0                                              \
   ? ((a) < 0                                           \
      ? (a) < (max) / (b)                               \
      : (b) == -1                                       \
      ? 0                                               \
      : (min) / (b) < (a))                              \
   : (b) == 0                                           \
   ? 0                                                  \
   : ((a) < 0                                           \
      ? (a) < (min) / (b)                               \
      : (max) / (b) < (a)))

# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                           \
   (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a))))       \
    || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))

#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \
  op_result_overflow (a, b,                                     \
                      _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
                      _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))

#define INT_MULTIPLY_OVERFLOW(a, b) \
  _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)

The statement in question is expanded '(a) < (min) / (b)' from
INT_MULTIPLY_RANGE_OVERFLOW.

'(a) < (min) / (b)'
=> '(a) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (a, b))) / (b)'
=> '(ans) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (ans, 256))) / (256)'
=> '(ans) < \
     (EXPR_SIGNED (_GL_INT_CONVERT (ans, 256)) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ans, 256)) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (_GL_INT_NEGATE_CONVERT (_GL_INT_CONVERT (ans, 256), 1) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ans, 256)) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : (_GL_INT_CONVERT (ans, 256))) - (1)) < 0) \
      ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ans, 256)) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \
      ? ~ (((_GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 1) << (TYPE_WIDTH (+ 
(_GL_INT_CONVERT (ans, 256))) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \
      ? ~ ((((1 ? 0 : (_GL_INT_CONVERT (ans, 256))) + (1)) << (TYPE_WIDTH (+ 
(_GL_INT_CONVERT (ans, 256))) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \
      ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << (TYPE_WIDTH (+ 
(_GL_INT_CONVERT (ans, 256))) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \
      ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ 
(_GL_INT_CONVERT (ans, 256))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \
      ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ ((1 ? 0 
: (ans)) + (1))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \
      ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ ((1 ? 0 
: (ans)) + (1))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : ((1 ? 0 : (_GL_INT_CONVERT (ans, 256))) + (0)) ) \
     / (256)'
=> '(ans) < \
     (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \
      ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ ((1 ? 0 
: (ans)) + (1))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \
      : ((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (0)) ) \
     / (256)'

Since 'ans' is 'unsigned int', the compiler treats '256' as 'unsigned int',
thus '_GL_INT_CONVERT (ans, 256)' is '256U'. Then, '_GL_INT_MINIMUM (256U)'
returns 0, so '(ans) < 0 / (256)' is expected to be false. Besides,
'(ans) < 0' is false, so '(a) < (min) / (b)' is always skipped, and
'(max) / (b) < (a)' becomes the only valid statement to check if 'ans'
overflows after multiplying 256.

Daniel Axtens (4):
  posix_wrap: tweaks in preparation for libtasn1
  libtasn1: import libtasn1-4.19.0
  libtasn1: compile into asn1 module
  asn1_test: test module for libtasn1

Gary Lin (15):
  libtasn1: disable code not needed in grub
  libtasn1: use bound-checked _asn1_str_cat()
  libtasn1: adjust the header paths in libtasn1.h
  libtasn1: Use grub_divmod64() for division
  libtasn1: fix the potential buffer overrun
  asn1_test: changes for grub compatibility
  libtasn1: Add the documentation
  tss2: Add TPM2 buffer handling functions
  tss2: Add TPM2 types and Marshal/Unmarshal functions
  tss2: Add TPM2 Software Stack (TSS2) support
  tpm2_key_protector: Support authorized policy
  cryptodisk: wipe out the cached keys from protectors
  diskfilter: look up cryptodisk devices first
  tpm2_key_protector: Add grub-emu support
  tests: Add tpm2_key_protector_test

Hernan Gatta (4):
  key_protector: Add key protectors framework
  key_protector: Add TPM2 Key Protector
  cryptodisk: Support key protectors
  util/grub-protect: Add new tool

Patrick Colp (2):
  tpm2_key_protector: Implement NV index
  cryptodisk: Fallback to passphrase

 .gitignore                                    |    2 +
 Makefile.util.def                             |   39 +
 autogen.sh                                    |   26 +
 configure.ac                                  |   30 +
 docs/grub-dev.texi                            |   35 +
 docs/man/grub-protect.h2m                     |    4 +
 grub-core/Makefile.am                         |    1 +
 grub-core/Makefile.core.def                   |   60 +
 grub-core/commands/tpm2_key_protector/args.c  |  130 +
 .../commands/tpm2_key_protector/module.c      | 1253 +++++++++
 grub-core/commands/tpm2_key_protector/tpm2.h  |   36 +
 .../commands/tpm2_key_protector/tpm2_args.h   |   51 +
 .../commands/tpm2_key_protector/tpm2key.asn   |   49 +
 .../commands/tpm2_key_protector/tpm2key.c     |  499 ++++
 .../commands/tpm2_key_protector/tpm2key.h     |   87 +
 .../tpm2_key_protector/tpm2key_asn1_tab.c     |   63 +
 grub-core/disk/cryptodisk.c                   |  262 +-
 grub-core/disk/diskfilter.c                   |   35 +-
 grub-core/disk/key_protector.c                |   79 +
 grub-core/kern/emu/main.c                     |   11 +-
 grub-core/kern/emu/misc.c                     |   51 +
 grub-core/lib/efi/tcg2.c                      |  144 +
 ...asn1-disable-code-not-needed-in-grub.patch |  319 +++
 ...asn1-use-bound-checked-_asn1_str_cat.patch |   85 +
 ...djust-the-header-paths-in-libtasn1.h.patch |   32 +
 ...tasn1-Use-grub_divmod64-for-division.patch |   30 +
 ...sn1-fix-the-potential-buffer-overrun.patch |   35 +
 ..._test-changes-for-grub-compatibility.patch |  844 ++++++
 grub-core/lib/libtasn1/COPYING                |   16 +
 grub-core/lib/libtasn1/README.md              |   98 +
 grub-core/lib/libtasn1/lib/coding.c           | 1425 ++++++++++
 grub-core/lib/libtasn1/lib/decoding.c         | 2501 +++++++++++++++++
 grub-core/lib/libtasn1/lib/element.c          | 1109 ++++++++
 grub-core/lib/libtasn1/lib/element.h          |   42 +
 grub-core/lib/libtasn1/lib/errors.c           |  100 +
 grub-core/lib/libtasn1/lib/gstr.c             |   74 +
 grub-core/lib/libtasn1/lib/gstr.h             |   50 +
 grub-core/lib/libtasn1/lib/int.h              |  221 ++
 grub-core/lib/libtasn1/lib/parser_aux.c       | 1178 ++++++++
 grub-core/lib/libtasn1/lib/parser_aux.h       |  172 ++
 grub-core/lib/libtasn1/lib/structure.c        | 1225 ++++++++
 grub-core/lib/libtasn1/lib/structure.h        |   46 +
 grub-core/lib/libtasn1/libtasn1.h             |  643 +++++
 .../tests/CVE-2018-1000654-1_asn1_tab.h       |   32 +
 .../tests/CVE-2018-1000654-2_asn1_tab.h       |   36 +
 .../lib/libtasn1/tests/CVE-2018-1000654.c     |   72 +
 grub-core/lib/libtasn1/tests/Test_overflow.c  |  168 ++
 grub-core/lib/libtasn1/tests/Test_simple.c    |  226 ++
 grub-core/lib/libtasn1/tests/Test_strings.c   |  156 +
 .../lib/libtasn1/tests/object-id-decoding.c   |  121 +
 .../lib/libtasn1/tests/object-id-encoding.c   |  133 +
 grub-core/lib/libtasn1/tests/octet-string.c   |  230 ++
 grub-core/lib/libtasn1/tests/reproducers.c    |   90 +
 grub-core/lib/libtasn1_wrap/wrap.c            |   27 +
 grub-core/lib/posix_wrap/c-ctype.h            |  114 +
 grub-core/lib/posix_wrap/limits.h             |    1 +
 grub-core/lib/posix_wrap/stdlib.h             |    8 +
 grub-core/lib/posix_wrap/string.h             |   21 +
 grub-core/lib/posix_wrap/sys/types.h          |    1 +
 grub-core/lib/tss2/buffer.c                   |  149 +
 grub-core/lib/tss2/tcg2.h                     |   35 +
 grub-core/lib/tss2/tcg2_emu.c                 |   54 +
 grub-core/lib/tss2/tpm2_cmd.c                 | 1054 +++++++
 grub-core/lib/tss2/tpm2_cmd.h                 |  157 ++
 grub-core/lib/tss2/tss2.c                     |   21 +
 grub-core/lib/tss2/tss2_buffer.h              |   66 +
 grub-core/lib/tss2/tss2_mu.c                  | 1170 ++++++++
 grub-core/lib/tss2/tss2_mu.h                  |  397 +++
 grub-core/lib/tss2/tss2_structs.h             |  768 +++++
 grub-core/lib/tss2/tss2_types.h               |  404 +++
 grub-core/tests/asn1/asn1_test.c              |   49 +
 grub-core/tests/asn1/asn1_test.h              |   44 +
 grub-core/tests/lib/functional_test.c         |    1 +
 include/grub/cryptodisk.h                     |   16 +
 include/grub/emu/misc.h                       |    5 +
 include/grub/key_protector.h                  |   47 +
 tests/asn1_test.in                            |   11 +
 tests/tpm2_key_protector_test.in              |  389 +++
 tests/util/grub-shell.in                      |    6 +-
 util/grub-protect.c                           | 1423 ++++++++++
 80 files changed, 20819 insertions(+), 75 deletions(-)
 create mode 100644 docs/man/grub-protect.h2m
 create mode 100644 grub-core/commands/tpm2_key_protector/args.c
 create mode 100644 grub-core/commands/tpm2_key_protector/module.c
 create mode 100644 grub-core/commands/tpm2_key_protector/tpm2.h
 create mode 100644 grub-core/commands/tpm2_key_protector/tpm2_args.h
 create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key.asn
 create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key.c
 create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key.h
 create mode 100644 grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c
 create mode 100644 grub-core/disk/key_protector.c
 create mode 100644 grub-core/lib/efi/tcg2.c
 create mode 100644 
grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.patch
 create mode 100644 
grub-core/lib/libtasn1-patches/0002-libtasn1-use-bound-checked-_asn1_str_cat.patch
 create mode 100644 
grub-core/lib/libtasn1-patches/0003-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch
 create mode 100644 
grub-core/lib/libtasn1-patches/0004-libtasn1-Use-grub_divmod64-for-division.patch
 create mode 100644 
grub-core/lib/libtasn1-patches/0005-libtasn1-fix-the-potential-buffer-overrun.patch
 create mode 100644 
grub-core/lib/libtasn1-patches/0006-asn1_test-changes-for-grub-compatibility.patch
 create mode 100644 grub-core/lib/libtasn1/COPYING
 create mode 100644 grub-core/lib/libtasn1/README.md
 create mode 100644 grub-core/lib/libtasn1/lib/coding.c
 create mode 100644 grub-core/lib/libtasn1/lib/decoding.c
 create mode 100644 grub-core/lib/libtasn1/lib/element.c
 create mode 100644 grub-core/lib/libtasn1/lib/element.h
 create mode 100644 grub-core/lib/libtasn1/lib/errors.c
 create mode 100644 grub-core/lib/libtasn1/lib/gstr.c
 create mode 100644 grub-core/lib/libtasn1/lib/gstr.h
 create mode 100644 grub-core/lib/libtasn1/lib/int.h
 create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.c
 create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.h
 create mode 100644 grub-core/lib/libtasn1/lib/structure.c
 create mode 100644 grub-core/lib/libtasn1/lib/structure.h
 create mode 100644 grub-core/lib/libtasn1/libtasn1.h
 create mode 100644 grub-core/lib/libtasn1/tests/CVE-2018-1000654-1_asn1_tab.h
 create mode 100644 grub-core/lib/libtasn1/tests/CVE-2018-1000654-2_asn1_tab.h
 create mode 100644 grub-core/lib/libtasn1/tests/CVE-2018-1000654.c
 create mode 100644 grub-core/lib/libtasn1/tests/Test_overflow.c
 create mode 100644 grub-core/lib/libtasn1/tests/Test_simple.c
 create mode 100644 grub-core/lib/libtasn1/tests/Test_strings.c
 create mode 100644 grub-core/lib/libtasn1/tests/object-id-decoding.c
 create mode 100644 grub-core/lib/libtasn1/tests/object-id-encoding.c
 create mode 100644 grub-core/lib/libtasn1/tests/octet-string.c
 create mode 100644 grub-core/lib/libtasn1/tests/reproducers.c
 create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c
 create mode 100644 grub-core/lib/posix_wrap/c-ctype.h
 create mode 100644 grub-core/lib/tss2/buffer.c
 create mode 100644 grub-core/lib/tss2/tcg2.h
 create mode 100644 grub-core/lib/tss2/tcg2_emu.c
 create mode 100644 grub-core/lib/tss2/tpm2_cmd.c
 create mode 100644 grub-core/lib/tss2/tpm2_cmd.h
 create mode 100644 grub-core/lib/tss2/tss2.c
 create mode 100644 grub-core/lib/tss2/tss2_buffer.h
 create mode 100644 grub-core/lib/tss2/tss2_mu.c
 create mode 100644 grub-core/lib/tss2/tss2_mu.h
 create mode 100644 grub-core/lib/tss2/tss2_structs.h
 create mode 100644 grub-core/lib/tss2/tss2_types.h
 create mode 100644 grub-core/tests/asn1/asn1_test.c
 create mode 100644 grub-core/tests/asn1/asn1_test.h
 create mode 100644 include/grub/key_protector.h
 create mode 100644 tests/asn1_test.in
 create mode 100644 tests/tpm2_key_protector_test.in
 create mode 100644 util/grub-protect.c

Range-diff against v17:
 1:  834e3b578 =  1:  77d52a5b7 posix_wrap: tweaks in preparation for libtasn1
 2:  cdf54d25a !  2:  931fccd49 libtasn1: import libtasn1-4.19.0
    @@ Commit message
         tar xf libtasn1-4.19.0.tar.gz
         rm -rf grub-core/lib/libtasn1/
         mkdir -p grub-core/lib/libtasn1/lib/
    +    mkdir -p grub-core/lib/libtasn1/tests/
         cp libtasn1-4.19.0/{README.md,COPYING} grub-core/lib/libtasn1/
         cp 
libtasn1-4.19.0/lib/{coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h}
 grub-core/libtasn1/lib/
         cp libtasn1-4.19.0/lib/includes/libtasn1.h grub-core/lib/libtasn1/
    +    cp 
libtasn1-4.19.0/tests/{CVE-2018-1000654-1_asn1_tab.h,CVE-2018-1000654-2_asn1_tab.h,CVE-2018-1000654.c,object-id-decoding.c,object-id-encoding.c,octet-string.c,reproducers.c,Test_overflow.c,Test_simple.c,Test_strings.c}
 grub-core/lib/libtasn1/tests
         rm -rf libtasn1-4.19.0*
     
         Signed-off-by: Daniel Axtens <dja@axtens.net>
         Signed-off-by: Gary Lin <glin@suse.com>
         Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
    +    Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
     
      ## grub-core/lib/libtasn1/COPYING (new) ##
     @@
    @@ grub-core/lib/libtasn1/libtasn1.h (new)
     +# endif
     +
     +#endif                            /* LIBTASN1_H */
    +
    + ## grub-core/lib/libtasn1/tests/CVE-2018-1000654-1_asn1_tab.h (new) ##
    +@@
    ++#if HAVE_CONFIG_H
    ++# include "config.h"
    ++#endif
    ++
    ++#include <libtasn1.h>
    ++
    ++const asn1_static_node CVE_2018_1000654_1_asn1_tab[] = {
    ++  { "TEST_TREE", 536875024, NULL },
    ++  { NULL, 1610612748, NULL },
    ++  { "iso", 1073741825, "1"},
    ++  { "identified-organization", 1073741825, "3"},
    ++  { "dod", 1073741825, "6"},
    ++  { "internet", 1073741825, "1"},
    ++  { "security", 1073741825, "5"},
    ++  { "mechanisms", 1073741825, "5"},
    ++  { "pkix", 1073741825, "7"},
    ++  { "id-mod", 1073741825, "0"},
    ++  { "id-pkix1-implicit-88", 1, "2"},
    ++  { "id-xnyTest", 1879048204, NULL },
    ++  { NULL, 1073741825, "id-ix"},
    ++  { NULL, 1073741825, "29"},
    ++  { NULL, 1, "1"},
    ++  { "id-ix", 1880096780, "OBJECR"},
    ++  { NULL, 1073741825, "id-ix"},
    ++  { NULL, 1073741825, "29"},
    ++  { NULL, 1, "2"},
    ++  { "id-xnyTest", 805306380, NULL },
    ++  { NULL, 1073741825, "id-ix"},
    ++  { NULL, 1073741825, "29"},
    ++  { NULL, 1, "1"},
    ++  { NULL, 0, NULL }
    ++};
    +
    + ## grub-core/lib/libtasn1/tests/CVE-2018-1000654-2_asn1_tab.h (new) ##
    +@@
    ++#if HAVE_CONFIG_H
    ++# include "config.h"
    ++#endif
    ++
    ++#include <libtasn1.h>
    ++
    ++const asn1_static_node CVE_2018_1000654_2_asn1_tab[] = {
    ++  { "TEST_TREE", 536875024, NULL },
    ++  { NULL, 1610612748, NULL },
    ++  { "iso", 1073741825, "1"},
    ++  { "identified-organization", 1073741825, "3"},
    ++  { "dod", 1073741825, "6"},
    ++  { "internet", 1073741825, "1"},
    ++  { "security", 1073741825, "5"},
    ++  { "mechanisms", 1073741825, "5"},
    ++  { "pkix", 1073741825, "7"},
    ++  { "id-mod", 1073741825, "0"},
    ++  { "id-pkix1-implicit-88", 1, "2"},
    ++  { "id-oneTest", 1879048204, NULL },
    ++  { NULL, 1073741825, "id-two"},
    ++  { NULL, 1073741825, "9"},
    ++  { NULL, 1, "1"},
    ++  { "id-two", 1879048204, NULL },
    ++  { NULL, 1073741825, "id-three"},
    ++  { NULL, 1073741825, "2"},
    ++  { NULL, 1, "2"},
    ++  { "id-three", 1879048204, NULL },
    ++  { NULL, 1073741825, "id-four"},
    ++  { NULL, 1073741825, "3"},
    ++  { NULL, 1, "3"},
    ++  { "id-four", 805306380, NULL },
    ++  { NULL, 1073741825, "id-two"},
    ++  { NULL, 1073741825, "3"},
    ++  { NULL, 1, "3"},
    ++  { NULL, 0, NULL }
    ++};
    +
    + ## grub-core/lib/libtasn1/tests/CVE-2018-1000654.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2002-2022 Free Software Foundation, Inc.
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ */
    ++
    ++/****************************************************************/
    ++/* Description: reproducer for CVE-2018-1000654                   */
    ++/****************************************************************/
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++#include "CVE-2018-1000654-1_asn1_tab.h"
    ++#include "CVE-2018-1000654-2_asn1_tab.h"
    ++
    ++int
    ++main (int argc, char *argv[])
    ++{
    ++  int result, verbose = 0;
    ++  asn1_node definitions = NULL;
    ++  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
    ++
    ++  if (argc > 1)
    ++    verbose = 1;
    ++
    ++  printf ("Test 1\n");
    ++
    ++  result =
    ++    asn1_array2tree (CVE_2018_1000654_1_asn1_tab, &definitions,
    ++               errorDescription);
    ++  if (result != ASN1_RECURSION)
    ++    {
    ++      asn1_perror (result);
    ++      printf ("ErrorDescription = %s\n\n", errorDescription);
    ++      exit (1);
    ++    }
    ++
    ++  asn1_delete_structure (&definitions);
    ++
    ++  printf ("Test 2\n");
    ++
    ++  result =
    ++    asn1_array2tree (CVE_2018_1000654_2_asn1_tab, &definitions,
    ++               errorDescription);
    ++  if (result != ASN1_RECURSION)
    ++    {
    ++      asn1_perror (result);
    ++      printf ("ErrorDescription = %s\n\n", errorDescription);
    ++      exit (1);
    ++    }
    ++
    ++  asn1_delete_structure (&definitions);
    ++
    ++  if (verbose)
    ++    printf ("Success\n");
    ++  exit (0);
    ++}
    +
    + ## grub-core/lib/libtasn1/tests/Test_overflow.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2012-2022 Free Software Foundation, Inc.
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ */
    ++
    ++/* Written by Simon Josefsson */
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++#include <limits.h>
    ++
    ++#include "libtasn1.h"
    ++
    ++int
    ++main (int argc, char **argv)
    ++{
    ++  /* Test that values larger than long are rejected.  This has worked
    ++     fine with all versions of libtasn1. */
    ++  int verbose = 0;
    ++
    ++  if (argc > 1)
    ++    verbose = 1;
    ++
    ++  {
    ++    unsigned char der[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
    ++    long l;
    ++    int len;
    ++
    ++    l = asn1_get_length_der (der, sizeof der, &len);
    ++
    ++    if (l == -2L)
    ++      {
    ++  if (verbose)
    ++    puts ("OK: asn1_get_length_der bignum");
    ++      }
    ++    else
    ++      {
    ++  printf ("ERROR: asn1_get_length_der bignum (l %ld len %d)\n", l, len);
    ++  return 1;
    ++      }
    ++  }
    ++
    ++  /* Test that values larger than int but smaller than long are
    ++     rejected.  This limitation was introduced with libtasn1 2.12. */
    ++  if (LONG_MAX > INT_MAX)
    ++    {
    ++      unsigned long num = ((long) UINT_MAX) << 2;
    ++      unsigned char der[20];
    ++      int der_len;
    ++      long l;
    ++      int len;
    ++
    ++      asn1_length_der (num, der, &der_len);
    ++
    ++      l = asn1_get_length_der (der, der_len, &len);
    ++
    ++      if (l == -2L)
    ++  {
    ++    if (verbose)
    ++      puts ("OK: asn1_get_length_der intnum");
    ++  }
    ++      else
    ++  {
    ++    printf ("ERROR: asn1_get_length_der intnum (l %ld len %d)\n", l,
    ++            len);
    ++    return 1;
    ++  }
    ++    }
    ++
    ++  /* Test that values larger than would fit in the input string are
    ++     rejected.  This problem was fixed in libtasn1 2.12. */
    ++  {
    ++    unsigned long num = 64;
    ++    unsigned char der[20];
    ++    int der_len;
    ++    long l;
    ++    int len;
    ++
    ++    asn1_length_der (num, der, &der_len);
    ++
    ++    der_len = sizeof (der);
    ++    l = asn1_get_length_der (der, der_len, &len);
    ++
    ++    if (l == -4L)
    ++      {
    ++  if (verbose)
    ++    puts ("OK: asn1_get_length_der overflow-small");
    ++      }
    ++    else
    ++      {
    ++  printf ("ERROR: asn1_get_length_der overflow-small (l %ld len %d)\n",
    ++          l, len);
    ++  return 1;
    ++      }
    ++  }
    ++
    ++  /* Test that values larger than would fit in the input string are
    ++     rejected.  This problem was fixed in libtasn1 2.12. */
    ++  {
    ++    unsigned long num = 1073741824;
    ++    unsigned char der[20];
    ++    int der_len;
    ++    long l;
    ++    int len;
    ++
    ++    asn1_length_der (num, der, &der_len);
    ++
    ++    der_len = sizeof (der);
    ++    l = asn1_get_length_der (der, der_len, &len);
    ++
    ++    if (l == -4L)
    ++      {
    ++  if (verbose)
    ++    puts ("OK: asn1_get_length_der overflow-large1");
    ++      }
    ++    else
    ++      {
    ++  printf ("ERROR: asn1_get_length_der overflow-large1 (l %ld len %d)\n",
    ++          l, len);
    ++  return 1;
    ++      }
    ++  }
    ++
    ++  /* Test that values larger than would fit in the input string are
    ++     rejected.  This problem was fixed in libtasn1 2.12. */
    ++  {
    ++    unsigned long num = 2147483649;
    ++    unsigned char der[20];
    ++    int der_len;
    ++    long l;
    ++    int len;
    ++
    ++    asn1_length_der (num, der, &der_len);
    ++
    ++    der_len = sizeof (der);
    ++    l = asn1_get_length_der (der, der_len, &len);
    ++
    ++    if (l == -2L)
    ++      {
    ++  if (verbose)
    ++    puts ("OK: asn1_get_length_der overflow-large2");
    ++      }
    ++    else
    ++      {
    ++  printf ("ERROR: asn1_get_length_der overflow-large2 (l %ld len %d)\n",
    ++          l, len);
    ++  return 1;
    ++      }
    ++  }
    ++
    ++  return 0;
    ++}
    +
    + ## grub-core/lib/libtasn1/tests/Test_simple.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2011-2022 Free Software Foundation, Inc.
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ * Written by Simon Josefsson
    ++ *
    ++ */
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++
    ++#include "libtasn1.h"
    ++
    ++struct tv
    ++{
    ++  int bitlen;
    ++  const char *bitstr;
    ++  int derlen;
    ++  const char *der;
    ++};
    ++
    ++static const struct tv tv[] = {
    ++  {0, "", 2, "\x01\x00"},
    ++  {1, "\x00", 3, "\x02\x07\x00"},
    ++  {2, "\x00", 3, "\x02\x06\x00"},
    ++  {3, "\x00", 3, "\x02\x05\x00"},
    ++  {4, "\x00", 3, "\x02\x04\x00"},
    ++  {5, "\x00", 3, "\x02\x03\x00"},
    ++  {6, "\x00", 3, "\x02\x02\x00"},
    ++  {7, "\x00", 3, "\x02\x01\x00"},
    ++  {8, "\x00\x00", 3, "\x02\x00\x00"},
    ++  {9, "\x00\x00", 4, "\x03\x07\x00\x00"},
    ++  {10, "\x00\x00", 4, "\x03\x06\x00\x00"},
    ++  {11, "\x00\x00", 4, "\x03\x05\x00\x00"},
    ++  {12, "\x00\x00", 4, "\x03\x04\x00\x00"},
    ++  {13, "\x00\x00", 4, "\x03\x03\x00\x00"},
    ++  {14, "\x00\x00", 4, "\x03\x02\x00\x00"},
    ++  {15, "\x00\x00", 4, "\x03\x01\x00\x00"},
    ++  {16, "\x00\x00", 4, "\x03\x00\x00\x00"},
    ++  {17, "\x00\x00\x00", 5, "\x04\x07\x00\x00\x00"},
    ++  {18, "\x00\x00\x00", 5, "\x04\x06\x00\x00\x00"},
    ++  {19, "\x00\x00\x00", 5, "\x04\x05\x00\x00\x00"},
    ++  {1, "\xFF", 3, "\x02\x07\x80"},
    ++  {2, "\xFF", 3, "\x02\x06\xc0"},
    ++  {3, "\xFF", 3, "\x02\x05\xe0"},
    ++  {4, "\xFF", 3, "\x02\x04\xf0"},
    ++  {5, "\xFF", 3, "\x02\x03\xf8"},
    ++  {6, "\xFF", 3, "\x02\x02\xfc"},
    ++  {7, "\xFF", 3, "\x02\x01\xfe"},
    ++  {8, "\xFF\xFF", 3, "\x02\x00\xff"},
    ++  {9, "\xFF\xFF", 4, "\x03\x07\xff\x80"},
    ++  {10, "\xFF\xFF", 4, "\x03\x06\xff\xc0"},
    ++  {11, "\xFF\xFF", 4, "\x03\x05\xff\xe0"},
    ++  {12, "\xFF\xFF", 4, "\x03\x04\xff\xf0"},
    ++  {13, "\xFF\xFF", 4, "\x03\x03\xff\xf8"},
    ++  {14, "\xFF\xFF", 4, "\x03\x02\xff\xfc"},
    ++  {15, "\xFF\xFF", 4, "\x03\x01\xff\xfe"},
    ++  {16, "\xFF\xFF", 4, "\x03\x00\xff\xff"},
    ++  {17, "\xFF\xFF\xFF", 5, "\x04\x07\xff\xff\x80"},
    ++  {18, "\xFF\xFF\xFF", 5, "\x04\x06\xff\xff\xc0"},
    ++  {19, "\xFF\xFF\xFF", 5, "\x04\x05\xff\xff\xe0"},
    ++};
    ++
    ++int
    ++main (int argc, char *argv[])
    ++{
    ++  int result;
    ++  unsigned char der[100];
    ++  unsigned char str[100];
    ++  int der_len = sizeof (der);
    ++  int str_size = sizeof (str);
    ++  int ret_len, bit_len;
    ++  size_t i;
    ++
    ++  {
    ++    unsigned int etype = 38;
    ++    unsigned int my_str_len = 10;
    ++    unsigned char my_str[10];
    ++    unsigned int tl_len = 10;
    ++    unsigned char tl[10];
    ++
    ++    /* https://gitlab.com/gnutls/libtasn1/-/issues/32 */
    ++    result = asn1_encode_simple_der (etype, my_str, my_str_len, tl, 
&tl_len);
    ++    if (result != ASN1_VALUE_NOT_VALID)
    ++      {
    ++  fprintf (stderr, "asn1_encode_simple_der out of range etype\n");
    ++  return 1;
    ++      }
    ++  }
    ++
    ++  /* Dummy test */
    ++
    ++  asn1_bit_der (NULL, 0, der, &der_len);
    ++  result = asn1_get_bit_der (der, 0, &ret_len, str, str_size, &bit_len);
    ++  if (result != ASN1_GENERIC_ERROR)
    ++    {
    ++      fprintf (stderr, "asn1_get_bit_der zero\n");
    ++      return 1;
    ++    }
    ++
    ++  /* Encode short strings with increasing bit lengths */
    ++
    ++  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
    ++    {
    ++      /* Encode */
    ++
    ++      asn1_bit_der ((const unsigned char *) tv[i].bitstr, tv[i].bitlen,
    ++              der, &der_len);
    ++
    ++#if 0
    ++      {
    ++  size_t j;
    ++  for (j = 0; j < der_len; j++)
    ++    printf ("\\x%02x", der[j]);
    ++  printf ("\n");
    ++      }
    ++#endif
    ++
    ++      if (der_len != tv[i].derlen || memcmp (der, tv[i].der, der_len) != 
0)
    ++  {
    ++    fprintf (stderr, "asn1_bit_der iter %lu\n", (unsigned long) i);
    ++    return 1;
    ++  }
    ++
    ++      /* Decode it */
    ++
    ++      result = asn1_get_bit_der (der, der_len, &ret_len, str,
    ++                           str_size, &bit_len);
    ++      if (result != ASN1_SUCCESS || ret_len != tv[i].derlen
    ++    || bit_len != tv[i].bitlen)
    ++  {
    ++    fprintf (stderr, "asn1_get_bit_der iter %lu, err: %d\n",
    ++             (unsigned long) i, result);
    ++    return 1;
    ++  }
    ++    }
    ++
    ++
    ++  /* Decode sample from "A Layman's Guide to a Subset of ASN.1, BER,
    ++     and DER" section 5.4 "BIT STRING": "The BER encoding of the BIT
    ++     STRING value "011011100101110111" can be any of the following,
    ++     among others, depending on the choice of padding bits, the form
    ++     of length octets [...]".
    ++   */
    ++
    ++  /* 03 04 06 6e 5d c0  DER encoding */
    ++
    ++  memcpy (der, "\x04\x06\x6e\x5d\xc0", 5);
    ++  der_len = 5;
    ++
    ++  result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, 
&bit_len);
    ++  if (result != ASN1_SUCCESS || ret_len != 5
    ++      || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0)
    ++    {
    ++      fprintf (stderr, "asn1_get_bit_der example\n");
    ++      return 1;
    ++    }
    ++
    ++  der_len = sizeof (der);
    ++  asn1_bit_der (str, bit_len, der, &der_len);
    ++  if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0)
    ++    {
    ++      fprintf (stderr, "asn1_bit_der example roundtrip\n");
    ++      return 1;
    ++    }
    ++
    ++  /* 03 04 06 6e 5d e0 padded with "100000" */
    ++
    ++  memcpy (der, "\x04\x06\x6e\x5d\xe0", 5);
    ++  der_len = 5;
    ++
    ++  result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, 
&bit_len);
    ++  if (result != ASN1_SUCCESS || ret_len != 5
    ++      || bit_len != 18 || memcmp (str, "\x6e\x5d\xe0", 3) != 0)
    ++    {
    ++      fprintf (stderr, "asn1_get_bit_der example padded\n");
    ++      return 1;
    ++    }
    ++
    ++  der_len = sizeof (der);
    ++  asn1_bit_der (str, bit_len, der, &der_len);
    ++  if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0)
    ++    {
    ++      fprintf (stderr, "asn1_bit_der example roundtrip\n");
    ++      return 1;
    ++    }
    ++
    ++  /* 03 81 04 06 6e 5d c0 long form of length octets */
    ++
    ++  memcpy (der, "\x81\x04\x06\x6e\x5d\xc0", 6);
    ++  der_len = 6;
    ++
    ++  result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, 
&bit_len);
    ++
    ++  if (result != ASN1_SUCCESS || ret_len != 6
    ++      || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0)
    ++    {
    ++      fprintf (stderr, "asn1_get_bit_der example long form\n");
    ++      return 1;
    ++    }
    ++
    ++  der_len = sizeof (der);
    ++  asn1_bit_der (str, bit_len, der, &der_len);
    ++  if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0)
    ++    {
    ++      fprintf (stderr, "asn1_bit_der example roundtrip\n");
    ++      return 1;
    ++    }
    ++
    ++  return 0;
    ++}
    +
    + ## grub-core/lib/libtasn1/tests/Test_strings.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2012-2022 Free Software Foundation, Inc.
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ * Written by Simon Josefsson
    ++ *
    ++ */
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++
    ++#include "libtasn1.h"
    ++
    ++struct tv
    ++{
    ++  unsigned int etype;
    ++  unsigned int str_len;
    ++  const void *str;
    ++  unsigned int der_len;
    ++  const void *der;
    ++};
    ++
    ++static const struct tv tv[] = {
    ++  {ASN1_ETYPE_IA5_STRING, 20,
    ++   
"\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72",
    ++   22,
    ++   
"\x16\x14\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72"},
    ++  {ASN1_ETYPE_PRINTABLE_STRING, 5, "\x4e\x69\x6b\x6f\x73",
    ++   7, "\x13\x05\x4e\x69\x6b\x6f\x73"},
    ++  {ASN1_ETYPE_UTF8_STRING, 12, "Αττική",
    ++   14, "\x0c\x0c\xce\x91\xcf\x84\xcf\x84\xce\xb9\xce\xba\xce\xae"},
    ++  {ASN1_ETYPE_TELETEX_STRING, 15,
    ++   "\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e",
    ++   17,
    ++   
"\x14\x0f\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e"},
    ++  {ASN1_ETYPE_OCTET_STRING, 36,
    ++   
"\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A",
    ++   38,
    ++   
"\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A"}
    ++};
    ++
    ++#define SSTR(x) sizeof(x)-1,x
    ++static const struct tv ber[] = {
    ++  {ASN1_ETYPE_OCTET_STRING,
    ++   SSTR ("\xa0\xa0"),
    ++   SSTR ("\x24\x80\x04\x82\x00\x02\xa0\xa0\x00\x00")},
    ++  {ASN1_ETYPE_OCTET_STRING,
    ++   SSTR ("\xa0\xa0\xb0\xb0\xb0"),
    ++   SSTR
    ++   
("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x00\x00")},
    ++  {ASN1_ETYPE_OCTET_STRING,
    ++   SSTR ("\xa0\xa0\xb0\xb0\xb0\xa1\xa1"),
    ++   SSTR
    ++   
("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x24\x80\x04\x82\x00\x02\xa1\xa1\x00\x00\x00\x00")},
    ++  {ASN1_ETYPE_OCTET_STRING,
    ++   SSTR ("\xa0\xa0\xb0\xb0\xb0\xa1\xa1\xc1"),
    ++   SSTR
    ++   
("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x24\x80\x04\x82\x00\x02\xa1\xa1\x04\x82\x00\x01\xc1\x00\x00\x00\x00")},
    ++};
    ++
    ++int
    ++main (int argc, char *argv[])
    ++{
    ++  int ret;
    ++  unsigned char tl[ASN1_MAX_TL_SIZE];
    ++  unsigned int tl_len, der_len, str_len;
    ++  const unsigned char *str;
    ++  unsigned char *b;
    ++  unsigned int i;
    ++
    ++  /* Dummy test */
    ++
    ++  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
    ++    {
    ++      /* Encode */
    ++      tl_len = sizeof (tl);
    ++      ret = asn1_encode_simple_der (tv[i].etype, tv[i].str, tv[i].str_len,
    ++                              tl, &tl_len);
    ++      if (ret != ASN1_SUCCESS)
    ++  {
    ++    fprintf (stderr, "Encoding error in %u: %s\n", i,
    ++             asn1_strerror (ret));
    ++    return 1;
    ++  }
    ++      der_len = tl_len + tv[i].str_len;
    ++
    ++      if (der_len != tv[i].der_len || memcmp (tl, tv[i].der, tl_len) != 0)
    ++  {
    ++    fprintf (stderr,
    ++             "DER encoding differs in %u! (size: %u, expected: %u)\n",
    ++             i, der_len, tv[i].der_len);
    ++    return 1;
    ++  }
    ++
    ++      /* decoding */
    ++      ret =
    ++  asn1_decode_simple_der (tv[i].etype, tv[i].der, tv[i].der_len, &str,
    ++                          &str_len);
    ++      if (ret != ASN1_SUCCESS)
    ++  {
    ++    fprintf (stderr, "Decoding error in %u: %s\n", i,
    ++             asn1_strerror (ret));
    ++    return 1;
    ++  }
    ++
    ++      if (str_len != tv[i].str_len || memcmp (str, tv[i].str, str_len) != 
0)
    ++  {
    ++    fprintf (stderr,
    ++             "DER decoded data differ in %u! (size: %u, expected: %u)\n",
    ++             i, der_len, tv[i].str_len);
    ++    return 1;
    ++  }
    ++    }
    ++
    ++  /* BER decoding */
    ++  for (i = 0; i < sizeof (ber) / sizeof (ber[0]); i++)
    ++    {
    ++      /* decoding */
    ++      ret =
    ++  asn1_decode_simple_ber (ber[i].etype, ber[i].der, ber[i].der_len, &b,
    ++                          &str_len, NULL);
    ++      if (ret != ASN1_SUCCESS)
    ++  {
    ++    fprintf (stderr, "BER decoding error in %u: %s\n", i,
    ++             asn1_strerror (ret));
    ++    return 1;
    ++  }
    ++
    ++      if (str_len != ber[i].str_len || memcmp (b, ber[i].str, str_len) != 
0)
    ++  {
    ++    fprintf (stderr,
    ++             "BER decoded data differ in %u! (size: %u, expected: %u)\n",
    ++             i, str_len, ber[i].str_len);
    ++    return 1;
    ++  }
    ++      free (b);
    ++    }
    ++
    ++
    ++  return 0;
    ++}
    +
    + ## grub-core/lib/libtasn1/tests/object-id-decoding.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2016 Red Hat, Inc.
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ */
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++
    ++#include "libtasn1.h"
    ++
    ++struct tv
    ++{
    ++  int der_len;
    ++  const unsigned char *der;
    ++  const char *oid;
    ++  int expected_error;
    ++};
    ++
    ++static const struct tv tv[] = {
    ++  {.der_len = 5,
    ++   .der = (void *) "\x06\x03\x80\x37\x03",
    ++   .oid = "2.999.3",
    ++   .expected_error = ASN1_DER_ERROR       /* leading 0x80 */
    ++   },
    ++  {.der_len = 12,
    ++   .der = (void *) "\x06\x0a\x2b\x06\x01\x80\x01\x92\x08\x09\x05\x01",
    ++   .oid = "1.3.6.1.4.1.2312.9.5.1",
    ++   .expected_error = ASN1_DER_ERROR       /* leading 0x80 */
    ++   },
    ++  {.der_len = 6,
    ++   .der = (void *) "\x06\x04\x01\x02\x03\x04",
    ++   .oid = "0.1.2.3.4",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 5,
    ++   .der = (void *) "\x06\x03\x51\x02\x03",
    ++   .oid = "2.1.2.3",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 5,
    ++   .der = (void *) "\x06\x03\x88\x37\x03",
    ++   .oid = "2.999.3",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 12,
    ++   .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01",
    ++   .oid = "1.3.6.1.4.1.2312.9.5.1",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 19,
    ++   .der =
    ++   (void *)
    ++   
"\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d",
    ++   .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 19,
    ++   .der =
    ++   (void *)
    ++   
"\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07",
    ++   .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7",
    ++   .expected_error = ASN1_SUCCESS},
    ++};
    ++
    ++int
    ++main (int argc, char *argv[])
    ++{
    ++  char str[128];
    ++  int ret, ret_len;
    ++  size_t i;
    ++
    ++  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
    ++    {
    ++      /* decode */
    ++      ret =
    ++  asn1_get_object_id_der (tv[i].der + 1,
    ++                          tv[i].der_len - 1, &ret_len, str,
    ++                          sizeof (str));
    ++      if (ret != tv[i].expected_error)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: asn1_get_object_id_der iter %lu: got '%s' expected 
%d\n",
    ++             __LINE__, (unsigned long) i, asn1_strerror (ret),
    ++             tv[i].expected_error);
    ++    return 1;
    ++  }
    ++
    ++      if (tv[i].expected_error != ASN1_SUCCESS)
    ++  continue;
    ++
    ++      if (ret_len != tv[i].der_len - 1)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: iter %lu: error in DER, length returned is %d, had 
%d\n",
    ++             __LINE__, (unsigned long) i, ret_len, tv[i].der_len - 1);
    ++    return 1;
    ++  }
    ++
    ++      if (strcmp (tv[i].oid, str) != 0)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: strcmp iter %lu: got invalid OID: %s, expected: %s\n",
    ++             __LINE__, (unsigned long) i, str, tv[i].oid);
    ++    return 1;
    ++  }
    ++
    ++    }
    ++
    ++  return 0;
    ++}
    +
    + ## grub-core/lib/libtasn1/tests/object-id-encoding.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2019 Nikos Mavrogiannopoulos
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ */
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++
    ++#include "libtasn1.h"
    ++
    ++struct tv
    ++{
    ++  int der_len;
    ++  const unsigned char *der;
    ++  const char *oid;
    ++  int expected_error;
    ++};
    ++
    ++static const struct tv tv[] = {
    ++  {.der_len = 0,
    ++   .der = (void *) "",
    ++   .oid = "5.999.3",
    ++   .expected_error = ASN1_VALUE_NOT_VALID /* cannot start with 5 */
    ++   },
    ++  {.der_len = 0,
    ++   .der = (void *) "",
    ++   .oid = "0.48.9",
    ++   .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 48 */
    ++   },
    ++  {.der_len = 0,
    ++   .der = (void *) "",
    ++   .oid = "1.40.9",
    ++   .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 40 */
    ++   },
    ++  {.der_len = 4,
    ++   .der = (void *) "\x06\x02\x4f\x63",
    ++   .oid = "1.39.99",
    ++   .expected_error = ASN1_SUCCESS,
    ++   },
    ++  {.der_len = 6,
    ++   .der = (void *) "\x06\x04\x01\x02\x03\x04",
    ++   .oid = "0.1.2.3.4",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 5,
    ++   .der = (void *) "\x06\x03\x51\x02\x03",
    ++   .oid = "2.1.2.3",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 5,
    ++   .der = (void *) "\x06\x03\x88\x37\x03",
    ++   .oid = "2.999.3",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 12,
    ++   .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01",
    ++   .oid = "1.3.6.1.4.1.2312.9.5.1",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 19,
    ++   .der =
    ++   (void *)
    ++   
"\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d",
    ++   .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109",
    ++   .expected_error = ASN1_SUCCESS},
    ++  {.der_len = 19,
    ++   .der =
    ++   (void *)
    ++   
"\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07",
    ++   .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7",
    ++   .expected_error = ASN1_SUCCESS},
    ++};
    ++
    ++int
    ++main (int argc, char *argv[])
    ++{
    ++  unsigned char der[128];
    ++  int ret, der_len, i, j;
    ++
    ++  for (i = 0; i < (int) (sizeof (tv) / sizeof (tv[0])); i++)
    ++    {
    ++      der_len = sizeof (der);
    ++      ret = asn1_object_id_der (tv[i].oid, der, &der_len, 0);
    ++      if (ret != ASN1_SUCCESS)
    ++  {
    ++    if (ret == tv[i].expected_error)
    ++      continue;
    ++    fprintf (stderr,
    ++             "%d: iter %lu, encoding of OID failed: %s\n",
    ++             __LINE__, (unsigned long) i, asn1_strerror (ret));
    ++    return 1;
    ++  }
    ++      else if (ret != tv[i].expected_error)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: iter %lu, encoding of OID %s succeeded when expecting 
failure\n",
    ++             __LINE__, (unsigned long) i, tv[i].oid);
    ++    return 1;
    ++  }
    ++
    ++      if (der_len != tv[i].der_len || memcmp (der, tv[i].der, der_len) != 
0)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: iter %lu, re-encoding of OID %s resulted to different 
string (%d vs %d bytes)\n",
    ++             __LINE__, (unsigned long) i, tv[i].oid, der_len,
    ++             tv[i].der_len);
    ++    fprintf (stderr, "\nGot:\t\t");
    ++    for (j = 0; j < der_len; j++)
    ++      fprintf (stderr, "%.2x", der[j]);
    ++
    ++    fprintf (stderr, "\nExpected:\t");
    ++    for (j = 0; j < tv[i].der_len; j++)
    ++      fprintf (stderr, "%.2x", tv[i].der[j]);
    ++    fprintf (stderr, "\n");
    ++
    ++    return 1;
    ++  }
    ++    }
    ++
    ++  return 0;
    ++}
    +
    + ## grub-core/lib/libtasn1/tests/octet-string.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2011-2022 Free Software Foundation, Inc.
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ * Written by Simon Josefsson and Nikos Mavrogiannopoulos
    ++ *
    ++ */
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++
    ++#include "libtasn1.h"
    ++
    ++struct tv
    ++{
    ++  const char *name;
    ++  int der_len;
    ++  const unsigned char *der_str;
    ++  int len;
    ++  const unsigned char *string;
    ++  int expected_error;
    ++  int ber;
    ++};
    ++
    ++static const struct tv tv[] = {
    ++  {.name = "primitive octet strings",
    ++   .der_len = 10,
    ++   .der_str = (void *) "\x04\x08\x01\x23\x45\x67\x89\xab\xcd\xef",
    ++   .len = 8,
    ++   .string = (void *) "\x01\x23\x45\x67\x89\xab\xcd\xef",
    ++   .ber = 0},
    ++  {.der_len = 22,
    ++   .der_str =
    ++   (void *)
    ++   
"\x04\x14\x13\x00\xd9\xa8\x47\xf7\xf2\x1c\xf4\xb0\xec\x5f\xc1\x73\xe5\x1b\x25\xc2\x62\x27",
    ++   .len = 20,
    ++   .string =
    ++   (void *)
    ++   
"\x13\x00\xD9\xA8\x47\xF7\xF2\x1C\xF4\xB0\xEC\x5F\xC1\x73\xE5\x1B\x25\xC2\x62\x27"},
    ++
    ++  {.name = "long type of length",
    ++   .der_len = 23,
    ++   .der_str =
    ++   (void *)
    ++   
"\x04\x81\x14\x13\x00\xd9\xa8\x47\xf7\xf2\x1c\xf4\xb0\xec\x5f\xc1\x73\xe5\x1b\x25\xc2\x62\x27",
    ++   .len = 20,
    ++   .string =
    ++   (void *)
    ++   
"\x13\x00\xD9\xA8\x47\xF7\xF2\x1C\xF4\xB0\xEC\x5F\xC1\x73\xE5\x1B\x25\xC2\x62\x27",
    ++   .ber = 1},
    ++  {.der_len = 11,
    ++   .der_str = (void *) "\x04\x81\x08\x01\x23\x45\x67\x89\xab\xcd\xef",
    ++   .len = 8,
    ++   .string = (void *) "\x01\x23\x45\x67\x89\xab\xcd\xef",
    ++   .ber = 1},
    ++
    ++  {.name = "constructed - indefinite",
    ++   .der_len = 11,
    ++   .der_str = (void *) "\x24\x80\x04\x05\x01\x02\x03\x04\x05\x00\x00",
    ++   .len = 5,
    ++   .string = (void *) "\x01\x02\x03\x04\x05",
    ++   .ber = 1,
    ++   },
    ++
    ++  {.name = "constructed - definite - concat",
    ++   .der_len = 12,
    ++   .der_str = (void *) "\x24\x0a\x04\x04\x0a\x0b\x0c\x0d\x04\x02\x0e\x0f",
    ++   .len = 6,
    ++   .string = (void *) "\x0a\x0b\x0c\x0d\x0e\x0f",
    ++   .ber = 1,
    ++   },
    ++  {.name = "constructed - definite - recursive",
    ++   .der_len = 15,
    ++   .der_str =
    ++   (void *) 
"\x24\x0d\x04\x04\x0a\x0b\x0c\x0d\x24\x05\x04\x00\x04\x01\x0f",
    ++   .len = 5,
    ++   .string = (void *) "\x0a\x0b\x0c\x0d\x0f",
    ++   .ber = 1,
    ++   },
    ++  {.name = "constructed - definite - single",
    ++   .der_len = 7,
    ++   .der_str = (void *) "\x24\x05\x04\x03\x01\x02\x03",
    ++   .len = 3,
    ++   .string = (void *) "\x01\x02\x03",
    ++   .ber = 1,
    ++   },
    ++
    ++  /* a large amount of recursive indefinite encoding */
    ++  {.name = "a large amount of recursive indefinite encoding",
    ++   .der_len = 29325,
    ++   .der_str =
    ++   (void *)
    ++   
"\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80",
    ++   .len = 0,
    ++   .ber = 1,
    ++   .expected_error = ASN1_DER_ERROR}
    ++};
    ++
    ++int
    ++main (int argc, char *argv[])
    ++{
    ++  unsigned char str[100];
    ++  unsigned char der[100];
    ++  int der_len = sizeof (der);
    ++  int str_size = sizeof (str);
    ++  unsigned char *tmp = NULL;
    ++  int ret, ret_len, j;
    ++  size_t i;
    ++
    ++  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
    ++    {
    ++      /* Decode */
    ++
    ++      if (tv[i].ber == 0)
    ++  {
    ++    str_size = sizeof (str);
    ++    ret =
    ++      asn1_get_octet_der (tv[i].der_str + 1,
    ++                          tv[i].der_len - 1, &ret_len, str,
    ++                          sizeof (str), &str_size);
    ++    if (ret != tv[i].expected_error)
    ++      {
    ++        fprintf (stderr,
    ++                 "%d: asn1_get_octet_der: %s: got %d expected %d\n",
    ++                 __LINE__, tv[i].name, ret, tv[i].expected_error);
    ++        return 1;
    ++      }
    ++    if (tv[i].expected_error)
    ++      continue;
    ++
    ++    if (ret_len != tv[i].der_len - 1)
    ++      {
    ++        fprintf (stderr,
    ++                 "%d: error in DER, length returned is %d, had %d\n",
    ++                 __LINE__, ret_len, tv[i].der_len - 1);
    ++        return 1;
    ++      }
    ++
    ++    if (str_size != tv[i].len
    ++        || memcmp (tv[i].string, str, tv[i].len) != 0)
    ++      {
    ++        fprintf (stderr,
    ++                 "%d: memcmp: %s: got invalid decoding\n",
    ++                 __LINE__, tv[i].name);
    ++
    ++        fprintf (stderr, "\nGot:\t\t");
    ++        for (j = 0; j < str_size; j++)
    ++          fprintf (stderr, "%.2x", str[j]);
    ++
    ++        fprintf (stderr, "\nExpected:\t");
    ++        for (j = 0; j < tv[i].len; j++)
    ++          fprintf (stderr, "%.2x", tv[i].string[j]);
    ++        fprintf (stderr, "\n");
    ++        return 1;
    ++      }
    ++
    ++    /* Encode */
    ++    der_len = sizeof (der);
    ++    asn1_octet_der (str, str_size, der, &der_len);
    ++
    ++    if (der_len != tv[i].der_len - 1
    ++        || memcmp (tv[i].der_str + 1, der, tv[i].der_len - 1) != 0)
    ++      {
    ++        fprintf (stderr,
    ++                 "encoding: %s: got invalid encoding\n", tv[i].name);
    ++        return 1;
    ++      }
    ++  }
    ++
    ++      ret =
    ++  asn1_decode_simple_ber (ASN1_ETYPE_OCTET_STRING,
    ++                          tv[i].der_str, tv[i].der_len,
    ++                          &tmp, (unsigned int *) &str_size,
    ++                          (unsigned int *) &der_len);
    ++      if (ret != tv[i].expected_error)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: asn1_decode_simple_ber: %s: got %s expected %s\n",
    ++             __LINE__, tv[i].name, asn1_strerror (ret),
    ++             asn1_strerror (tv[i].expected_error));
    ++    return 1;
    ++  }
    ++      if (tv[i].expected_error)
    ++  continue;
    ++
    ++      if (der_len != tv[i].der_len)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: error: %s: DER, length returned is %d, had %d\n",
    ++             __LINE__, tv[i].name, der_len, tv[i].der_len);
    ++    return 1;
    ++  }
    ++
    ++      if (str_size != tv[i].len || memcmp (tv[i].string, tmp, tv[i].len) 
!= 0)
    ++  {
    ++    fprintf (stderr,
    ++             "%d: memcmp: %s: got invalid decoding\n",
    ++             __LINE__, tv[i].name);
    ++    fprintf (stderr, "\nGot:\t\t");
    ++    for (j = 0; j < str_size; j++)
    ++      fprintf (stderr, "%.2x", tmp[j]);
    ++
    ++    fprintf (stderr, "\nExpected:\t");
    ++    for (j = 0; j < tv[i].len; j++)
    ++      fprintf (stderr, "%.2x", tv[i].string[j]);
    ++    fprintf (stderr, "\n");
    ++    return 1;
    ++  }
    ++      free (tmp);
    ++      tmp = NULL;
    ++
    ++    }
    ++
    ++  return 0;
    ++}
    +
    + ## grub-core/lib/libtasn1/tests/reproducers.c (new) ##
    +@@
    ++/*
    ++ * Copyright (C) 2019-2022 Free Software Foundation, Inc.
    ++ *
    ++ * This file is part of LIBTASN1.
    ++ *
    ++ * This program is free software: you can redistribute it and/or modify
    ++ * it under the terms of the GNU General Public License as published by
    ++ * the Free Software Foundation, either version 3 of the License, or
    ++ * (at your option) any later version.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ * GNU General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public License
    ++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    ++ *
    ++ */
    ++
    ++/****************************************************************/
    ++/* Description: run reproducers for several fixed issues        */
    ++/****************************************************************/
    ++
    ++#include <stdio.h>
    ++#include <string.h>
    ++#include <stdlib.h>
    ++
    ++#include <libtasn1.h>
    ++
    ++#include <int.h>
    ++
    ++/* produces endless loop (fixed by d4b624b2):
    ++ * The following translates into a single node with all pointers
    ++ * (right,left,down) set to NULL. */
    ++const asn1_static_node endless_asn1_tab[] = {
    ++  {"TEST_TREE", 536875024, NULL},
    ++  {NULL, 0, NULL}
    ++};
    ++
    ++/* produces memory leak (fixed by f16d1ff9):
    ++ * 152 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ++ *    at 0x4837B65: calloc (vg_replace_malloc.c:762)
    ++ *    by 0x4851C0D: _asn1_add_static_node (parser_aux.c:71)
    ++ *    by 0x4853AAC: asn1_array2tree (structure.c:200)
    ++ *    by 0x10923B: main (single_node.c:67)
    ++ */
    ++const asn1_static_node tab[] = {
    ++  {"a", CONST_DOWN, ""},
    ++  {"b", 0, ""},
    ++  {"c", 0, ""},
    ++  {NULL, 0, NULL}
    ++};
    ++
    ++int
    ++main (int argc, char *argv[])
    ++{
    ++  int result, verbose = 0;
    ++  asn1_node definitions = NULL;
    ++  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
    ++
    ++  if (argc > 1)
    ++    verbose = 1;
    ++
    ++  result = asn1_array2tree (endless_asn1_tab, &definitions, 
errorDescription);
    ++  if (result != ASN1_SUCCESS)
    ++    {
    ++      asn1_perror (result);
    ++      printf ("ErrorDescription = %s\n\n", errorDescription);
    ++      exit (EXIT_FAILURE);
    ++    }
    ++
    ++  asn1_delete_structure (&definitions);
    ++
    ++  definitions = NULL;
    ++  result = asn1_array2tree (tab, &definitions, errorDescription);
    ++  if (result != ASN1_SUCCESS)
    ++    {
    ++      asn1_perror (result);
    ++      printf ("ErrorDescription = %s\n\n", errorDescription);
    ++      exit (EXIT_FAILURE);
    ++    }
    ++
    ++  asn1_delete_structure (&definitions);
    ++
    ++  if (verbose)
    ++    printf ("Success\n");
    ++
    ++  exit (EXIT_SUCCESS);
    ++}
 3:  4055c72d0 !  3:  1ca207217 libtasn1: disable code not needed in grub
    @@ Metadata
      ## Commit message ##
         libtasn1: disable code not needed in grub
     
    -    Based on the patch from "Daniel Axtens <dja@axtens.net>"
    -
         We don't expect to be able to write ASN.1, only read it,
         so we can disable some code.
     
    @@ Commit message
         which is convenient because it means we don't have to
         import it from gnulib.
     
    +    Signed-off-by: Daniel Axtens <dja@axtens.net>
         Signed-off-by: Gary Lin <glin@suse.com>
    +    Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
     
      ## 
grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.patch
 (new) ##
     @@
    -+From f95a7b9c72fe91e44a90067c9008791a15e490c0 Mon Sep 17 00:00:00 2001
    ++From 6b61d48782dc67bed72af70aa5db5b9cb1b4f1d0 Mon Sep 17 00:00:00 2001
     +From: Daniel Axtens <dja@axtens.net>
     +Date: Fri, 1 May 2020 17:12:23 +1000
    -+Subject: [PATCH 1/3] libtasn1: disable code not needed in grub
    ++Subject: [PATCH 1/6] libtasn1: disable code not needed in grub
     +
     +We don't expect to be able to write ASN.1, only read it,
     +so we can disable some code.
    @@ 
grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.pat
     +which is convenient because it means we don't have to
     +import it from gnulib.
     +
    -+Cc: Vladimir Serbinenko <phcoder@gmail.com>
     +Signed-off-by: Daniel Axtens <dja@axtens.net>
     +Signed-off-by: Gary Lin <glin@suse.com>
     +---
 4:  11cb1c021 !  4:  bf48cf8f8 libtasn1: changes for grub compatibility
    @@ Metadata
     Author: Gary Lin <glin@suse.com>
     
      ## Commit message ##
    -    libtasn1: changes for grub compatibility
    +    libtasn1: use bound-checked _asn1_str_cat()
     
    -    Based on the patch from "Daniel Axtens <dja@axtens.net>"
    -
    -    Do a few things to make libtasn1 compile as part of grub:
    -
    -     - remove _asn1_strcat and replace strcat with the bound-checked
    -       _asn1_str_cat except the one inside _asn1_str_cat. That strcat is
    -       replaced with strcpy.
    -
    -     - adjust header paths in libtasn1.h
    -
    -     - replace a 64 bit division with a call to grub_divmod64, preventing
    -       creation of __udivdi3 calls on 32 bit platforms.
    +    Remove _asn1_strcat() and replace strcat() with the bound-checked
    +    _asn1_str_cat() except the one inside _asn1_str_cat(). That strcat
    +    is replaced with strcpy.
     
    +    Signed-off-by: Daniel Axtens <dja@axtens.net>
         Signed-off-by: Gary Lin <glin@suse.com>
     
    - ## 
grub-core/lib/libtasn1-patches/0002-libtasn1-changes-for-grub-compatibility.patch
 (new) ##
    + ## 
grub-core/lib/libtasn1-patches/0002-libtasn1-use-bound-checked-_asn1_str_cat.patch
 (new) ##
     @@
    -+From 1d62aa76a833855f58261fc69f40bd7763182274 Mon Sep 17 00:00:00 2001
    -+From: Daniel Axtens <dja@axtens.net>
    -+Date: Fri, 1 May 2020 20:44:29 +1000
    -+Subject: [PATCH 2/3] libtasn1: changes for grub compatibility
    -+
    -+Do a few things to make libtasn1 compile as part of grub:
    ++From d87d8e78371e3afbdd876193295ab9e3f60c140b Mon Sep 17 00:00:00 2001
    ++From: Gary Lin <glin@suse.com>
    ++Date: Tue, 25 Jun 2024 16:27:57 +0800
    ++Subject: [PATCH 2/6] libtasn1: use bound-checked _asn1_str_cat()
     +
    -+ - remove _asn1_strcat and replace strcat with the bound-checked
    -+   _asn1_str_cat except the one inside _asn1_str_cat. That strcat is
    -+   replaced with strcpy.
    ++Remove _asn1_strcat() and replace strcat() with the bound-checked
    ++_asn1_str_cat() except the one inside _asn1_str_cat(). That strcat
    ++is replaced with strcpy.
     +
    -+ - adjust header paths in libtasn1.h
    -+
    -+ - replace a 64 bit division with a call to grub_divmod64, preventing
    -+   creation of __udivdi3 calls on 32 bit platforms.
    -+
    -+Cc: Vladimir Serbinenko <phcoder@gmail.com>
     +Signed-off-by: Daniel Axtens <dja@axtens.net>
     +Signed-off-by: Gary Lin <glin@suse.com>
    -+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
     +---
    -+ grub-core/lib/libtasn1-grub/lib/decoding.c   | 8 ++++----
    -+ grub-core/lib/libtasn1-grub/lib/element.c    | 2 +-
    -+ grub-core/lib/libtasn1-grub/lib/gstr.c       | 2 +-
    -+ grub-core/lib/libtasn1-grub/lib/int.h        | 1 -
    -+ grub-core/lib/libtasn1-grub/lib/parser_aux.c | 2 +-
    -+ grub-core/lib/libtasn1-grub/libtasn1.h       | 5 ++---
    -+ 6 files changed, 9 insertions(+), 11 deletions(-)
    ++ grub-core/lib/libtasn1-grub/lib/decoding.c | 8 ++++----
    ++ grub-core/lib/libtasn1-grub/lib/element.c  | 2 +-
    ++ grub-core/lib/libtasn1-grub/lib/gstr.c     | 2 +-
    ++ grub-core/lib/libtasn1-grub/lib/int.h      | 1 -
    ++ 4 files changed, 6 insertions(+), 7 deletions(-)
     +
     +diff --git a/grub-core/lib/libtasn1-grub/lib/decoding.c 
b/grub-core/lib/libtasn1-grub/lib/decoding.c
     +index bf9cb13ac..51859fe36 100644
    @@ -115,7 +115,6 @@ extern const tag_and_class_st _asn1_tags[];
     + 
     + # if SIZEOF_UNSIGNED_LONG_INT == 8
     + #  define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b)
    -+diff --git a/grub-core/lib/libtasn1-grub/lib/parser_aux.c 
b/grub-core/lib/libtasn1-grub/lib/parser_aux.c
    -+index c05bd2339..e4e4c0556 100644
    -+--- a/grub-core/lib/libtasn1-grub/lib/parser_aux.c
    -++++ b/grub-core/lib/libtasn1-grub/lib/parser_aux.c
    -+@@ -632,7 +632,7 @@ _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE])
    -+   count = 0;
    -+   do
    -+     {
    -+-      d = val / 10;
    -++      d = grub_divmod64(val, 10, NULL);
    -+       r = val - d * 10;
    -+       temp[start + count] = '0' + (char) r;
    -+       count++;
    -+diff --git a/grub-core/lib/libtasn1-grub/libtasn1.h 
b/grub-core/lib/libtasn1-grub/libtasn1.h
    -+index 058ab27b0..7d64b6ab7 100644
    -+--- a/grub-core/lib/libtasn1-grub/libtasn1.h
    -++++ b/grub-core/lib/libtasn1-grub/libtasn1.h
    -+@@ -54,9 +54,8 @@
    -+ #  define __LIBTASN1_PURE__
    -+ # endif
    -+ 
    -+-# include <sys/types.h>
    -+-# include <time.h>
    -+-# include <stdio.h>              /* for FILE* */
    -++# include <grub/types.h>
    -++# include <grub/time.h>
    -+ 
    -+ # ifdef __cplusplus
    -+ extern "C"
     +-- 
     +2.35.3
     +
 -:  --------- >  5:  0f93bcdf5 libtasn1: adjust the header paths in libtasn1.h
 -:  --------- >  6:  ab1fdab6f libtasn1: Use grub_divmod64() for division
 5:  ff1aacb5e !  7:  caa413fd4 libtasn1: fix the potential buffer overrun
    @@ Commit message
         libtasn1 issue: https://gitlab.com/gnutls/libtasn1/-/issues/49
     
         Signed-off-by: Gary Lin <glin@suse.com>
    +    Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
     
    - ## 
grub-core/lib/libtasn1-patches/0003-libtasn1-fix-the-potential-buffer-overrun.patch
 (new) ##
    + ## 
grub-core/lib/libtasn1-patches/0005-libtasn1-fix-the-potential-buffer-overrun.patch
 (new) ##
     @@
    -+From 636c1cbfe1e244ba887c6e1a18fabbcb3bb8b1b8 Mon Sep 17 00:00:00 2001
    ++From 38cc5e33cf89ed5d3152923fbedd9869bf566bb5 Mon Sep 17 00:00:00 2001
     +From: Gary Lin <glin@suse.com>
     +Date: Mon, 8 Apr 2024 14:57:21 +0800
    -+Subject: [PATCH 3/3] libtasn1: fix the potential buffer overrun
    ++Subject: [PATCH 5/6] libtasn1: fix the potential buffer overrun
     +
     +In _asn1_tag_der(), the first while loop for the long form may end up
     +with a 'k' value with 'ASN1_MAX_TAG_SIZE' and cause the buffer overrun
 -:  --------- >  8:  28045abf2 asn1_test: changes for grub compatibility
 6:  73dfd01bd !  9:  87b0b3860 libtasn1: compile into asn1 module
    @@ Commit message
     
         Signed-off-by: Daniel Axtens <dja@axtens.net>
         Signed-off-by: Gary Lin <glin@suse.com>
    -    Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
    +    Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
     
      ## autogen.sh ##
     @@ autogen.sh: for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c 
mpih-mul2.c mpih-mul
    @@ autogen.sh: for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c 
mpih-mul
     +
     +for patch in \
     +  0001-libtasn1-disable-code-not-needed-in-grub.patch \
    -+  0002-libtasn1-changes-for-grub-compatibility.patch \
    -+  0003-libtasn1-fix-the-potential-buffer-overrun.patch ; do
    ++  0002-libtasn1-use-bound-checked-_asn1_str_cat.patch \
    ++  0003-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch \
    ++  0004-libtasn1-Use-grub_divmod64-for-division.patch \
    ++  0005-libtasn1-fix-the-potential-buffer-overrun.patch ; do
     +  patch -p1 -i grub-core/lib/libtasn1-patches/$patch
     +done
     +
    @@ grub-core/Makefile.core.def: module = {
     +  common = lib/libtasn1-grub/lib/errors.c;
     +  common = lib/libtasn1_wrap/wrap.c;
     +  cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
    -+  // -Wno-type-limits comes from libtasn1's configure.ac
    ++  /* -Wno-type-limits comes from configure.ac of libtasn1 */
     +  cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) 
-I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/lib/libtasn1-grub/lib 
-Wno-type-limits';
     +};
     
    @@ grub-core/lib/libtasn1_wrap/wrap.c (new)
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2020 IBM Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ grub-core/lib/libtasn1_wrap/wrap.c (new)
     +
     +/*
     + * libtasn1 is provided under LGPL2.1+, which is compatible
    -+ * with GPL3+. As Grub as a whole is under GPL3+, this module
    ++ * with GPL3+. As GRUB as a whole is under GPL3+, this module
     + * is therefore under GPL3+ also.
     + */
     +GRUB_MOD_LICENSE ("GPLv3+");
 7:  6dbd9060f <  -:  --------- asn1_test: test module for libtasn1
 -:  --------- > 10:  6e39c7766 asn1_test: test module for libtasn1
 8:  a0b370b0b ! 11:  5a8b24309 libtasn1: Add the documentation
    @@ docs/grub-dev.texi: cp minilzo-2.10/*.[hc] grub-core/lib/minilzo
     +tar xf libtasn1-4.19.0.tar.gz
     +rm -rf grub-core/lib/libtasn1/
     +mkdir -p grub-core/lib/libtasn1/lib/
    ++mkdir -p grub-core/lib/libtasn1/tests/
     +cp libtasn1-4.19.0/@lbracechar{}README.md,COPYING@rbracechar{} 
grub-core/lib/libtasn1/
     +cp 
libtasn1-4.19.0/lib/@lbracechar{}coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h@rbracechar{}
 grub-core/lib/libtasn1/lib/
     +cp libtasn1-4.19.0/lib/includes/libtasn1.h grub-core/lib/libtasn1/
    ++cp 
libtasn1-4.19.0/tests/@lbracechar{}CVE-2018-1000654-1_asn1_tab.h,CVE-2018-1000654-2_asn1_tab.h,CVE-2018-1000654.c,object-id-decoding.c,object-id-encoding.c,octet-string.c,reproducers.c,Test_overflow.c,Test_simple.c,Test_strings.c@rbracechar{}
 grub-core/lib/libtasn1/tests
     +rm -rf libtasn1-4.19.0*
     +@end example
     +
     +After upgrading the library, it may be necessary to apply the patches in
     +@file{grub-core/lib/libtasn1-patches/} to adjust the code to be 
compatible with
    -+grub. These patches were needed to use the current version of libtasn1. 
The
    ++GRUB. These patches were needed to use the current version of libtasn1. 
The
     +existing patches may not apply cleanly, apply at all, or even be needed 
for a
    -+newer version of the library, and other patches maybe needed due to 
changes in
    ++newer version of the library, and other patches may be needed due to 
changes in
     +the newer version. If existing patches need to be refreshed to apply 
cleanly,
     +please include updated patches as part of the a patch set sent to the 
list.
     +If new patches are needed or existing patches are not needed, also please 
send
 9:  46f29445b ! 12:  3059a8df6 key_protector: Add key protectors framework
    @@ Commit message
         Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
         Signed-off-by: Gary Lin <glin@suse.com>
         Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
    +    Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
     
      ## grub-core/Makefile.am ##
     @@ grub-core/Makefile.am: endif
    @@ grub-core/disk/key_protector.c (new)
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ include/grub/key_protector.h (new)
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
 -:  --------- > 13:  584346494 tss2: Add TPM2 buffer handling functions
10:  ba02aa532 ! 14:  c2c071d9c tpm2: Add TPM Software Stack (TSS)
    @@
      ## Metadata ##
    -Author: Hernan Gatta <hegatta@linux.microsoft.com>
    +Author: Gary Lin <glin@suse.com>
     
      ## Commit message ##
    -    tpm2: Add TPM Software Stack (TSS)
    +    tss2: Add TPM2 types and Marshal/Unmarshal functions
     
    -    A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to
    -    compose and submit TPM commands and parse reponses.
    -
    -    A limited number of TPM commands may be accessed via the EFI TCG2
    -    protocol. This protocol exposes functionality that is primarily geared
    -    toward TPM usage within the context of Secure Boot. For all other TPM
    -    commands, however, such as sealing and unsealing, this protocol does 
not
    -    provide any help, with the exception of passthrough command submission.
    -
    -    The SubmitCommand method allows a caller to send raw commands to the
    -    system's TPM and to receive the corresponding response. These
    -    command/response pairs are formatted using the TPM wire protocol. To
    -    construct commands in this way, and to parse the TPM's response, it is
    -    necessary to, first, possess knowledge of the various TPM structures, 
and,
    -    second, of the TPM wire protocol itself.
    -
    -    As such, this patch includes a set of header files that define the
    -    necessary TPM structures and TSS functions, implementations of various
    -    TPM2_* functions (inventoried below), and logic to write and read 
command
    -    and response buffers, respectively, using the TPM wire protocol.
    -
    -    Functions: TPM2_Create, TPM2_CreatePrimary, TPM2_EvictControl,
    -    TPM2_FlushContext, TPM2_Load, TPM2_PCR_Read, TPM2_PolicyGetDigest,
    -    TPM2_PolicyPCR, TPM2_ReadPublic, TPM2_StartAuthSession, TPM2_Unseal,
    -    TPM2_LoadExternal, TPM2_Hash, TPM2_VerifySignature,
    -    TPM2_PolicyAuthorize, TPM2_TestParms
    +    This commit adds the necessary TPM2 types and structs as the 
preparation
    +    for the TPM2 Software Stack (TSS2) support. The Marshal/Unmarshal
    +    functions are also added to handle the data structure to be submitted 
to
    +    TPM2 commands and to be received from the response.
     
    +    Cc: Stefan Berger <stefanb@linux.ibm.com>
         Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
         Signed-off-by: Gary Lin <glin@suse.com>
    -    Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
     
    - ## grub-core/tpm2/buffer.c (new) ##
    + ## grub-core/lib/tss2/tss2_mu.c (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ grub-core/tpm2/buffer.c (new)
     + */
     +
     +#include <grub/misc.h>
    -+#include <grub/tpm2/buffer.h>
    -+
    -+void grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer)
    -+{
    -+  grub_memset (buffer->data, 0xDD, sizeof (buffer->data));
    -+  buffer->size = 0;
    -+  buffer->offset = 0;
    -+  buffer->cap = sizeof (buffer->data);
    -+  buffer->error = 0;
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void* data,
    -+                 grub_size_t size)
    -+{
    -+  grub_uint32_t r = buffer->cap - buffer->size;
    -+
    -+  if (buffer->error)
    -+    return;
    -+
    -+  if (size > r)
    -+    {
    -+      buffer->error = 1;
    -+      return;
    -+    }
    -+
    -+  grub_memcpy (&buffer->data[buffer->size], (void*) data, size);
    -+  buffer->size += size;
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value)
    -+{
    -+  grub_tpm2_buffer_pack (buffer, (const char*) &value, sizeof (value));
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value)
    -+{
    -+  grub_uint16_t tmp = grub_cpu_to_be16 (value);
    -+  grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp));
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value)
    -+{
    -+  grub_uint32_t tmp = grub_cpu_to_be32 (value);
    -+  grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp));
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void* data,
    -+                   grub_size_t size)
    -+{
    -+  grub_uint32_t r = buffer->size - buffer->offset;
    -+
    -+  if (buffer->error)
    -+    return;
    -+
    -+  if (size > r)
    -+    {
    -+      buffer->error = 1;
    -+      return;
    -+    }
    -+
    -+  grub_memcpy (data, &buffer->data[buffer->offset], size);
    -+  buffer->offset += size;
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t* 
value)
    -+{
    -+  grub_uint32_t r = buffer->size - buffer->offset;
    -+
    -+  if (buffer->error)
    -+    return;
    -+
    -+  if (sizeof (*value) > r)
    -+    {
    -+      buffer->error = 1;
    -+      return;
    -+    }
    -+
    -+  grub_memcpy (value, &buffer->data[buffer->offset], sizeof (*value));
    -+  buffer->offset += sizeof (*value);
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t* 
value)
    -+{
    -+  grub_uint16_t tmp;
    -+  grub_uint32_t r = buffer->size - buffer->offset;
    -+
    -+  if (buffer->error)
    -+    return;
    -+
    -+  if (sizeof (tmp) > r)
    -+    {
    -+      buffer->error = 1;
    -+      return;
    -+    }
    -+
    -+  grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp));
    -+  buffer->offset += sizeof (tmp);
    -+  *value = grub_be_to_cpu16 (tmp);
    -+}
    -+
    -+void
    -+grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t* 
value)
    -+{
    -+  grub_uint32_t tmp;
    -+  grub_uint32_t r = buffer->size - buffer->offset;
    -+
    -+  if (buffer->error)
    -+    return;
    -+
    -+  if (sizeof (tmp) > r)
    -+    {
    -+      buffer->error = 1;
    -+      return;
    -+    }
    -+
    -+  grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp));
    -+  buffer->offset += sizeof (tmp);
    -+  *value = grub_be_to_cpu32 (tmp);
    -+}
    -
    - ## grub-core/tpm2/mu.c (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
     +
    -+#include <grub/misc.h>
    -+#include <grub/tpm2/mu.h>
    ++#include <tss2_mu.h>
     +
     +void
    -+grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer,
     +                                  const TPMS_AUTH_COMMAND* authCommand)
     +{
     +  grub_uint32_t start;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
     +                      const grub_uint16_t size,
     +                      const grub_uint8_t* b)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer,
     +                                  const TPMI_ALG_SYM_OBJECT algorithm,
     +                                  const TPMU_SYM_KEY_BITS *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
     +                              const TPMI_ALG_SYM_OBJECT algorithm,
     +                              const TPMU_SYM_MODE *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer,
     +                             const TPMT_SYM_DEF *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->algorithm);
    -+  grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, 
&p->keyBits);
    -+  grub_tpm2_mu_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode);
    ++  grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, 
&p->keyBits);
    ++  grub_Tss2_MU_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
     +                                   const TPMS_PCR_SELECTION* pcrSelection)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, pcrSelection->hash);
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
     +                                   const TPML_PCR_SELECTION* pcrSelection)
     +{
     +  grub_tpm2_buffer_pack_u32 (buffer, pcrSelection->count);
     +
     +  for (grub_uint32_t i = 0; i < pcrSelection->count; i++)
    -+    grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (buffer,
    ++    grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (buffer,
     +                                       &pcrSelection->pcrSelections[i]);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
     +                            const TPMA_OBJECT *p)
     +{
     +  grub_tpm2_buffer_pack_u32 (buffer, *((const grub_uint32_t*) p));
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer,
     +                                const TPMS_SCHEME_XOR *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer,
     +                                 const TPMS_SCHEME_HMAC *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer,
     +                                      const TPMI_ALG_KEYEDHASH_SCHEME 
scheme,
     +                                      const TPMU_SCHEME_KEYEDHASH *p)
     +{
     +  switch (scheme)
     +    {
     +    case TPM_ALG_HMAC:
    -+      grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (buffer, &p->hmac);
    ++      grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (buffer, &p->hmac);
     +      break;
     +    case TPM_ALG_XOR:
    -+      grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (buffer, &p->exclusiveOr);
    ++      grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (buffer, &p->exclusiveOr);
     +      break;
     +    case TPM_ALG_NULL:
     +      break;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
     +                                      const TPMT_KEYEDHASH_SCHEME *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
    -+  grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (buffer, p->scheme, 
&p->details);
    ++  grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (buffer, p->scheme, 
&p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer,
     +                                     const TPMS_KEYEDHASH_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme);
    ++  grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
     +                                    const TPMT_SYM_DEF_OBJECT *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->algorithm);
    -+  grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, 
&p->keyBits);
    -+  grub_tpm2_mu_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode);
    ++  grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, 
&p->keyBits);
    ++  grub_Tss2_MU_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
     +                                 const TPMI_ALG_RSA_DECRYPT scheme,
     +                                 const TPMU_ASYM_SCHEME *p __attribute__ 
((unused)))
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
     +                                const TPMT_RSA_SCHEME *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
    -+  grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details);
    ++  grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer,
     +                               const TPMS_RSA_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric);
    -+  grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (buffer, &p->scheme);
    ++  grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric);
    ++  grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (buffer, &p->scheme);
     +  grub_tpm2_buffer_pack_u16 (buffer, p->keyBits);
     +  grub_tpm2_buffer_pack_u32 (buffer, p->exponent);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer,
     +                                     const TPMS_SYMCIPHER_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->sym);
    ++  grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->sym);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
     +                                const TPMT_ECC_SCHEME *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
    -+  grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details);
    ++  grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
     +                                const TPMI_ALG_KDF scheme,
     +                                const TPMU_KDF_SCHEME *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
     +                                const TPMT_KDF_SCHEME *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->scheme);
    -+  grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (buffer, p->scheme, &p->details);
    ++  grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (buffer, p->scheme, &p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
     +                               const TPMS_ECC_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric);
    -+  grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (buffer, &p->scheme);
    ++  grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric);
    ++  grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (buffer, &p->scheme);
     +  grub_tpm2_buffer_pack_u16 (buffer, p->curveID);
    -+  grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (buffer, &p->kdf);
    ++  grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (buffer, &p->kdf);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
     +                                  const grub_uint32_t type,
     +                                  const TPMU_PUBLIC_PARMS *p)
     +{
     +  switch (type)
     +    {
     +    case TPM_ALG_KEYEDHASH:
    -+      grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (buffer, 
&p->keyedHashDetail);
    ++      grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (buffer, 
&p->keyedHashDetail);
     +      break;
     +    case TPM_ALG_SYMCIPHER:
    -+      grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (buffer, &p->symDetail);
    ++      grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (buffer, &p->symDetail);
     +      break;
     +    case TPM_ALG_RSA:
    -+      grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (buffer, &p->rsaDetail);
    ++      grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (buffer, &p->rsaDetail);
     +      break;
     +    case TPM_ALG_ECC:
    -+      grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (buffer, &p->eccDetail);
    ++      grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (buffer, &p->eccDetail);
     +      break;
     +    default:
     +      buffer->error = 1;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer,
     +                               const TPMS_ECC_POINT *p)
     +{
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->x.size, p->x.buffer);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->y.size, p->y.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->x.size, p->x.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->y.size, p->y.buffer);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer,
     +                               const TPMI_ALG_PUBLIC type,
     +                               const TPMU_PUBLIC_ID *p)
     +{
     +  switch(type)
     +    {
     +    case TPM_ALG_KEYEDHASH:
    -+      grub_tpm2_mu_TPM2B_Marshal (buffer, p->keyedHash.size,
    ++      grub_Tss2_MU_TPM2B_Marshal (buffer, p->keyedHash.size,
     +                            p->keyedHash.buffer);
     +      break;
     +    case TPM_ALG_SYMCIPHER:
    -+      grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer);
    ++      grub_Tss2_MU_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer);
     +      break;
     +    case TPM_ALG_RSA:
    -+      grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer);
    ++      grub_Tss2_MU_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer);
     +      break;
     +    case TPM_ALG_ECC:
    -+      grub_tpm2_mu_TPMS_ECC_POINT_Marshal (buffer, &p->ecc);
    ++      grub_Tss2_MU_TPMS_ECC_POINT_Marshal (buffer, &p->ecc);
     +      break;
     +    default:
     +      buffer->error = 1;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
     +                                  const TPMT_PUBLIC_PARMS *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->type);
    -+  grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, 
&p->parameters);
    ++  grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, 
&p->parameters);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
     +                            const TPMT_PUBLIC *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->type);
     +  grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg);
    -+  grub_tpm2_mu_TPMA_OBJECT_Marshal (buffer, &p->objectAttributes);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->authPolicy.size, 
p->authPolicy.buffer);
    -+  grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, 
&p->parameters);
    -+  grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (buffer, p->type, &p->unique);
    ++  grub_Tss2_MU_TPMA_OBJECT_Marshal (buffer, &p->objectAttributes);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->authPolicy.size, 
p->authPolicy.buffer);
    ++  grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, 
&p->parameters);
    ++  grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (buffer, p->type, &p->unique);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
     +                             const TPM2B_PUBLIC *p)
     +{
     +  grub_uint32_t start;
    @@ grub-core/tpm2/mu.c (new)
     +      grub_tpm2_buffer_pack_u16 (buffer, p->size);
     +
     +      start = buffer->size;
    -+      grub_tpm2_mu_TPMT_PUBLIC_Marshal (buffer, &p->publicArea);
    ++      grub_Tss2_MU_TPMT_PUBLIC_Marshal (buffer, &p->publicArea);
     +      size = grub_cpu_to_be16 (buffer->size - start);
     +      grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size,
     +             sizeof (size));
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
     +                                      const TPMS_SENSITIVE_CREATE *p)
     +{
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->userAuth.size, 
p->userAuth.buffer);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->data.size, p->data.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->userAuth.size, 
p->userAuth.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->data.size, p->data.buffer);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer,
     +                                               const TPMI_ALG_PUBLIC type,
     +                                               const 
TPMU_SENSITIVE_COMPOSITE *p)
     +{
     +  switch(type)
     +    {
     +    case TPM_ALG_RSA:
    -+      grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer);
    ++      grub_Tss2_MU_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer);
     +      break;
     +    case TPM_ALG_ECC:
    -+      grub_tpm2_mu_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer);
    ++      grub_Tss2_MU_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer);
     +      break;
     +    case TPM_ALG_KEYEDHASH:
    -+      grub_tpm2_mu_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer);
    ++      grub_Tss2_MU_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer);
     +      break;
     +    case TPM_ALG_SYMCIPHER:
    -+      grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer);
    ++      grub_Tss2_MU_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer);
     +      break;
     +    default:
     +      buffer->error = 1;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
     +                                     const TPMT_SENSITIVE *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->sensitiveType);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->authValue.size, 
p->authValue.buffer);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->seedValue.size, 
p->seedValue.buffer);
    -+  grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType,
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->authValue.size, 
p->authValue.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->seedValue.size, 
p->seedValue.buffer);
    ++  grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType,
     +                                                 &p->sensitive);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
     +                                      const TPM2B_SENSITIVE *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->size);
    -+  grub_tpm2_mu_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea);
    ++  grub_Tss2_MU_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
     +                                       const TPM2B_SENSITIVE_CREATE 
*sensitiveCreate)
     +{
     +  grub_uint32_t start;
    @@ grub-core/tpm2/mu.c (new)
     +    {
     +      grub_tpm2_buffer_pack_u16 (buffer, sensitiveCreate->size);
     +      start = buffer->size;
    -+      grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (buffer,
    ++      grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (buffer,
     +                                            &sensitiveCreate->sensitive);
     +      size = grub_cpu_to_be16 (buffer->size - start);
     +
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer,
     +                                         const TPMS_SIGNATURE_RSA *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->hash);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer,
     +                                         const TPMS_SIGNATURE_ECC *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->hash);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureR.size, 
p->signatureR.buffer);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureS.size, 
p->signatureS.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->signatureR.size, 
p->signatureR.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->signatureS.size, 
p->signatureS.buffer);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer,
     +                              const TPMI_ALG_HASH hashAlg,
     +                              const TPMU_HA *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer,
     +                              const TPMT_HA *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
    -+  grub_tpm2_mu_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest);
    ++  grub_Tss2_MU_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
     +                                     const TPMI_ALG_SIG_SCHEME sigAlg,
     +                                     const TPMU_SIGNATURE *p)
     +{
     +  switch (sigAlg)
     +    {
     +    case TPM_ALG_RSASSA:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsassa);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsassa);
     +      break;
     +    case TPM_ALG_RSAPSS:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsapss);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsapss);
     +      break;
     +    case TPM_ALG_ECDSA:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdsa);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdsa);
     +      break;
     +    case TPM_ALG_ECDAA:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdaa);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdaa);
     +      break;
     +    case TPM_ALG_SM2:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->sm2);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->sm2);
     +      break;
     +    case TPM_ALG_ECSCHNORR:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecschnorr);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecschnorr);
     +      break;
     +    case TPM_ALG_HMAC:
    -+      grub_tpm2_mu_TPMT_HA_Marshal (buffer, &p->hmac);
    ++      grub_Tss2_MU_TPMT_HA_Marshal (buffer, &p->hmac);
     +      break;
     +    case TPM_ALG_NULL:
     +      break;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
     +                                     const TPMT_SIGNATURE *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->sigAlg);
    -+  grub_tpm2_mu_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature);
    ++  grub_Tss2_MU_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer,
     +                                       const TPMT_TK_VERIFIED *p)
     +{
     +  grub_tpm2_buffer_pack_u16 (buffer, p->tag);
     +  grub_tpm2_buffer_pack_u32 (buffer, p->hierarchy);
    -+  grub_tpm2_mu_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer);
    ++  grub_Tss2_MU_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer);
     +}
     +
     +static void
    -+__tpm2_mu_TPM2B_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer,
    ++__Tss2_MU_TPM2B_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer,
     +                            TPM2B* p, grub_uint16_t bound)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->size);
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +#define TPM2B_BUFFER_UNMARSHAL(buffer, type, data) \
    -+  __tpm2_mu_TPM2B_BUFFER_Unmarshal(buffer, (TPM2B *)data, sizeof(type) - 
sizeof(grub_uint16_t))
    ++  __Tss2_MU_TPM2B_BUFFER_Unmarshal(buffer, (TPM2B *)data, sizeof(type) - 
sizeof(grub_uint16_t))
     +
     +void
    -+grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                     TPMS_AUTH_RESPONSE* p)
     +{
     +  grub_uint8_t tmp;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
     +                               TPM2B_DIGEST* digest)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DIGEST, digest);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer,
     +                              TPM2B_NONCE* nonce)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NONCE, nonce);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                             TPM2B_DATA* data)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DATA, data);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                     TPMS_CREATION_DATA *data)
     +{
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (buffer, &data->pcrSelect);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &data->pcrDigest);
    ++  grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (buffer, &data->pcrSelect);
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &data->pcrDigest);
     +  grub_tpm2_buffer_unpack_u8 (buffer, (grub_uint8_t *)&data->locality);
     +  grub_tpm2_buffer_unpack_u16 (buffer, &data->parentNameAlg);
    -+  grub_tpm2_mu_TPM2B_NAME_Unmarshal (buffer, &data->parentName);
    -+  grub_tpm2_mu_TPM2B_NAME_Unmarshal (buffer, &data->parentQualifiedName);
    -+  grub_tpm2_mu_TPM2B_DATA_Unmarshal (buffer, &data->outsideInfo);
    ++  grub_Tss2_MU_TPM2B_NAME_Unmarshal (buffer, &data->parentName);
    ++  grub_Tss2_MU_TPM2B_NAME_Unmarshal (buffer, &data->parentQualifiedName);
    ++  grub_Tss2_MU_TPM2B_DATA_Unmarshal (buffer, &data->outsideInfo);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                      TPM2B_CREATION_DATA *data)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &data->size);
    -+  grub_tpm2_mu_TPMS_CREATION_DATA_Unmarshal (buffer, &data->creationData);
    ++  grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (buffer, &data->creationData);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                TPM2B_PRIVATE *private)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PRIVATE, private);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                       TPM2B_SENSITIVE_DATA *data)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_SENSITIVE_DATA, data);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                       TPM2B_PUBLIC_KEY_RSA *rsa)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PUBLIC_KEY_RSA, rsa);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                      TPM2B_ECC_PARAMETER *param)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_ECC_PARAMETER, param);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
     +                              TPMA_OBJECT *p)
     +{
     +  grub_tpm2_buffer_unpack_u32 (buffer, (grub_uint32_t*)p);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                   TPMS_SCHEME_HMAC *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                  TPMS_SCHEME_XOR *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg);
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                        TPMI_ALG_KEYEDHASH_SCHEME scheme,
     +                                        TPMU_SCHEME_KEYEDHASH *p)
     +{
     +  switch (scheme)
     +    {
     +    case TPM_ALG_HMAC:
    -+      grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (buffer, &p->hmac);
    ++      grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (buffer, &p->hmac);
     +      break;
     +    case TPM_ALG_XOR:
    -+      grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (buffer, &p->exclusiveOr);
    ++      grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (buffer, &p->exclusiveOr);
     +      break;
     +    case TPM_ALG_NULL:
     +      break;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                        TPMT_KEYEDHASH_SCHEME *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme);
    -+  grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (buffer, p->scheme, 
&p->details);
    ++  grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (buffer, p->scheme, 
&p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                       TPMS_KEYEDHASH_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (buffer, &p->scheme);
    ++  grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (buffer, &p->scheme);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                    TPMI_ALG_SYM_OBJECT algorithm,
     +                                    TPMU_SYM_KEY_BITS *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                TPMI_ALG_SYM_OBJECT algorithm,
     +                                TPMU_SYM_MODE *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                      TPMT_SYM_DEF_OBJECT *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->algorithm);
    -+  grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (buffer, p->algorithm, 
&p->keyBits);
    -+  grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (buffer, p->algorithm, &p->mode);
    ++  grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (buffer, p->algorithm, 
&p->keyBits);
    ++  grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (buffer, p->algorithm, &p->mode);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                       TPMS_SYMCIPHER_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->sym);
    ++  grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->sym);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                   TPMI_ALG_RSA_DECRYPT scheme,
     +                                   TPMU_ASYM_SCHEME *p 
__attribute__((unused)))
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                  TPMT_RSA_SCHEME *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme);
    -+  grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, 
&p->details);
    ++  grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, 
&p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                 TPMS_RSA_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric);
    -+  grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (buffer, &p->scheme);
    ++  grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric);
    ++  grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (buffer, &p->scheme);
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->keyBits);
     +  grub_tpm2_buffer_unpack_u32 (buffer, &p->exponent);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                  TPMT_ECC_SCHEME *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme);
    -+  grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, 
&p->details);
    ++  grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, 
&p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                  TPMI_ALG_KDF scheme,
     +                                  TPMU_KDF_SCHEME *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                  TPMT_KDF_SCHEME *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme);
    -+  grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (buffer, p->scheme, &p->details);
    ++  grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (buffer, p->scheme, &p->details);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                 TPMS_ECC_PARMS *p)
     +{
    -+  grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric);
    -+  grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (buffer, &p->scheme );
    ++  grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric);
    ++  grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (buffer, &p->scheme );
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->curveID);
    -+  grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (buffer, &p->kdf);
    ++  grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (buffer, &p->kdf);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                    grub_uint32_t type,
     +                                    TPMU_PUBLIC_PARMS *p)
     +{
     +  switch (type)
     +    {
     +    case TPM_ALG_KEYEDHASH:
    -+      grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (buffer, 
&p->keyedHashDetail);
    ++      grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (buffer, 
&p->keyedHashDetail);
     +      break;
     +    case TPM_ALG_SYMCIPHER:
    -+      grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (buffer, &p->symDetail);
    ++      grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (buffer, &p->symDetail);
     +      break;
     +    case TPM_ALG_RSA:
    -+      grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (buffer, &p->rsaDetail);
    ++      grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (buffer, &p->rsaDetail);
     +      break;
     +    case TPM_ALG_ECC:
    -+      grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (buffer, &p->eccDetail);
    ++      grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (buffer, &p->eccDetail);
     +      break;
     +    default:
     +      buffer->error = 1;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                 TPMS_ECC_POINT *p)
     +{
    -+  grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->x);
    -+  grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->y);
    ++  grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->x);
    ++  grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->y);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                 TPMI_ALG_PUBLIC type,
     +                                 TPMU_PUBLIC_ID *p)
     +{
     +  switch(type)
     +    {
     +    case TPM_ALG_KEYEDHASH:
    -+      grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->keyedHash);
    ++      grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->keyedHash);
     +      break;
     +    case TPM_ALG_SYMCIPHER:
    -+      grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->sym);
    ++      grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->sym);
     +      break;
     +    case TPM_ALG_RSA:
    -+      grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &p->rsa);
    ++      grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &p->rsa);
     +      break;
     +    case TPM_ALG_ECC:
    -+      grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (buffer, &p->ecc);
    ++      grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (buffer, &p->ecc);
     +      break;
     +    default:
     +      buffer->error = 1;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
     +                              TPMT_PUBLIC *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->type);
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg);
    -+  grub_tpm2_mu_TPMA_OBJECT_Unmarshal (buffer, &p->objectAttributes);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy);
    -+  grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (buffer, p->type, 
&p->parameters);
    -+  grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (buffer, p->type, &p->unique);
    ++  grub_Tss2_MU_TPMA_OBJECT_Unmarshal (buffer, &p->objectAttributes);
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy);
    ++  grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (buffer, p->type, 
&p->parameters);
    ++  grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (buffer, p->type, &p->unique);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
     +                               TPM2B_PUBLIC *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->size);
    -+  grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (buffer, &p->publicArea);
    ++  grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (buffer, &p->publicArea);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                 TPMS_NV_PUBLIC *p)
     +{
     +  grub_tpm2_buffer_unpack_u32 (buffer, &p->nvIndex);
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg);
     +  grub_tpm2_buffer_unpack_u32 (buffer, &p->attributes);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy);
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy);
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->dataSize);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                  TPM2B_NV_PUBLIC *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->size);
    -+  grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (buffer, &p->nvPublic);
    ++  grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (buffer, &p->nvPublic);
     +}
     +
     +void
    -+grub_tpm2_mu_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer,
     +                             TPM2B_NAME *n)
     +{
     +  TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NAME, n);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                       TPMS_TAGGED_PROPERTY* property)
     +{
     +  grub_tpm2_buffer_unpack_u32 (buffer, &property->property);
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                   TPMT_TK_CREATION *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->tag);
     +  grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->digest);
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                          TPMT_TK_HASHCHECK *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->tag);
     +  grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->digest);
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                         TPMT_TK_VERIFIED *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->tag);
     +  grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->digest);
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                     TPMS_PCR_SELECTION* pcrSelection)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &pcrSelection->hash);
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                     TPML_PCR_SELECTION* pcrSelection)
     +{
     +  grub_tpm2_buffer_unpack_u32 (buffer, &pcrSelection->count);
    @@ grub-core/tpm2/mu.c (new)
     +    }
     +
     +  for (grub_uint32_t i = 0; i < pcrSelection->count; i++)
    -+    grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (buffer, 
&pcrSelection->pcrSelections[i]);
    ++    grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (buffer, 
&pcrSelection->pcrSelections[i]);
     +}
     +
     +void
    -+grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
     +                              TPML_DIGEST* digest)
     +{
     +  grub_tpm2_buffer_unpack_u32 (buffer, &digest->count);
    @@ grub-core/tpm2/mu.c (new)
     +    }
     +
     +  for (grub_uint32_t i = 0; i < digest->count; i++)
    -+    grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &digest->digests[i]);
    ++    grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &digest->digests[i]);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                           TPMS_SIGNATURE_RSA *rsa)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &rsa->hash);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &rsa->sig);
    ++  grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &rsa->sig);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                           TPMS_SIGNATURE_ECC *ecc)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &ecc->hash);
    -+  grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureR);
    -+  grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureS);
    ++  grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureR);
    ++  grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureS);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                TPMI_ALG_HASH hashAlg,
     +                                TPMU_HA *p)
     +{
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                TPMT_HA *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg);
    -+  grub_tpm2_mu_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest);
    ++  grub_Tss2_MU_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest);
     +}
     +
     +void
    -+grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                       TPMI_ALG_SIG_SCHEME sigAlg,
     +                                       TPMU_SIGNATURE *p)
     +{
     +  switch (sigAlg)
     +    {
     +    case TPM_ALG_RSASSA:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsassa);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsassa);
     +      break;
     +    case TPM_ALG_RSAPSS:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsapss);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (buffer, 
(TPMS_SIGNATURE_RSA *)&p->rsapss);
     +      break;
     +    case TPM_ALG_ECDSA:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdsa);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdsa);
     +      break;
     +    case TPM_ALG_ECDAA:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdaa);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecdaa);
     +      break;
     +    case TPM_ALG_SM2:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->sm2);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->sm2);
     +      break;
     +    case TPM_ALG_ECSCHNORR:
    -+      grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecschnorr);
    ++      grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, 
(TPMS_SIGNATURE_ECC *)&p->ecschnorr);
     +      break;
     +    case TPM_ALG_HMAC:
    -+      grub_tpm2_mu_TPMT_HA_Unmarshal (buffer, &p->hmac);
    ++      grub_Tss2_MU_TPMT_HA_Unmarshal (buffer, &p->hmac);
     +      break;
     +    case TPM_ALG_NULL:
     +      break;
    @@ grub-core/tpm2/mu.c (new)
     +}
     +
     +void
    -+grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
     +                                       TPMT_SIGNATURE *p)
     +{
     +  grub_tpm2_buffer_unpack_u16 (buffer, &p->sigAlg);
    -+  grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, 
&p->signature);
    ++  grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, 
&p->signature);
     +}
     
    - ## grub-core/tpm2/tcg2.c (new) ##
    + ## grub-core/lib/tss2/tss2_mu.h (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ grub-core/tpm2/tcg2.c (new)
     + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
     + */
     +
    -+#include <grub/efi/api.h>
    -+#include <grub/efi/efi.h>
    -+#include <grub/efi/tpm.h>
    -+#include <grub/mm.h>
    -+#include <grub/tpm2/tcg2.h>
    ++#ifndef GRUB_TPM2_MU_HEADER
    ++#define GRUB_TPM2_MU_HEADER 1
     +
    -+static grub_err_t
    -+grub_tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2,
    -+              grub_size_t *max_output_size)
    -+{
    -+  grub_efi_status_t status;
    ++#include <tss2_buffer.h>
    ++#include <tss2_structs.h>
     +
    -+  static int has_caps = 0;
    -+  static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps =
    -+  {
    -+    .Size = (grub_uint8_t) sizeof (caps)
    -+  };
    ++void
    ++grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer,
    ++                                  const TPMS_AUTH_COMMAND* authCommand);
     +
    -+  if (has_caps)
    -+    goto exit;
    ++void
    ++grub_Tss2_MU_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
    ++                      const grub_uint16_t size,
    ++                      const grub_uint8_t* b);
     +
    -+  status = protocol->get_capability (protocol, &caps);
    -+  if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
    -+    return GRUB_ERR_FILE_NOT_FOUND;
    ++void
    ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer,
    ++                                  const TPMI_ALG_SYM_OBJECT algorithm,
    ++                                  const TPMU_SYM_KEY_BITS *p);
     +
    -+  has_caps = 1;
    ++void
    ++grub_Tss2_MU_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
    ++                              const TPMI_ALG_SYM_OBJECT algorithm,
    ++                              const TPMU_SYM_MODE *p);
     +
    -+exit:
    -+  if (tpm2)
    -+    *tpm2 = caps.TPMPresentFlag;
    -+  if (max_output_size)
    -+    *max_output_size = caps.MaxResponseSize;
    ++void
    ++grub_Tss2_MU_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer,
    ++                             const TPMT_SYM_DEF *p);
     +
    -+  return GRUB_ERR_NONE;
    -+}
    ++void
    ++grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
    ++                                   const TPMS_PCR_SELECTION* 
pcrSelection);
     +
    -+static grub_err_t
    -+grub_tcg2_get_protocol (grub_efi_tpm2_protocol_t **protocol)
    -+{
    -+  static grub_guid_t tpm2_guid = EFI_TPM2_GUID;
    -+  static grub_efi_tpm2_protocol_t *tpm2_protocol = NULL;
    ++void
    ++grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
    ++                                   const TPML_PCR_SELECTION* 
pcrSelection);
     +
    -+  int tpm2;
    -+  grub_efi_handle_t *handles;
    -+  grub_efi_uintn_t num_handles;
    -+  grub_efi_handle_t tpm2_handle;
    -+  grub_err_t err = GRUB_ERR_FILE_NOT_FOUND;
    ++void
    ++grub_Tss2_MU_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
    ++                            const TPMA_OBJECT *p);
     +
    -+  if (tpm2_protocol)
    -+    {
    -+      *protocol = tpm2_protocol;
    -+      return GRUB_ERR_NONE;
    -+    }
    ++void
    ++grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer,
    ++                                const TPMS_SCHEME_XOR *p);
     +
    -+  handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, 
NULL,
    -+                              &num_handles);
    -+  if (!handles || !num_handles)
    -+    return err;
    ++void
    ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer,
    ++                                 const TPMS_SCHEME_HMAC *p);
     +
    -+  tpm2_handle = handles[0];
    ++void
    ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer,
    ++                                      const TPMI_ALG_KEYEDHASH_SCHEME 
scheme,
    ++                                      const TPMU_SCHEME_KEYEDHASH *p);
     +
    -+  tpm2_protocol = grub_efi_open_protocol (tpm2_handle, &tpm2_guid,
    -+                                    GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    -+  if (!tpm2_protocol)
    -+    goto exit;
    ++void
    ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++                                      const TPMT_KEYEDHASH_SCHEME *p);
     +
    -+  err = grub_tcg2_get_caps (tpm2_protocol, &tpm2, NULL);
    -+  if (err || !tpm2)
    -+    goto exit;
    ++void
    ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++                                     const TPMS_KEYEDHASH_PARMS *p);
     +
    -+  *protocol = tpm2_protocol;
    -+  err = GRUB_ERR_NONE;
    ++void
    ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
    ++                                    const TPMT_SYM_DEF_OBJECT *p);
     +
    -+exit:
    -+  grub_free (handles);
    -+  return err;
    -+}
    ++void
    ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++                                 const TPMI_ALG_RSA_DECRYPT scheme,
    ++                                 const TPMU_ASYM_SCHEME *p);
     +
    -+grub_err_t
    -+grub_tcg2_get_max_output_size (grub_size_t *size)
    -+{
    -+  grub_err_t err;
    -+  grub_size_t max;
    -+  grub_efi_tpm2_protocol_t *protocol;
    ++void
    ++grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++                                const TPMT_RSA_SCHEME *p);
     +
    -+  if (!size)
    -+    return GRUB_ERR_BAD_ARGUMENT;
    ++void
    ++grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++                               const TPMS_RSA_PARMS *p);
     +
    -+  err = grub_tcg2_get_protocol (&protocol);
    -+  if (err)
    -+    return err;
    ++void
    ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++                                     const TPMS_SYMCIPHER_PARMS *p);
     +
    -+  err = grub_tcg2_get_caps (protocol, NULL, &max);
    -+  if (err)
    -+    return err;
    ++void
    ++grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++                                const TPMT_ECC_SCHEME *p);
     +
    -+  *size = max;
    ++void
    ++grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++                                const TPMI_ALG_KDF scheme,
    ++                                const TPMU_KDF_SCHEME *p);
     +
    -+  return GRUB_ERR_NONE;
    -+}
    ++void
    ++grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    ++                                const TPMT_KDF_SCHEME *p);
     +
    -+grub_err_t
    -+grub_tcg2_submit_command (grub_size_t input_size,
    -+                    grub_uint8_t *input,
    -+                    grub_size_t output_size,
    -+                    grub_uint8_t *output)
    -+{
    -+  grub_err_t err;
    -+  grub_efi_status_t status;
    -+  grub_efi_tpm2_protocol_t *protocol;
    ++void
    ++grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++                               const TPMS_ECC_PARMS *p);
     +
    -+  if (!input_size || !input || !output_size || !output)
    -+    return GRUB_ERR_BAD_ARGUMENT;
    ++void
    ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++                                  const grub_uint32_t type,
    ++                                  const TPMU_PUBLIC_PARMS *p);
     +
    -+  err = grub_tcg2_get_protocol (&protocol);
    -+  if (err)
    -+    return err;
    ++void
    ++grub_Tss2_MU_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer,
    ++                               const TPMS_ECC_POINT *p);
     +
    -+  status = protocol->submit_command (protocol, input_size, input,
    -+                               output_size, output);
    -+  if (status != GRUB_EFI_SUCCESS)
    -+    return GRUB_ERR_INVALID_COMMAND;
    ++void
    ++grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer,
    ++                               const TPMI_ALG_PUBLIC type,
    ++                               const TPMU_PUBLIC_ID *p);
     +
    -+  return GRUB_ERR_NONE;
    -+}
    -
    - ## grub-core/tpm2/tpm2.c (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
    ++void
    ++grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    ++                                  const TPMT_PUBLIC_PARMS *p);
     +
    -+#include <grub/err.h>
    -+#include <grub/misc.h>
    -+#include <grub/tpm2/buffer.h>
    -+#include <grub/tpm2/mu.h>
    -+#include <grub/tpm2/tcg2.h>
    -+#include <grub/tpm2/tpm2.h>
    -+#include <grub/types.h>
    ++void
    ++grub_Tss2_MU_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
    ++                            const TPMT_PUBLIC *p);
     +
    -+static TPM_RC
    -+grub_tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG tag,
    -+                         const TPM_CC commandCode,
    -+                         TPM_RC *responseCode,
    -+                         const struct grub_tpm2_buffer *in,
    -+                         struct grub_tpm2_buffer *out)
    -+{
    -+  grub_err_t err;
    -+  struct grub_tpm2_buffer buf;
    -+  TPMI_ST_COMMAND_TAG tag_out;
    -+  grub_uint32_t command_size;
    -+  grub_size_t max_output_size;
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&buf);
    -+  grub_tpm2_buffer_pack_u16 (&buf, tag);
    -+  grub_tpm2_buffer_pack_u32 (&buf, 0);
    -+  grub_tpm2_buffer_pack_u32 (&buf, commandCode);
    -+  grub_tpm2_buffer_pack (&buf, in->data, in->size);
    -+
    -+  if (buf.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  command_size = grub_swap_bytes32 (buf.size);
    -+  grub_memcpy (&buf.data[sizeof (grub_uint16_t)], &command_size,
    -+         sizeof (command_size));
    -+
    -+  /* Stay within output block limits */
    -+  err = grub_tcg2_get_max_output_size (&max_output_size);
    -+  if (err || max_output_size > out->cap)
    -+    max_output_size = out->cap - 1;
    -+
    -+  /* Submit */
    -+  err = grub_tcg2_submit_command (buf.size, buf.data, max_output_size,
    -+                            out->data);
    -+  if (err)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Unmarshal */
    -+  out->size = sizeof (grub_uint16_t) + sizeof (grub_uint32_t) +
    -+        sizeof (grub_uint32_t);
    -+  grub_tpm2_buffer_unpack_u16 (out, &tag_out);
    -+  grub_tpm2_buffer_unpack_u32 (out, &command_size);
    -+  grub_tpm2_buffer_unpack_u32 (out, responseCode);
    -+  out->size = command_size;
    -+  if (out->error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
    ++                             const TPM2B_PUBLIC *p);
     +
    -+static TPM_RC
    -+grub_tpm2_submit_command (const TPMI_ST_COMMAND_TAG tag,
    -+                    const TPM_CC commandCode,
    -+                    TPM_RC *responseCode,
    -+                    const struct grub_tpm2_buffer *in,
    -+                    struct grub_tpm2_buffer *out)
    -+{
    -+  TPM_RC err;
    -+  int retry_cnt = 0;
    -+
    -+  /* Catch TPM_RC_RETRY and send the command again */
    -+  do {
    -+    err = grub_tpm2_submit_command_real (tag, commandCode, responseCode,
    -+                                   in, out);
    -+    if (*responseCode != TPM_RC_RETRY)
    -+      break;
    ++void
    ++grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
    ++                                      const TPMS_SENSITIVE_CREATE *p);
     +
    -+    retry_cnt++;
    -+  } while (retry_cnt < 3);
    ++void
    ++grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
    ++                                       const TPM2B_SENSITIVE_CREATE 
*sensitiveCreate);
     +
    -+  return err;
    -+}
    ++void
    ++grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer,
    ++                                               const TPMI_ALG_PUBLIC type,
    ++                                               const 
TPMU_SENSITIVE_COMPOSITE *p);
    ++void
    ++grub_Tss2_MU_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
    ++                                     const TPMT_SENSITIVE *p);
     +
    -+TPM_RC
    -+TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
    -+              const TPMS_AUTH_COMMAND *authCommand,
    -+              const TPM2B_SENSITIVE_CREATE *inSensitive,
    -+              const TPM2B_PUBLIC *inPublic,
    -+              const TPM2B_DATA *outsideInfo,
    -+              const TPML_PCR_SELECTION *creationPCR,
    -+              TPM_HANDLE *objectHandle,
    -+              TPM2B_PUBLIC *outPublic,
    -+              TPM2B_CREATION_DATA *creationData,
    -+              TPM2B_DIGEST *creationHash,
    -+              TPMT_TK_CREATION *creationTicket,
    -+              TPM2B_NAME *name,
    -+              TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPM_HANDLE objectHandleTmp;
    -+  TPM2B_PUBLIC outPublicTmp;
    -+  TPM2B_CREATION_DATA creationDataTmp;
    -+  TPM2B_DIGEST creationHashTmp;
    -+  TPMT_TK_CREATION creationTicketTmp;
    -+  TPM2B_NAME nameTmp;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t parameterSize;
    -+
    -+  if (!inSensitive || !inPublic || !outsideInfo || !creationPCR)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!objectHandle)
    -+    objectHandle = &objectHandleTmp;
    -+  if (!outPublic)
    -+    outPublic = &outPublicTmp;
    -+  if (!creationData)
    -+    creationData = &creationDataTmp;
    -+  if (!creationHash)
    -+    creationHash = &creationHashTmp;
    -+  if (!creationTicket)
    -+    creationTicket = &creationTicketTmp;
    -+  if (!name)
    -+    name = &nameTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (outPublic, 0, sizeof (*outPublic));
    -+  grub_memset (creationData, 0, sizeof (*creationData));
    -+  grub_memset (creationHash, 0, sizeof (*creationHash));
    -+  grub_memset (creationTicket, 0, sizeof (*creationTicket));
    -+  grub_memset (name, 0, sizeof (*name));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, primaryHandle);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic);
    -+  grub_tpm2_mu_TPM2B_Marshal (&in, outsideInfo->size, 
outsideInfo->buffer);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, creationPCR);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_CreatePrimary, 
&responseCode, &in,
    -+                           &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  grub_tpm2_buffer_unpack_u32 (&out, objectHandle);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &parameterSize);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic);
    -+  grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (&out, creationData);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, creationHash);
    -+  grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (&out, creationTicket);
    -+  grub_tpm2_mu_TPM2B_NAME_Unmarshal (&out, name);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
    ++                                      const TPM2B_SENSITIVE *p);
     +
    -+TPM_RC
    -+TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
    -+                 const TPMI_DH_ENTITY bind,
    -+                 const TPMS_AUTH_COMMAND *authCommand,
    -+                 const TPM2B_NONCE *nonceCaller,
    -+                 const TPM2B_ENCRYPTED_SECRET *encryptedSalt,
    -+                 const TPM_SE sessionType,
    -+                 const TPMT_SYM_DEF *symmetric,
    -+                 const TPMI_ALG_HASH authHash,
    -+                 TPMI_SH_AUTH_SESSION *sessionHandle,
    -+                 TPM2B_NONCE *nonceTpm,
    -+                 TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMI_SH_AUTH_SESSION sessionHandleTmp;
    -+  TPM2B_NONCE nonceTpmTmp;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (!nonceCaller || !symmetric)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (tpmKey == TPM_RH_NULL &&
    -+      (encryptedSalt && encryptedSalt->size != 0))
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!sessionHandle)
    -+    sessionHandle = &sessionHandleTmp;
    -+  if (!nonceTpm)
    -+    nonceTpm = &nonceTpmTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (sessionHandle, 0, sizeof (*sessionHandle));
    -+  grub_memset (nonceTpm, 0, sizeof (*nonceTpm));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, tpmKey);
    -+  grub_tpm2_buffer_pack_u32 (&in, bind);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_mu_TPM2B_Marshal (&in, nonceCaller->size, 
nonceCaller->buffer);
    -+  if (encryptedSalt)
    -+    grub_tpm2_mu_TPM2B_Marshal (&in, encryptedSalt->size, 
encryptedSalt->secret);
    -+  else
    -+    grub_tpm2_buffer_pack_u16 (&in, 0);
    -+  grub_tpm2_buffer_pack_u8 (&in, sessionType);
    -+  grub_tpm2_mu_TPMT_SYM_DEF_Marshal (&in, symmetric);
    -+  grub_tpm2_buffer_pack_u16 (&in, authHash);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_StartAuthSession, 
&responseCode,
    -+                           &in, &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  grub_tpm2_buffer_unpack_u32 (&out, sessionHandle);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+  grub_tpm2_mu_TPM2B_NONCE_Unmarshal (&out, nonceTpm);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer,
    ++                                         const TPMS_SIGNATURE_RSA *p);
     +
    -+TPM_RC
    -+TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions,
    -+          const TPMS_AUTH_COMMAND *authCommand,
    -+          const TPM2B_DIGEST *pcrDigest,
    -+          const TPML_PCR_SELECTION *pcrs,
    -+          TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (!pcrs)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, policySessions);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  if (pcrDigest)
    -+    grub_tpm2_mu_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer);
    -+  else
    -+    grub_tpm2_buffer_pack_u16 (&in, 0);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrs);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyPCR, &responseCode, 
&in,
    -+                           &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal*/
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer,
    ++                                         const TPMS_SIGNATURE_ECC *p);
     +
    -+TPM_RC
    -+TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle,
    -+           const TPMS_AUTH_COMMAND* authCommand,
    -+           TPM2B_PUBLIC *outPublic)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t parameterSize;
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, objectHandle);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_ReadPublic, &responseCode, 
&in,
    -+                           &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &parameterSize);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer,
    ++                              const TPMI_ALG_HASH hashAlg,
    ++                              const TPMU_HA *p);
     +
    -+TPM_RC
    -+TPM2_Load (const TPMI_DH_OBJECT parent_handle,
    -+     const TPMS_AUTH_COMMAND *authCommand,
    -+     const TPM2B_PRIVATE *inPrivate,
    -+     const TPM2B_PUBLIC *inPublic,
    -+     TPM_HANDLE *objectHandle,
    -+     TPM2B_NAME *name,
    -+     TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPM_HANDLE objectHandleTmp;
    -+  TPM2B_NAME nonceTmp;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (!inPrivate || !inPublic)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!objectHandle)
    -+    objectHandle = &objectHandleTmp;
    -+  if (!name)
    -+    name = &nonceTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (objectHandle, 0, sizeof (*objectHandle));
    -+  grub_memset (name, 0, sizeof (*name));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, parent_handle);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_mu_TPM2B_Marshal (&in, inPrivate->size, inPrivate->buffer);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_Load, &responseCode, &in, 
&out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  grub_tpm2_buffer_unpack_u32 (&out, objectHandle);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+  grub_tpm2_mu_TPM2B_NAME_Unmarshal (&out, name);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer,
    ++                              const TPMT_HA *p);
     +
    -+TPM_RC
    -+TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand,
    -+                   const TPM2B_SENSITIVE *inPrivate,
    -+                   const TPM2B_PUBLIC *inPublic,
    -+                   const TPMI_RH_HIERARCHY hierarchy,
    -+                   TPM_HANDLE *objectHandle,
    -+                   TPM2B_NAME *name,
    -+                   TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPM_HANDLE objectHandleTmp;
    -+  TPM2B_NAME nameTmp;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (!inPublic)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!objectHandle)
    -+    objectHandle = &objectHandleTmp;
    -+  if (!name)
    -+    name = &nameTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (objectHandle, 0, sizeof (*objectHandle));
    -+  grub_memset (name, 0, sizeof (*name));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  if (inPrivate)
    -+    grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (&in, inPrivate);
    -+  else
    -+    grub_tpm2_buffer_pack_u16 (&in, 0);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic);
    -+  grub_tpm2_buffer_pack_u32 (&in, hierarchy);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_LoadExternal, &responseCode, 
&in, &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  grub_tpm2_buffer_unpack_u32 (&out, objectHandle);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+  grub_tpm2_mu_TPM2B_NAME_Unmarshal (&out, name);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
    ++                                     const TPMI_ALG_SIG_SCHEME sigAlg,
    ++                                     const TPMU_SIGNATURE *p);
     +
    -+TPM_RC
    -+TPM2_Unseal (const TPMI_DH_OBJECT itemHandle,
    -+       const TPMS_AUTH_COMMAND *authCommand,
    -+       TPM2B_SENSITIVE_DATA *outData,
    -+       TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPM2B_SENSITIVE_DATA outDataTmp;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (!outData)
    -+    outData = &outDataTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (outData, 0, sizeof (*outData));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, itemHandle);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_Unseal, &responseCode, &in, 
&out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+  grub_tpm2_mu_TPM2B_SENSITIVE_DATA_Unmarshal (&out, outData);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
    ++                                     const TPMT_SIGNATURE *p);
     +
    -+TPM_RC
    -+TPM2_FlushContext (const TPMI_DH_CONTEXT handle)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPM_RC responseCode;
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, handle);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (TPM_ST_NO_SESSIONS, TPM_CC_FlushContext,
    -+                           &responseCode, &in, &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer,
    ++                                       const TPMT_TK_VERIFIED *p);
     +
    -+TPM_RC
    -+TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
    -+         const TPML_PCR_SELECTION  *pcrSelectionIn,
    -+         grub_uint32_t *pcrUpdateCounter,
    -+         TPML_PCR_SELECTION *pcrSelectionOut,
    -+         TPML_DIGEST *pcrValues,
    -+         TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  grub_uint32_t pcrUpdateCounterTmp;
    -+  TPML_PCR_SELECTION pcrSelectionOutTmp;
    -+  TPML_DIGEST pcrValuesTmp;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t parameterSize;
    -+
    -+  if (!pcrSelectionIn)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!pcrUpdateCounter)
    -+    pcrUpdateCounter = &pcrUpdateCounterTmp;
    -+  if (!pcrSelectionOut)
    -+    pcrSelectionOut = &pcrSelectionOutTmp;
    -+  if (!pcrValues)
    -+    pcrValues = &pcrValuesTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrSelectionIn);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_PCR_Read, &responseCode, &in,
    -+                           &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &parameterSize);
    -+  grub_tpm2_buffer_unpack_u32 (&out, pcrUpdateCounter);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (&out, pcrSelectionOut);
    -+  grub_tpm2_mu_TPML_DIGEST_Unmarshal (&out, pcrValues);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                     TPMS_AUTH_RESPONSE* p);
     +
    -+TPM_RC
    -+TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession,
    -+                const TPMS_AUTH_COMMAND *authCommand,
    -+                TPM2B_DIGEST *policyDigest,
    -+                TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPM2B_DIGEST policyDigestTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t parameterSize;
    -+
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+  if (!policyDigest)
    -+    policyDigest = &policyDigestTmp;
    -+
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+  grub_memset (policyDigest, 0, sizeof (*policyDigest));
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, policySession);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyGetDigest, 
&responseCode,
    -+                           &in, &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &parameterSize);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, policyDigest);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                               TPM2B_DIGEST* digest);
     +
    -+TPM_RC
    -+TPM2_Create (const TPMI_DH_OBJECT parentHandle,
    -+       const TPMS_AUTH_COMMAND *authCommand,
    -+       const TPM2B_SENSITIVE_CREATE *inSensitive,
    -+       const TPM2B_PUBLIC *inPublic,
    -+       const TPM2B_DATA *outsideInfo,
    -+       const TPML_PCR_SELECTION *creationPCR,
    -+       TPM2B_PRIVATE *outPrivate,
    -+       TPM2B_PUBLIC *outPublic,
    -+       TPM2B_CREATION_DATA *creationData,
    -+       TPM2B_DIGEST *creationHash,
    -+       TPMT_TK_CREATION *creationTicket,
    -+       TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPM2B_PUBLIC outPublicTmp;
    -+  TPM2B_PRIVATE outPrivateTmp;
    -+  TPM2B_CREATION_DATA creationDataTmp;
    -+  TPM2B_DIGEST creationHashTmp;
    -+  TPMT_TK_CREATION creationTicketTmp;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? 
TPM_ST_SESSIONS:TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  TPM_RC rc;
    -+  grub_uint32_t parameterSize;
    -+
    -+  if (!inSensitive || !inPublic || !outsideInfo || !creationPCR)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!outPrivate)
    -+    outPrivate = &outPrivateTmp;
    -+  if (!outPublic)
    -+    outPublic = &outPublicTmp;
    -+  if (!creationData)
    -+    creationData = &creationDataTmp;
    -+  if (!creationHash)
    -+    creationHash = &creationHashTmp;
    -+  if (!creationTicket)
    -+    creationTicket = &creationTicketTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (outPrivate, 0, sizeof (*outPrivate));
    -+  grub_memset (outPublic, 0, sizeof (*outPublic));
    -+  grub_memset (creationData, 0, sizeof (*creationData));
    -+  grub_memset (creationHash, 0, sizeof (*creationHash));
    -+  grub_memset (creationTicket, 0, sizeof (*creationTicket));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, parentHandle);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic);
    -+  grub_tpm2_mu_TPM2B_Marshal (&in, outsideInfo->size, 
outsideInfo->buffer);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, creationPCR);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_Create, &responseCode, &in,
    -+                           &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+   grub_tpm2_buffer_unpack_u32 (&out, &parameterSize);
    -+  grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (&out, outPrivate);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic);
    -+  grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (&out, creationData);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, creationHash);
    -+  grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (&out, creationTicket);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                              TPM2B_NONCE* nonce);
     +
    -+TPM_RC
    -+TPM2_EvictControl (const TPMI_RH_PROVISION auth,
    -+             const TPMI_DH_OBJECT objectHandle,
    -+             const TPMS_AUTH_COMMAND *authCommand,
    -+             const TPMI_DH_PERSISTENT persistentHandle,
    -+             TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  TPM_RC rc;
    -+  grub_uint32_t parameterSize;
    -+
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, auth);
    -+  grub_tpm2_buffer_pack_u32 (&in, objectHandle);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_buffer_pack_u32 (&in, persistentHandle);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_EvictControl, &responseCode, 
&in,
    -+                           &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    {
    -+      grub_tpm2_buffer_unpack_u32 (&out, &parameterSize);
    -+      grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse);
    -+    }
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    ++void
    ++grub_Tss2_MU_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                             TPM2B_DATA* data);
     +
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                     TPMS_CREATION_DATA *data);
     +
    -+TPM_RC
    -+TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand,
    -+           const TPM2B_MAX_BUFFER *data,
    -+           const TPMI_ALG_HASH hashAlg,
    -+           const TPMI_RH_HIERARCHY hierarchy,
    -+           TPM2B_DIGEST *outHash,
    -+           TPMT_TK_HASHCHECK *validation,
    -+           TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPM2B_DIGEST outHashTmp;
    -+  TPMT_TK_HASHCHECK validationTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (hashAlg == TPM_ALG_NULL)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!outHash)
    -+    outHash = &outHashTmp;
    -+  if (!validation)
    -+    validation = &validationTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (outHash, 0, sizeof (*outHash));
    -+  grub_memset (validation, 0, sizeof (*validation));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  if (data)
    -+    grub_tpm2_mu_TPM2B_Marshal (&in, data->size, data->buffer);
    -+  else
    -+    grub_tpm2_buffer_pack_u16 (&in, 0);
    -+  grub_tpm2_buffer_pack_u16 (&in, hashAlg);
    -+  grub_tpm2_buffer_pack_u32 (&in, hierarchy);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_Hash, &responseCode, &in, 
&out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, outHash);
    -+  grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (&out, validation);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                      TPM2B_CREATION_DATA *data);
     +
    -+TPM_RC
    -+TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle,
    -+                      const TPMS_AUTH_COMMAND *authCommand,
    -+                      const TPM2B_DIGEST *digest,
    -+                      const TPMT_SIGNATURE *signature,
    -+                      TPMT_TK_VERIFIED *validation,
    -+                      TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPMT_TK_VERIFIED validationTmp;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (!digest || !signature)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!validation)
    -+    validation = &validationTmp;
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (validation, 0, sizeof (*validation));
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_buffer_pack_u32 (&in, keyHandle);
    -+  grub_tpm2_mu_TPM2B_Marshal (&in, digest->size, digest->buffer);
    -+  grub_tpm2_mu_TPMT_SIGNATURE_Marshal (&in, signature);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_VerifySignature, 
&responseCode, &in, &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+  grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (&out, validation);
    -+  if (tag == TPM_ST_SESSIONS)
    -+    grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                TPM2B_PRIVATE* private);
     +
    -+TPM_RC
    -+TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession,
    -+                      const TPMS_AUTH_COMMAND *authCommand,
    -+                      const TPM2B_DIGEST *approvedPolicy,
    -+                      const TPM2B_NONCE *policyRef,
    -+                      const TPM2B_NAME *keySign,
    -+                      const TPMT_TK_VERIFIED *checkTicket,
    -+                      TPMS_AUTH_RESPONSE *authResponse)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMS_AUTH_RESPONSE authResponseTmp;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+  grub_uint32_t param_size;
    -+
    -+  if (!approvedPolicy || !keySign || !checkTicket)
    -+    return TPM_RC_VALUE;
    -+
    -+  if (!authResponse)
    -+    authResponse = &authResponseTmp;
    -+
    -+  grub_memset (authResponse, 0, sizeof (*authResponse));
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_buffer_pack_u32 (&in, policySession);
    -+  if (authCommand)
    -+    grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
    -+  grub_tpm2_mu_TPM2B_Marshal (&in, approvedPolicy->size, 
approvedPolicy->buffer);
    -+  if (policyRef)
    -+    grub_tpm2_mu_TPM2B_Marshal (&in, policyRef->size, policyRef->buffer);
    -+  else
    -+    grub_tpm2_buffer_pack_u16 (&in, 0);
    -+  grub_tpm2_mu_TPM2B_Marshal (&in, keySign->size, keySign->name);
    -+  grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (&in, checkTicket);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyAuthorize, 
&responseCode, &in, &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (tag == TPM_ST_SESSIONS)
    -+    {
    -+      grub_tpm2_buffer_unpack_u32 (&out, &param_size);
    -+      grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
    -+    }
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    ++void
    ++grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                       TPM2B_SENSITIVE_DATA *data);
     +
    -+  return TPM_RC_SUCCESS;
    -+}
    ++void
    ++grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                       TPM2B_PUBLIC_KEY_RSA *rsa);
     +
    -+TPM_RC
    -+TPM2_TestParms (const TPMT_PUBLIC_PARMS *parms,
    -+          const TPMS_AUTH_COMMAND* authCommand)
    -+{
    -+  TPM_RC rc;
    -+  struct grub_tpm2_buffer in;
    -+  struct grub_tpm2_buffer out;
    -+  TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : 
TPM_ST_NO_SESSIONS;
    -+  TPM_RC responseCode;
    -+
    -+  if (!parms)
    -+    return TPM_RC_VALUE;
    -+
    -+  /* Marshal */
    -+  grub_tpm2_buffer_init (&in);
    -+  grub_tpm2_mu_TPMT_PUBLIC_PARMS_Marshal (&in, parms);
    -+  if (in.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  /* Submit */
    -+  grub_tpm2_buffer_init (&out);
    -+  rc = grub_tpm2_submit_command (tag, TPM_CC_TestParms, &responseCode, 
&in,
    -+                           &out);
    -+  if (rc != TPM_RC_SUCCESS)
    -+    return rc;
    -+  if (responseCode != TPM_RC_SUCCESS)
    -+    return responseCode;
    -+
    -+  /* Unmarshal */
    -+  if (out.error)
    -+    return TPM_RC_FAILURE;
    -+
    -+  return TPM_RC_SUCCESS;
    -+}
    -
    - ## include/grub/tpm2/buffer.h (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
    ++void
    ++grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                      TPM2B_ECC_PARAMETER *param);
     +
    -+#ifndef GRUB_TPM2_BUFFER_HEADER
    -+#define GRUB_TPM2_BUFFER_HEADER 1
    ++void
    ++grub_Tss2_MU_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                              TPMA_OBJECT *p);
     +
    -+#include <grub/types.h>
    ++void
    ++grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                   TPMS_SCHEME_HMAC *p);
     +
    -+#define GRUB_TPM2_BUFFER_CAPACITY 4096
    ++void
    ++grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                  TPMS_SCHEME_XOR *p);
     +
    -+struct grub_tpm2_buffer
    -+{
    -+  grub_uint8_t data[GRUB_TPM2_BUFFER_CAPACITY];
    -+  grub_size_t size;
    -+  grub_size_t offset;
    -+  grub_size_t cap;
    -+  int error;
    -+};
    -+typedef struct grub_tpm2_buffer *grub_tpm2_buffer_t;
    ++void
    ++grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                        TPMI_ALG_KEYEDHASH_SCHEME scheme,
    ++                                        TPMU_SCHEME_KEYEDHASH *p);
     +
     +void
    -+grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer);
    ++grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                        TPMT_KEYEDHASH_SCHEME *p);
     +
     +void
    -+grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void* data,
    -+                 grub_size_t size);
    ++grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                       TPMS_KEYEDHASH_PARMS *p);
     +
     +void
    -+grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value);
    ++grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                    TPMI_ALG_SYM_OBJECT algorithm,
    ++                                    TPMU_SYM_KEY_BITS *p);
     +
     +void
    -+grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t 
value);
    ++grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                TPMI_ALG_SYM_OBJECT algorithm,
    ++                                TPMU_SYM_MODE *p);
     +
     +void
    -+grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t 
value);
    ++grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                      TPMT_SYM_DEF_OBJECT *p);
     +
     +void
    -+grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void* data,
    -+                   grub_size_t size);
    ++grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                       TPMS_SYMCIPHER_PARMS *p);
     +
     +void
    -+grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t* 
value);
    ++grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                   TPMI_ALG_RSA_DECRYPT scheme,
    ++                                   TPMU_ASYM_SCHEME *p);
     +
     +void
    -+grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t* 
value);
    ++grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                  TPMT_RSA_SCHEME *p);
     +
     +void
    -+grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t* 
value);
    ++grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                 TPMS_RSA_PARMS *p);
     +
    -+#endif /* ! GRUB_TPM2_BUFFER_HEADER */
    -
    - ## include/grub/tpm2/internal/functions.h (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
    ++void
    ++grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                  TPMT_ECC_SCHEME *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                  TPMI_ALG_KDF scheme,
    ++                                  TPMU_KDF_SCHEME *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                  TPMT_KDF_SCHEME *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                 TPMS_ECC_PARMS *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                    grub_uint32_t type,
    ++                                    TPMU_PUBLIC_PARMS *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                 TPMS_ECC_POINT *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                 TPMI_ALG_PUBLIC type,
    ++                                 TPMU_PUBLIC_ID *p);
     +
    -+#ifndef GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER
    -+#define GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER 1
    -+
    -+#include <grub/tpm2/internal/structs.h>
    -+
    -+TPM_RC
    -+TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle,
    -+              const TPMS_AUTH_COMMAND *authCommand,
    -+              const TPM2B_SENSITIVE_CREATE *inSensitive,
    -+              const TPM2B_PUBLIC *inPublic,
    -+              const TPM2B_DATA *outsideInfo,
    -+              const TPML_PCR_SELECTION *creationPCR,
    -+              TPM_HANDLE *objectHandle,
    -+              TPM2B_PUBLIC *outPublic,
    -+              TPM2B_CREATION_DATA *creationData,
    -+              TPM2B_DIGEST *creationHash,
    -+              TPMT_TK_CREATION *creationTicket,
    -+              TPM2B_NAME *name,
    -+              TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey,
    -+                 const TPMI_DH_ENTITY bind,
    -+                 const TPMS_AUTH_COMMAND *authCommand,
    -+                 const TPM2B_NONCE *nonceCaller,
    -+                 const TPM2B_ENCRYPTED_SECRET *encryptedSalt,
    -+                 const TPM_SE sessionType,
    -+                 const TPMT_SYM_DEF *symmetric,
    -+                 const TPMI_ALG_HASH authHash,
    -+                 TPMI_SH_AUTH_SESSION *sessionHandle,
    -+                 TPM2B_NONCE *nonceTpm,
    -+                 TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_PolicyPCR (const TPMI_SH_POLICY policySession,
    -+          const TPMS_AUTH_COMMAND *authCommand,
    -+          const TPM2B_DIGEST *pcrDigest,
    -+          const TPML_PCR_SELECTION *pcrs,
    -+          TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle,
    -+           const TPMS_AUTH_COMMAND* authCommand,
    -+           TPM2B_PUBLIC *outPublic);
    -+
    -+TPM_RC
    -+TPM2_Load (const TPMI_DH_OBJECT parent_handle,
    -+     const TPMS_AUTH_COMMAND *authCommand,
    -+     const TPM2B_PRIVATE *inPrivate,
    -+     const TPM2B_PUBLIC *inPublic,
    -+     TPM_HANDLE *objectHandle,
    -+     TPM2B_NAME *name,
    -+     TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand,
    -+                   const TPM2B_SENSITIVE *inPrivate,
    -+                   const TPM2B_PUBLIC *inPublic,
    -+                   const TPMI_RH_HIERARCHY hierarchy,
    -+                   TPM_HANDLE *objectHandle,
    -+                   TPM2B_NAME *name,
    -+                   TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_Unseal (const TPMI_DH_OBJECT item_handle,
    -+       const TPMS_AUTH_COMMAND *authCommand,
    -+       TPM2B_SENSITIVE_DATA *outData,
    -+       TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_FlushContext (const TPMI_DH_CONTEXT handle);
    -+
    -+TPM_RC
    -+TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand,
    -+         const TPML_PCR_SELECTION *pcrSelectionIn,
    -+         grub_uint32_t *pcrUpdateCounter,
    -+         TPML_PCR_SELECTION *pcrSelectionOut,
    -+         TPML_DIGEST *pcrValues,
    -+         TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession,
    -+                const TPMS_AUTH_COMMAND *authCommand,
    -+                TPM2B_DIGEST *policyDigest,
    -+                TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_Create (const TPMI_DH_OBJECT parentHandle,
    -+       const TPMS_AUTH_COMMAND *authCommand,
    -+       const TPM2B_SENSITIVE_CREATE *inSensitive,
    -+       const TPM2B_PUBLIC *inPublic,
    -+       const TPM2B_DATA *outsideInfo,
    -+       const TPML_PCR_SELECTION *creationPCR,
    -+       TPM2B_PRIVATE *outPrivate,
    -+       TPM2B_PUBLIC *outPublic,
    -+       TPM2B_CREATION_DATA *creationData,
    -+       TPM2B_DIGEST *creationHash,
    -+       TPMT_TK_CREATION *creationTicket,
    -+       TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_EvictControl (const TPMI_RH_PROVISION auth,
    -+             const TPMI_DH_OBJECT objectHandle,
    -+             const TPMS_AUTH_COMMAND *authCommand,
    -+             const TPMI_DH_PERSISTENT persistentHandle,
    -+             TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand,
    -+           const TPM2B_MAX_BUFFER *data,
    -+           const TPMI_ALG_HASH hashAlg,
    -+           const TPMI_RH_HIERARCHY hierarchy,
    -+           TPM2B_DIGEST *outHash,
    -+           TPMT_TK_HASHCHECK *validation,
    -+           TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle,
    -+                      const TPMS_AUTH_COMMAND *authCommand,
    -+                      const TPM2B_DIGEST *digest,
    -+                      const TPMT_SIGNATURE *signature,
    -+                      TPMT_TK_VERIFIED *validation,
    -+                      TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession,
    -+                      const TPMS_AUTH_COMMAND *authCommand,
    -+                      const TPM2B_DIGEST *approvedPolicy,
    -+                      const TPM2B_NONCE *policyRef,
    -+                      const TPM2B_NAME *keySign,
    -+                      const TPMT_TK_VERIFIED *checkTicket,
    -+                      TPMS_AUTH_RESPONSE *authResponse);
    -+
    -+TPM_RC
    -+TPM2_TestParms (const TPMT_PUBLIC_PARMS *parms,
    -+          const TPMS_AUTH_COMMAND* authCommand);
    -+
    -+#endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */
    ++void
    ++grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                              TPMT_PUBLIC *p);
    ++
    ++void
    ++grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                               TPM2B_PUBLIC *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                 TPMS_NV_PUBLIC *p);
    ++
    ++void
    ++grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                  TPM2B_NV_PUBLIC *p);
    ++
    ++void
    ++grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                             TPM2B_NAME *n);
    ++
    ++void
    ++grub_Tss2_MU_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                       TPMS_TAGGED_PROPERTY* property);
    ++
    ++void
    ++grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                   TPMT_TK_CREATION *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                          TPMT_TK_HASHCHECK *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                         TPMT_TK_VERIFIED *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                     TPMS_PCR_SELECTION* pcrSelection);
    ++
    ++void
    ++grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                     TPML_PCR_SELECTION* pcrSelection);
    ++
    ++void
    ++grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                              TPML_DIGEST* digest);
    ++
    ++void
    ++grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                           TPMS_SIGNATURE_RSA *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                           TPMS_SIGNATURE_ECC *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                TPMI_ALG_HASH hashAlg,
    ++                                TPMU_HA *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                TPMT_HA *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                       TPMI_ALG_SIG_SCHEME sigAlg,
    ++                                       TPMU_SIGNATURE *p);
    ++
    ++void
    ++grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
    ++                                       TPMT_SIGNATURE *p);
    ++
    ++#endif /* ! GRUB_TPM2_MU_HEADER */
     
    - ## include/grub/tpm2/internal/structs.h (new) ##
    + ## grub-core/lib/tss2/tss2_structs.h (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ include/grub/tpm2/internal/structs.h (new)
     +#ifndef GRUB_TPM2_INTERNAL_STRUCTS_HEADER
     +#define GRUB_TPM2_INTERNAL_STRUCTS_HEADER 1
     +
    -+#include <grub/tpm2/internal/types.h>
    ++#include <tss2_types.h>
     +
     +/* TPMS_TAGGED_PROPERTY Structure */
     +struct TPMS_TAGGED_PROPERTY
    @@ include/grub/tpm2/internal/structs.h (new)
     +/* TPMA_SESSION Structure */
     +struct TPMA_SESSION
     +{
    -+  unsigned int continueSession:1;
    -+  unsigned int auditExclusive:1;
    -+  unsigned int auditReset:1;
    -+  unsigned int reserved1:2;
    -+  unsigned int decrypt:1;
    -+  unsigned int encrypt:1;
    -+  unsigned int audit:1;
    -+  unsigned int reserved:24;
    ++  grub_uint8_t continueSession:1;
    ++  grub_uint8_t auditExclusive:1;
    ++  grub_uint8_t auditReset:1;
    ++  grub_uint8_t reserved:2;
    ++  grub_uint8_t decrypt:1;
    ++  grub_uint8_t encrypt:1;
    ++  grub_uint8_t audit:1;
     +};
     +typedef struct TPMA_SESSION TPMA_SESSION;
     +
    @@ include/grub/tpm2/internal/structs.h (new)
     +/* TPMA_OBJECT Structure */
     +struct TPMA_OBJECT
     +{
    -+  unsigned int reserved1:1;
    -+  unsigned int fixedTPM:1;
    -+  unsigned int stClear:1;
    -+  unsigned int reserved2:1;
    -+  unsigned int fixedParent:1;
    -+  unsigned int sensitiveDataOrigin:1;
    -+  unsigned int userWithAuth:1;
    -+  unsigned int adminWithPolicy:1;
    -+  unsigned int reserved3:2;
    -+  unsigned int noDA:1;
    -+  unsigned int encryptedDuplication:1;
    -+  unsigned int reserved4:4;
    -+  unsigned int restricted:1;
    -+  unsigned int decrypt:1;
    -+  unsigned int sign:1;
    -+  unsigned int reserved5:13;
    ++  grub_uint32_t reserved1:1;
    ++  grub_uint32_t fixedTPM:1;
    ++  grub_uint32_t stClear:1;
    ++  grub_uint32_t reserved2:1;
    ++  grub_uint32_t fixedParent:1;
    ++  grub_uint32_t sensitiveDataOrigin:1;
    ++  grub_uint32_t userWithAuth:1;
    ++  grub_uint32_t adminWithPolicy:1;
    ++  grub_uint32_t reserved3:2;
    ++  grub_uint32_t noDA:1;
    ++  grub_uint32_t encryptedDuplication:1;
    ++  grub_uint32_t reserved4:4;
    ++  grub_uint32_t restricted:1;
    ++  grub_uint32_t decrypt:1;
    ++  grub_uint32_t sign:1;
    ++  grub_uint32_t reserved5:13;
     +};
     +typedef struct TPMA_OBJECT TPMA_OBJECT;
     +
    @@ include/grub/tpm2/internal/structs.h (new)
     +/* TPMA_LOCALITY Structure */
     +struct TPMA_LOCALITY
     +{
    -+  unsigned char TPM_LOC_ZERO:1;
    -+  unsigned char TPM_LOC_ONE:1;
    -+  unsigned char TPM_LOC_TWO:1;
    -+  unsigned char TPM_LOC_THREE:1;
    -+  unsigned char TPM_LOC_FOUR:1;
    -+  unsigned char Extended:3;
    ++  grub_uint8_t TPM_LOC_ZERO:1;
    ++  grub_uint8_t TPM_LOC_ONE:1;
    ++  grub_uint8_t TPM_LOC_TWO:1;
    ++  grub_uint8_t TPM_LOC_THREE:1;
    ++  grub_uint8_t TPM_LOC_FOUR:1;
    ++  grub_uint8_t Extended:3;
     +};
     +typedef struct TPMA_LOCALITY TPMA_LOCALITY;
     +
    @@ include/grub/tpm2/internal/structs.h (new)
     +
     +#endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */
     
    - ## include/grub/tpm2/internal/types.h (new) ##
    + ## grub-core/lib/tss2/tss2_types.h (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ include/grub/tpm2/internal/types.h (new)
     +typedef TPM_HANDLE TPMI_DH_PERSISTENT;
     +
     +#endif /* ! GRUB_TPM2_INTERNAL_TYPES_HEADER */
    -
    - ## include/grub/tpm2/mu.h (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
    -+
    -+#ifndef GRUB_TPM2_MU_HEADER
    -+#define GRUB_TPM2_MU_HEADER 1
    -+
    -+#include <grub/tpm2/buffer.h>
    -+#include <grub/tpm2/tpm2.h>
    -+
    -+void
    -+grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer,
    -+                                  const TPMS_AUTH_COMMAND* authCommand);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer,
    -+                      const grub_uint16_t size,
    -+                      const grub_uint8_t* b);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer,
    -+                                  const TPMI_ALG_SYM_OBJECT algorithm,
    -+                                  const TPMU_SYM_KEY_BITS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer,
    -+                              const TPMI_ALG_SYM_OBJECT algorithm,
    -+                              const TPMU_SYM_MODE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer,
    -+                             const TPMT_SYM_DEF *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
    -+                                   const TPMS_PCR_SELECTION* 
pcrSelection);
    -+
    -+void
    -+grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer,
    -+                                   const TPML_PCR_SELECTION* 
pcrSelection);
    -+
    -+void
    -+grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
    -+                            const TPMA_OBJECT *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer,
    -+                                const TPMS_SCHEME_XOR *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer,
    -+                                 const TPMS_SCHEME_HMAC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer,
    -+                                      const TPMI_ALG_KEYEDHASH_SCHEME 
scheme,
    -+                                      const TPMU_SCHEME_KEYEDHASH *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    -+                                      const TPMT_KEYEDHASH_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    -+                                     const TPMS_KEYEDHASH_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer,
    -+                                    const TPMT_SYM_DEF_OBJECT *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    -+                                 const TPMI_ALG_RSA_DECRYPT scheme,
    -+                                 const TPMU_ASYM_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    -+                                const TPMT_RSA_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    -+                               const TPMS_RSA_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    -+                                     const TPMS_SYMCIPHER_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    -+                                const TPMT_ECC_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    -+                                const TPMI_ALG_KDF scheme,
    -+                                const TPMU_KDF_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer,
    -+                                const TPMT_KDF_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    -+                               const TPMS_ECC_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    -+                                  const grub_uint32_t type,
    -+                                  const TPMU_PUBLIC_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer,
    -+                               const TPMS_ECC_POINT *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer,
    -+                               const TPMI_ALG_PUBLIC type,
    -+                               const TPMU_PUBLIC_ID *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer,
    -+                                  const TPMT_PUBLIC_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
    -+                            const TPMT_PUBLIC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
    -+                             const TPM2B_PUBLIC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
    -+                                      const TPMS_SENSITIVE_CREATE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
    -+                                       const TPM2B_SENSITIVE_CREATE 
*sensitiveCreate);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer,
    -+                                               const TPMI_ALG_PUBLIC type,
    -+                                               const 
TPMU_SENSITIVE_COMPOSITE *p);
    -+void
    -+grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
    -+                                     const TPMT_SENSITIVE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
    -+                                      const TPM2B_SENSITIVE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer,
    -+                                         const TPMS_SIGNATURE_RSA *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer,
    -+                                         const TPMS_SIGNATURE_ECC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer,
    -+                              const TPMI_ALG_HASH hashAlg,
    -+                              const TPMU_HA *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer,
    -+                              const TPMT_HA *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
    -+                                     const TPMI_ALG_SIG_SCHEME sigAlg,
    -+                                     const TPMU_SIGNATURE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
    -+                                     const TPMT_SIGNATURE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer,
    -+                                       const TPMT_TK_VERIFIED *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                     TPMS_AUTH_RESPONSE* p);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                               TPM2B_DIGEST* digest);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                              TPM2B_NONCE* nonce);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                             TPM2B_DATA* data);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                     TPMS_CREATION_DATA *data);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                      TPM2B_CREATION_DATA *data);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                TPM2B_PRIVATE* private);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                       TPM2B_SENSITIVE_DATA *data);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                       TPM2B_PUBLIC_KEY_RSA *rsa);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                      TPM2B_ECC_PARAMETER *param);
    -+
    -+void
    -+grub_tpm2_mu_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                              TPMA_OBJECT *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                   TPMS_SCHEME_HMAC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                  TPMS_SCHEME_XOR *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                        TPMI_ALG_KEYEDHASH_SCHEME scheme,
    -+                                        TPMU_SCHEME_KEYEDHASH *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                        TPMT_KEYEDHASH_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                       TPMS_KEYEDHASH_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                    TPMI_ALG_SYM_OBJECT algorithm,
    -+                                    TPMU_SYM_KEY_BITS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                TPMI_ALG_SYM_OBJECT algorithm,
    -+                                TPMU_SYM_MODE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                      TPMT_SYM_DEF_OBJECT *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                       TPMS_SYMCIPHER_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                   TPMI_ALG_RSA_DECRYPT scheme,
    -+                                   TPMU_ASYM_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                  TPMT_RSA_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                 TPMS_RSA_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                  TPMT_ECC_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                  TPMI_ALG_KDF scheme,
    -+                                  TPMU_KDF_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                  TPMT_KDF_SCHEME *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                 TPMS_ECC_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                    grub_uint32_t type,
    -+                                    TPMU_PUBLIC_PARMS *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                 TPMS_ECC_POINT *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                 TPMI_ALG_PUBLIC type,
    -+                                 TPMU_PUBLIC_ID *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                              TPMT_PUBLIC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                               TPM2B_PUBLIC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                 TPMS_NV_PUBLIC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                  TPM2B_NV_PUBLIC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                             TPM2B_NAME *n);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                       TPMS_TAGGED_PROPERTY* property);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                   TPMT_TK_CREATION *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                          TPMT_TK_HASHCHECK *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                         TPMT_TK_VERIFIED *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                     TPMS_PCR_SELECTION* pcrSelection);
    -+
    -+void
    -+grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                     TPML_PCR_SELECTION* pcrSelection);
    -+
    -+void
    -+grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                              TPML_DIGEST* digest);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                           TPMS_SIGNATURE_RSA *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                           TPMS_SIGNATURE_ECC *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                TPMI_ALG_HASH hashAlg,
    -+                                TPMU_HA *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                TPMT_HA *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                       TPMI_ALG_SIG_SCHEME sigAlg,
    -+                                       TPMU_SIGNATURE *p);
    -+
    -+void
    -+grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
    -+                                       TPMT_SIGNATURE *p);
    -+
    -+#endif /* ! GRUB_TPM2_MU_HEADER */
    -
    - ## include/grub/tpm2/tcg2.h (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
    -+
    -+#ifndef GRUB_TPM2_TCG2_HEADER
    -+#define GRUB_TPM2_TCG2_HEADER 1
    -+
    -+#include <grub/err.h>
    -+#include <grub/types.h>
    -+
    -+grub_err_t
    -+grub_tcg2_get_max_output_size (grub_size_t *size);
    -+
    -+grub_err_t
    -+grub_tcg2_submit_command (grub_size_t input_size,
    -+                    grub_uint8_t *input,
    -+                    grub_size_t output_size,
    -+                    grub_uint8_t *output);
    -+
    -+#endif /* ! GRUB_TPM2_TCG2_HEADER */
    -
    - ## include/grub/tpm2/tpm2.h (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
    -+
    -+#ifndef GRUB_TPM2_TPM2_HEADER
    -+#define GRUB_TPM2_TPM2_HEADER 1
    -+
    -+#include <grub/tpm2/internal/types.h>
    -+#include <grub/tpm2/internal/structs.h>
    -+#include <grub/tpm2/internal/functions.h>
    -+
    -+/* Well-Known Windows SRK handle */
    -+#define TPM2_SRK_HANDLE 0x81000001
    -+
    -+typedef struct TPM2_SEALED_KEY {
    -+  TPM2B_PUBLIC  public;
    -+  TPM2B_PRIVATE private;
    -+} TPM2_SEALED_KEY;
    -+
    -+#endif /* ! GRUB_TPM2_TPM2_HEADER */
 -:  --------- > 15:  c3161e49b tss2: Add TPM2 Software Stack (TSS2) support
11:  324bc5b0b ! 16:  dd1efc0fe key_protector: Add TPM2 Key Protector
    @@ Commit message
     
      ## grub-core/Makefile.core.def ##
     @@ grub-core/Makefile.core.def: module = {
    -   enable = efi;
    +   cppflags = '-I$(srcdir)/lib/tss2';
      };
      
     +module = {
    -+  name = tpm2;
    -+  common = tpm2/args.c;
    -+  common = tpm2/buffer.c;
    -+  common = tpm2/module.c;
    -+  common = tpm2/mu.c;
    -+  common = tpm2/tpm2.c;
    -+  common = tpm2/tpm2key.c;
    -+  common = tpm2/tpm2key_asn1_tab.c;
    -+  efi = tpm2/tcg2.c;
    ++  name = tpm2_key_protector;
    ++  common = commands/tpm2_key_protector/args.c;
    ++  common = commands/tpm2_key_protector/module.c;
    ++  common = commands/tpm2_key_protector/tpm2key.c;
    ++  common = commands/tpm2_key_protector/tpm2key_asn1_tab.c;
    ++  /* The plaform support of tpm2_key_protector depends on the tcg2 
implementation in tss2. */
     +  enable = efi;
    -+  cppflags = '-I$(srcdir)/lib/libtasn1-grub';
    ++  cppflags = '-I$(srcdir)/lib/tss2 -I$(srcdir)/lib/libtasn1-grub';
     +};
     +
      module = {
        name = tr;
        common = commands/tr.c;
     
    - ## grub-core/tpm2/args.c (new) ##
    + ## grub-core/commands/tpm2_key_protector/args.c (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ grub-core/tpm2/args.c (new)
     +#include <grub/err.h>
     +#include <grub/mm.h>
     +#include <grub/misc.h>
    -+#include <grub/tpm2/internal/args.h>
    ++
    ++#include "tpm2_args.h"
     +
     +grub_err_t
     +grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
    @@ grub-core/tpm2/args.c (new)
     +{
     +  char *current_pcr = value;
     +  char *next_pcr;
    -+  unsigned long pcr;
    ++  const char *pcr_end;
    ++  grub_uint64_t pcr;
     +  grub_uint8_t i;
     +
     +  if (grub_strlen (value) == 0)
    @@ grub-core/tpm2/args.c (new)
     +    {
     +      next_pcr = grub_strchr (current_pcr, ',');
     +      if (next_pcr == current_pcr)
    -+  return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                     N_("Empty entry in PCR list"));
    -+      if (next_pcr)
    ++  return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Empty entry in PCR 
list"));
    ++      if (next_pcr != NULL)
     +  *next_pcr = '\0';
     +
     +      grub_errno = GRUB_ERR_NONE;
    -+      pcr = grub_strtoul (current_pcr, NULL, 10);
    -+      if (grub_errno != GRUB_ERR_NONE)
    -+  return grub_error (grub_errno,
    -+                     N_("Entry '%s' in PCR list is not a number"),
    -+                     current_pcr);
    ++      pcr = grub_strtoul (current_pcr, &pcr_end, 10);
    ++      if (*current_pcr == '\0' || *pcr_end != '\0')
    ++  return grub_error (GRUB_ERR_BAD_NUMBER, N_("Entry '%s' in PCR list is 
not a number"), current_pcr);
     +
     +      if (pcr > TPM_MAX_PCRS)
    -+  return grub_error (GRUB_ERR_OUT_OF_RANGE,
    -+                     N_("Entry %lu in PCR list is too large to be a PCR "
    -+                        "number, PCR numbers range from 0 to %u"),
    -+                     pcr, TPM_MAX_PCRS);
    ++  return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Entry %lu in PCR list is 
too large to be a PCR number, PCR numbers range from 0 to %u"), pcr, 
TPM_MAX_PCRS);
     +
    -+      pcrs[i] = (grub_uint8_t)pcr;
    -+      *pcr_count += 1;
    ++      pcrs[i] = (grub_uint8_t) pcr;
    ++      ++(*pcr_count);
     +
     +      if (next_pcr == NULL)
     +  break;
     +
     +      current_pcr = next_pcr + 1;
     +      if (*current_pcr == '\0')
    -+  return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                     N_("Trailing comma at the end of PCR list"));
    ++  return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Trailing comma at the end 
of PCR list"));
     +    }
     +
     +  if (i == TPM_MAX_PCRS)
    -+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
    -+                 N_("Too many PCRs in PCR list, the maximum number of "
    -+                    "PCRs is %u"), TPM_MAX_PCRS);
    ++    return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Too many PCRs in PCR 
list, the maximum number of PCRs is %u"), TPM_MAX_PCRS);
     +
     +  return GRUB_ERR_NONE;
     +}
    @@ grub-core/tpm2/args.c (new)
     +      srk_type->detail.rsa_bits = 2048;
     +    }
     +  else
    -+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
    -+                 N_("Value '%s' is not a valid asymmetric key type"),
    -+                 value);
    ++    return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Value '%s' is not a 
valid asymmetric key type"), value);
     +
     +  return GRUB_ERR_NONE;
     +}
    @@ grub-core/tpm2/args.c (new)
     +grub_err_t
     +grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE 
*handle)
     +{
    -+  unsigned long num;
    ++  grub_uint64_t num;
    ++  const char *str_end;
     +
     +  grub_errno = GRUB_ERR_NONE;
    -+  num = grub_strtoul (value, NULL, 0);
    -+  if (grub_errno != GRUB_ERR_NONE)
    -+    return grub_error (grub_errno, N_("TPM handle value '%s' is not a 
number"),
    -+                 value);
    ++  num = grub_strtoul (value, &str_end, 0);
    ++  if (*value == '\0' || *str_end != '\0')
    ++    return grub_error (GRUB_ERR_BAD_NUMBER, N_("TPM handle value '%s' is 
not a number"), value);
     +
     +  if (num > GRUB_UINT_MAX)
    -+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
    -+                 N_("Value %lu is too large to be a TPM handle, TPM "
    -+                    "handles are unsigned 32-bit integers"), num);
    ++    return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Value %lu is too large 
to be a TPM handle, TPM handles are unsigned 32-bit integers"), num);
     +
    -+  *handle = (TPM_HANDLE)num;
    ++  *handle = (TPM_HANDLE) num;
     +
     +  return GRUB_ERR_NONE;
     +}
     
    - ## grub-core/tpm2/module.c (new) ##
    + ## grub-core/commands/tpm2_key_protector/module.c (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ grub-core/tpm2/module.c (new)
     +#include <grub/misc.h>
     +#include <grub/mm.h>
     +#include <grub/key_protector.h>
    -+#include <grub/tpm2/buffer.h>
    -+#include <grub/tpm2/internal/args.h>
    -+#include <grub/tpm2/internal/types.h>
    -+#include <grub/tpm2/mu.h>
    -+#include <grub/tpm2/tpm2.h>
    -+#include <grub/tpm2/tpm2key.h>
    ++
    ++#include <tss2_buffer.h>
    ++#include <tss2_types.h>
    ++#include <tss2_mu.h>
    ++
    ++#include "tpm2_args.h"
    ++#include "tpm2.h"
    ++#include "tpm2key.h"
     +
     +GRUB_MOD_LICENSE ("GPLv3+");
     +
    @@ grub-core/tpm2/module.c (new)
     +
     +static grub_extcmd_t grub_tpm2_protector_init_cmd;
     +static grub_extcmd_t grub_tpm2_protector_clear_cmd;
    -+static struct grub_tpm2_protector_context grub_tpm2_protector_ctx = { 0 };
    ++static struct grub_tpm2_protector_context grub_tpm2_protector_ctx = {0};
     +
     +static grub_err_t
     +grub_tpm2_protector_srk_read_file (const char *filepath, void **buffer,
    @@ grub-core/tpm2/module.c (new)
     +    {
     +      /* Push errno from grub_file_open() into the error message stack */
     +      grub_error_push();
    -+      err = grub_error (GRUB_ERR_FILE_NOT_FOUND,
    -+                  N_("Could not open file: %s\n"),
    -+                  filepath);
    ++      err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("Could not open file: 
%s\n"), filepath);
     +      goto error;
     +    }
     +
     +  file_size = grub_file_size (file);
     +  if (file_size == 0)
     +    {
    -+      err = grub_error (GRUB_ERR_OUT_OF_RANGE,
    -+                  N_("Could not read file size: %s"),
    -+                  filepath);
    ++      err = grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Could not read file 
size: %s"), filepath);
     +      goto error;
     +    }
     +
     +  read_buffer = grub_malloc (file_size);
     +  if (read_buffer == NULL)
     +    {
    -+      err = grub_error (GRUB_ERR_OUT_OF_MEMORY,
    -+                  N_("Could not allocate buffer for %s"),
    -+                  filepath);
    ++      err = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("Could not allocate 
buffer for %s"), filepath);
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/module.c (new)
     +  if (read_n != file_size)
     +    {
     +      grub_free (read_buffer);
    -+      err = grub_error (GRUB_ERR_FILE_READ_ERROR,
    -+                  N_("Could not retrieve file contents: %s"),
    -+                  filepath);
    ++      err = grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Could not retrieve 
file contents: %s"), filepath);
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/module.c (new)
     +
     +  err = GRUB_ERR_NONE;
     +
    -+error:
    ++ error:
     +  if (file != NULL)
     +    grub_file_close (file);
     +
    @@ grub-core/tpm2/module.c (new)
     +static grub_err_t
     +grub_tpm2_protector_srk_unmarshal_keyfile (void *sealed_key,
     +                                     grub_size_t sealed_key_size,
    -+                                     TPM2_SEALED_KEY *sk)
    ++                                     tpm2_sealed_key_t *sk)
     +{
     +  struct grub_tpm2_buffer buf;
     +
     +  grub_tpm2_buffer_init (&buf);
     +  if (sealed_key_size > buf.cap)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Sealed key larger than %" PRIuGRUB_SIZE " bytes"),
    -+                 buf.cap);
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Sealed key larger than 
%" PRIuGRUB_SIZE " bytes"), buf.cap);
     +
     +  grub_memcpy (buf.data, sealed_key, sealed_key_size);
     +  buf.size = sealed_key_size;
     +
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public);
    -+  grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private);
    ++  grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public);
    ++  grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private);
     +
    -+  if (buf.error)
    ++  if (buf.error != 0)
     +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Malformed TPM wire key 
file"));
     +
     +  return GRUB_ERR_NONE;
    @@ grub-core/tpm2/module.c (new)
     +                                     tpm2key_authpolicy_t *authpol_seq,
     +                                     grub_uint8_t *rsaparent,
     +                                     grub_uint32_t *parent,
    -+                                     TPM2_SEALED_KEY *sk)
    ++                                     tpm2_sealed_key_t *sk)
     +{
     +  asn1_node tpm2key = NULL;
     +  grub_uint8_t rsaparent_tmp;
    @@ grub-core/tpm2/module.c (new)
     +  grub_tpm2_buffer_init (&buf);
     +  if (sealed_pub_size + sealed_priv_size > buf.cap)
     +    {
    -+      err = grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                  N_("Sealed key larger than %" PRIuGRUB_SIZE " bytes"),
    -+                  buf.cap);
    ++      err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Sealed key larger than 
%" PRIuGRUB_SIZE " bytes"), buf.cap);
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/module.c (new)
     +
     +  buf.offset = 0;
     +
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public);
    -+  grub_tpm2_mu_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private);
    ++  grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public);
    ++  grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private);
     +
    -+  if (buf.error)
    ++  if (buf.error != 0)
     +    {
     +      err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Malformed TPM 2.0 key 
file"));
     +      goto error;
    @@ grub-core/tpm2/module.c (new)
     +
     +  err = GRUB_ERR_NONE;
     +
    -+error:
    ++ error:
     +  /* End the parsing */
     +  grub_tpm2key_end_parsing (tpm2key);
     +  grub_free (sealed_pub);
    @@ grub-core/tpm2/module.c (new)
     +  if (rc == TPM_RC_SUCCESS)
     +    return GRUB_ERR_NONE;
     +
    -+  return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+               N_("Failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 
0x%x)"),
    -+               srk_handle, rc);
    ++  return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Failed to retrieve SRK 
from 0x%x (TPM2_ReadPublic: 0x%x)"), srk_handle, rc);
     +}
     +
     +/* Get the SRK with the template */
    @@ grub-core/tpm2/module.c (new)
     +                       TPM_HANDLE *srk_handle)
     +{
     +  TPM_RC rc;
    -+  TPMT_PUBLIC_PARMS parms = { 0 };
    -+  TPMS_AUTH_COMMAND authCommand = { 0 };
    -+  TPM2B_SENSITIVE_CREATE inSensitive = { 0 };
    -+  TPM2B_PUBLIC inPublic = { 0 };
    -+  TPM2B_DATA outsideInfo = { 0 };
    -+  TPML_PCR_SELECTION creationPcr = { 0 };
    -+  TPM2B_PUBLIC outPublic = { 0 };
    -+  TPM2B_CREATION_DATA creationData = { 0 };
    -+  TPM2B_DIGEST creationHash = { 0 };
    -+  TPMT_TK_CREATION creationTicket = { 0 };
    -+  TPM2B_NAME srkName = { 0 };
    ++  TPMT_PUBLIC_PARMS parms = {0};
    ++  TPMS_AUTH_COMMAND authCommand = {0};
    ++  TPM2B_SENSITIVE_CREATE inSensitive = {0};
    ++  TPM2B_PUBLIC inPublic = {0};
    ++  TPM2B_DATA outsideInfo = {0};
    ++  TPML_PCR_SELECTION creationPcr = {0};
    ++  TPM2B_PUBLIC outPublic = {0};
    ++  TPM2B_CREATION_DATA creationData = {0};
    ++  TPM2B_DIGEST creationHash = {0};
    ++  TPMT_TK_CREATION creationTicket = {0};
    ++  TPM2B_NAME srkName = {0};
     +  TPM_HANDLE tmp_handle = 0;
     +
     +  inPublic.publicArea.type = srk_type.type;
    @@ grub-core/tpm2/module.c (new)
     +
     +  rc = TPM2_TestParms (&parms, NULL);
     +  if (rc != TPM_RC_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Unsupported SRK template (TPM2_TestParms: 0x%x)"),
    -+                 rc);
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unsupported SRK 
template (TPM2_TestParms: 0x%x)"), rc);
     +
     +  /* Create SRK */
     +  authCommand.sessionHandle = TPM_RS_PW;
    @@ grub-core/tpm2/module.c (new)
     +                     &creationData, &creationHash, &creationTicket,
     +                     &srkName, NULL);
     +  if (rc != TPM_RC_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_DEVICE,
    -+                 N_("Could not create SRK (TPM2_CreatePrimary: 0x%x)"),
    -+                 rc);
    ++    return grub_error (GRUB_ERR_BAD_DEVICE, N_("Could not create SRK 
(TPM2_CreatePrimary: 0x%x)"), rc);
     +
     +  *srk_handle = tmp_handle;
     +
     +  return GRUB_ERR_NONE;
     +}
     +
    -+/* Load the SRK from the persistent handle or create one with a given 
type of
    -+   template, and then associate the sealed key with the SRK
    -+   Return values:
    -+   * GRUB_ERR_NONE: Everything is fine.
    -+   * GRUB_ERR_BAD_ARGUMENT: The SRK doesn't match. Try another one.
    -+   * Other: Something went wrong.
    -+*/
    ++/*
    ++ * Load the SRK from the persistent handle or create one with a given 
type of
    ++ * template, and then associate the sealed key with the SRK
    ++ * Return values:
    ++ * - GRUB_ERR_NONE: Everything is fine.
    ++ * - GRUB_ERR_BAD_ARGUMENT: The SRK doesn't match. Try another one.
    ++ * - Other: Something went wrong.
    ++ */
     +static grub_err_t
     +grub_tpm2_protector_srk_load (const grub_srk_type_t srk_type,
    -+                        const TPM2_SEALED_KEY *sealed_key,
    ++                        const tpm2_sealed_key_t *sealed_key,
     +                        const TPM_HANDLE parent,
     +                        TPM_HANDLE *sealed_handle,
     +                        TPM_HANDLE *srk_handle)
     +{
    -+  TPMS_AUTH_COMMAND authCmd = { 0 };
    -+  TPM2B_NAME name = { 0 };
    ++  TPMS_AUTH_COMMAND authCmd = {0};
    ++  TPM2B_NAME name = {0};
     +  TPM_RC rc;
     +  grub_err_t err;
     +
    @@ grub-core/tpm2/module.c (new)
     +  authCmd.sessionHandle = TPM_RS_PW;
     +  rc = TPM2_Load (*srk_handle, &authCmd, &sealed_key->private, 
&sealed_key->public,
     +            sealed_handle, &name, NULL);
    -+  /* If TPM2_Load returns (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1), then 
it
    -+     implies the wrong SRK is used. */
    ++  /*
    ++   * If TPM2_Load returns (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1), then 
it
    ++   * implies the wrong SRK is used.
    ++   */
     +  if (rc == (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1))
     +    {
     +      err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("SRK not matched"));
    @@ grub-core/tpm2/module.c (new)
     +    }
     +  else if (rc != TPM_RC_SUCCESS)
     +    {
    -+      err = grub_error (GRUB_ERR_BAD_DEVICE,
    -+                  N_("Failed to load sealed key (TPM2_Load: 0x%x)"),
    -+                  rc);
    ++      err = grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to load sealed 
key (TPM2_Load: 0x%x)"), rc);
     +      goto error;
     +    }
     +
     +  return GRUB_ERR_NONE;
     +
    -+error:
    ++ error:
     +  if (!TPM_HT_IS_PERSISTENT (*srk_handle))
     +    TPM2_FlushContext (*srk_handle);
     +
    @@ grub-core/tpm2/module.c (new)
     +static const char *
     +srk_type_to_name (grub_srk_type_t srk_type)
     +{
    -+  if (srk_type.type == TPM_ALG_ECC)
    -+    {
    -+      switch (srk_type.detail.ecc_curve)
    -+        {
    -+    case TPM_ECC_NIST_P256:
    -+      return "ECC_NIST_P256";
    -+        }
    -+    }
    -+  else if (srk_type.type == TPM_ALG_RSA)
    -+   {
    -+      switch (srk_type.detail.rsa_bits)
    -+  {
    -+    case 2048:
    -+      return "RSA2048";
    -+  }
    -+   }
    ++  if (srk_type.type == TPM_ALG_ECC && srk_type.detail.ecc_curve == 
TPM_ECC_NIST_P256)
    ++    return "ECC_NIST_P256";
    ++  else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 
2048)
    ++    return "RSA2048";
     +
     +  return "Unknown";
     +}
     +
     +static grub_err_t
     +grub_tpm2_protector_load_key (const struct grub_tpm2_protector_context 
*ctx,
    -+                        const TPM2_SEALED_KEY *sealed_key,
    ++                        const tpm2_sealed_key_t *sealed_key,
     +                        const TPM_HANDLE parent_handle,
     +                        TPM_HANDLE *sealed_handle,
     +                        TPM_HANDLE *srk_handle)
    @@ grub-core/tpm2/module.c (new)
     +  return err;
     +
     +      grub_print_error ();
    -+      grub_printf_ (N_("Trying the specified SRK algorithm: %s\n"),
    -+              srk_type_to_name (ctx->srk_type));
    ++      grub_printf_ (N_("Trying the specified SRK algorithm: %s\n"), 
srk_type_to_name (ctx->srk_type));
     +      grub_errno = GRUB_ERR_NONE;
     +      *srk_handle = 0;
     +    }
    @@ grub-core/tpm2/module.c (new)
     +     fallback_srks[i].detail.ecc_curve == ctx->srk_type.detail.ecc_curve))
     +  continue;
     +
    -+      grub_printf_ (N_("Trying fallback %s template\n"),
    -+              srk_type_to_name (fallback_srks[i]));
    ++      grub_printf_ (N_("Trying fallback %s template\n"), srk_type_to_name 
(fallback_srks[i]));
     +
     +      *srk_handle = 0;
     +
    @@ grub-core/tpm2/module.c (new)
     +  TPML_PCR_SELECTION pcr_sel;
     +  TPM_RC rc;
     +
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &pcr_digest);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (cmd_buf, &pcr_sel);
    -+  if (cmd_buf->error)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Failed to unmarshal CommandPolicy for 
TPM2_PolicyPCR"));
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &pcr_digest);
    ++  grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (cmd_buf, &pcr_sel);
    ++  if (cmd_buf->error != 0)
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Failed to unmarshal 
CommandPolicy for TPM2_PolicyPCR"));
     +
     +  rc = TPM2_PolicyPCR (session, NULL, &pcr_digest, &pcr_sel, NULL);
     +  if (rc != TPM_RC_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_DEVICE,
    -+                 N_("Failed to submit PCR policy (TPM2_PolicyPCR: 0x%x)"),
    -+                 rc);
    ++    return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to submit PCR 
policy (TPM2_PolicyPCR: 0x%x)"), rc);
     +
     +  return GRUB_ERR_NONE;
     +}
    @@ grub-core/tpm2/module.c (new)
     +
     +  grub_tpm2_buffer_init (&buf);
     +  if (policy->cmd_policy_len > buf.cap)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("CommandPolicy larger than TPM buffer"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("CommandPolicy larger 
than TPM buffer"));
     +
     +  grub_memcpy (buf.data, policy->cmd_policy, policy->cmd_policy_len);
     +  buf.size = policy->cmd_policy_len;
    @@ grub-core/tpm2/module.c (new)
     +      err = grub_tpm2_protector_policypcr (session, &buf);
     +      break;
     +    default:
    -+      return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                   N_("Unknown TPM Command: 0x%x"), policy->cmd_code);
    ++      return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown TPM Command: 
0x%x"), policy->cmd_code);
     +    }
     +
     +  return err;
    @@ grub-core/tpm2/module.c (new)
     +      {
     +  .hash = ctx->bank,
     +  .sizeOfSelect = 3,
    -+  .pcrSelect = { 0 }
    ++  .pcrSelect = {0}
     +      },
     +    }
     +  };
    @@ grub-core/tpm2/module.c (new)
     +    TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], 
ctx->pcrs[i]);
     +
     +  grub_tpm2_buffer_pack_u16 (&buf, 0);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&buf, &pcr_sel);
    ++  grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&buf, &pcr_sel);
     +
    -+  if (buf.error)
    ++  if (buf.error != 0)
     +    return GRUB_ERR_BAD_ARGUMENT;
     +
     +  policy = grub_malloc (sizeof(struct tpm2key_policy));
    @@ grub-core/tpm2/module.c (new)
     +
     +  return GRUB_ERR_NONE;
     +
    -+error:
    ++ error:
     +  grub_free (policy);
     +
     +  return err;
    @@ grub-core/tpm2/module.c (new)
     +grub_tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE 
sealed_handle,
     +                      grub_uint8_t **key, grub_size_t *key_size)
     +{
    -+  TPMS_AUTH_COMMAND authCmd = { 0 };
    ++  TPMS_AUTH_COMMAND authCmd = {0};
     +  TPM2B_SENSITIVE_DATA data;
    -+  TPM2B_NONCE nonceCaller = { 0 };
    -+  TPMT_SYM_DEF symmetric = { 0 };
    ++  TPM2B_NONCE nonceCaller = {0};
    ++  TPMT_SYM_DEF symmetric = {0};
     +  TPMI_SH_AUTH_SESSION session;
     +  grub_uint8_t *key_out;
     +  TPM_RC rc;
    @@ grub-core/tpm2/module.c (new)
     +                        TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256,
     +                        &session, NULL, NULL);
     +  if (rc != TPM_RC_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_DEVICE,
    -+                 N_("Failed to start auth session (TPM2_StartAuthSession: 
0x%x)"),
    -+                 rc);
    ++    return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to start auth 
session (TPM2_StartAuthSession: 0x%x)"), rc);
     +
     +  /* Enforce the policy command sequence */
     +  err = grub_tpm2_protector_enforce_policy_seq (policy_seq, session);
    @@ grub-core/tpm2/module.c (new)
     +  rc = TPM2_Unseal (sealed_handle, &authCmd, &data, NULL);
     +  if (rc != TPM_RC_SUCCESS)
     +    {
    -+      err = grub_error (GRUB_ERR_BAD_DEVICE,
    -+                  N_("Failed to unseal sealed key (TPM2_Unseal: 0x%x)"),
    -+                  rc);
    ++      err = grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to unseal sealed 
key (TPM2_Unseal: 0x%x)"), rc);
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/module.c (new)
     +  key_out = grub_malloc (data.size);
     +  if (key_out == NULL)
     +    {
    -+      err = grub_error (GRUB_ERR_OUT_OF_MEMORY,
    -+                  N_("No memory left to allocate unlock key buffer"));
    ++      err = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("No memory left to 
allocate unlock key buffer"));
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/module.c (new)
     +
     +  err = GRUB_ERR_NONE;
     +
    -+error:
    ++ error:
     +  TPM2_FlushContext (session);
     +
     +  return err;
    @@ grub-core/tpm2/module.c (new)
     +grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context 
*ctx,
     +                           grub_uint8_t **key, grub_size_t *key_size)
     +{
    -+  TPM2_SEALED_KEY sealed_key = { 0 };
    ++  tpm2_sealed_key_t sealed_key = {0};
     +  void *file_bytes = NULL;
     +  grub_size_t file_size = 0;
     +  grub_uint8_t rsaparent = 0;
    @@ grub-core/tpm2/module.c (new)
     +   * Retrieve sealed key, parent handle, policy sequence, and authpolicy
     +   * sequence from the key file
     +  */
    -+  if (ctx->tpm2key)
    ++  if (ctx->tpm2key != NULL)
     +    {
     +      err = grub_tpm2_protector_srk_read_file (ctx->tpm2key, &file_bytes,
     +                                         &file_size);
    @@ grub-core/tpm2/module.c (new)
     +  if (err == GRUB_ERR_NONE)
     +    while (grub_error_pop ());
     +
    -+exit2:
    ++ exit2:
     +  TPM2_FlushContext (sealed_handle);
     +
     +  if (!TPM_HT_IS_PERSISTENT (srk_handle))
     +    TPM2_FlushContext (srk_handle);
     +
    -+exit1:
    ++ exit1:
     +  grub_tpm2key_free_policy_seq (policy_seq);
     +  grub_tpm2key_free_authpolicy_seq (authpol_seq);
     +  grub_free (file_bytes);
    @@ grub-core/tpm2/module.c (new)
     +}
     +
     +static grub_err_t
    -+grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context 
*ctx,
    -+                          grub_uint8_t **key, grub_size_t *key_size)
    ++grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context 
*ctx __attribute__ ((unused)),
    ++                          grub_uint8_t **key __attribute__ ((unused)),
    ++                          grub_size_t *key_size __attribute__ ((unused)))
     +{
    -+  (void)ctx;
    -+  (void)key;
    -+  (void)key_size;
    -+
    -+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
    -+               N_("NV Index mode is not implemented yet"));
    ++  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("NV Index mode is 
not implemented yet"));
     +}
     +
     +static grub_err_t
    @@ grub-core/tpm2/module.c (new)
     +{
     +  /* Expect a call to tpm2_protector_init before anybody tries to use us 
*/
     +  if (grub_tpm2_protector_ctx.mode == GRUB_TPM2_PROTECTOR_MODE_UNSET)
    -+    return grub_error (GRUB_ERR_INVALID_COMMAND,
    -+                 N_("Cannot use TPM2 key protector without initializing "
    -+                    "it, call tpm2_protector_init first"));
    ++    return grub_error (GRUB_ERR_INVALID_COMMAND, N_("Cannot use TPM2 key 
protector without initializing it, call tpm2_protector_init first"));
     +
     +  if (key == NULL || key_size == NULL)
     +    return GRUB_ERR_BAD_ARGUMENT;
    @@ grub-core/tpm2/module.c (new)
     +  /* Checks for SRK mode */
     +  if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK &&
     +      (ctx->keyfile == NULL && ctx->tpm2key == NULL))
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("In SRK mode, a key file must be specified: "
    -+                    "--tpm2key/-T or --keyfile/-k"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("In SRK mode, a key file 
must be specified: --tpm2key/-T or --keyfile/-k"));
     +
     +  if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK &&
     +      (ctx->keyfile != NULL && ctx->tpm2key != NULL))
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("In SRK mode, please specify a key file with "
    -+                    "only --tpm2key/-T or --keyfile/-k"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("In SRK mode, please 
specify a key file with only --tpm2key/-T or --keyfile/-k"));
     +
     +  if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->nv != 0)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("In SRK mode, an NV Index cannot be specified"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("In SRK mode, an NV 
Index cannot be specified"));
     +
     +  /* Checks for NV mode */
     +  if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->nv == 0)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("In NV Index mode, an NV Index must be specified: "
    -+                     "--nvindex or -n"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("In NV Index mode, an NV 
Index must be specified: --nvindex or -n"));
     +
     +  if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV &&
     +      (ctx->tpm2key != NULL || ctx->keyfile != NULL))
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("In NV Index mode, a keyfile cannot be specified"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("In NV Index mode, a 
keyfile cannot be specified"));
     +
     +  if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->srk != 0)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("In NV Index mode, an SRK cannot be specified"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("In NV Index mode, an 
SRK cannot be specified"));
     +
     +  if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV &&
     +      ctx->srk_type.type != TPM_ALG_ERROR)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("In NV Index mode, an asymmetric key type cannot be "
    -+                    "specified"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("In NV Index mode, an 
asymmetric key type cannot be specified"));
     +
     +  /* Defaults assignment */
     +  if (ctx->bank == TPM_ALG_ERROR)
    @@ grub-core/tpm2/module.c (new)
     +
     +  *file = grub_strdup (value);
     +  if (*file == NULL)
    -+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
    -+                 N_("No memory to duplicate file path"));
    ++    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("No memory to duplicate 
file path"));
     +
     +  return GRUB_ERR_NONE;
     +}
    @@ grub-core/tpm2/module.c (new)
     +  else if (grub_strcmp (value, "nv") == 0)
     +    *mode = GRUB_TPM2_PROTECTOR_MODE_NV;
     +  else
    -+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
    -+                 N_("Value '%s' is not a valid TPM2 key protector mode"),
    -+                 value);
    ++    return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Value '%s' is not a 
valid TPM2 key protector mode"), value);
     +
     +  return GRUB_ERR_NONE;
     +}
    @@ grub-core/tpm2/module.c (new)
     +  grub_err_t err;
     +
     +  if (argc)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("The TPM2 key protector does not accept any "
    -+                    "non-option arguments (i.e., like -o and/or --option "
    -+                    "only)"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("The TPM2 key protector 
does not accept any non-option arguments (i.e., like -o and/or --option 
only)"));
     +
     +  grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
     +  grub_memset (&grub_tpm2_protector_ctx, 0, sizeof 
(grub_tpm2_protector_ctx));
    @@ grub-core/tpm2/module.c (new)
     +                                 char **args __attribute__ ((unused)))
     +{
     +  if (argc)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("tpm2_key_protector_clear accepts no arguments"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
N_("tpm2_key_protector_clear accepts no arguments"));
     +
     +  grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
     +  grub_memset (&grub_tpm2_protector_ctx, 0, sizeof 
(grub_tpm2_protector_ctx));
    @@ grub-core/tpm2/module.c (new)
     +    .recover_key = grub_tpm2_protector_recover_key
     +  };
     +
    -+GRUB_MOD_INIT (tpm2)
    ++GRUB_MOD_INIT (tpm2_key_protector)
     +{
     +  grub_tpm2_protector_init_cmd =
     +    grub_register_extcmd ("tpm2_key_protector_init",
    @@ grub-core/tpm2/module.c (new)
     +  grub_key_protector_register (&grub_tpm2_key_protector);
     +}
     +
    -+GRUB_MOD_FINI (tpm2)
    ++GRUB_MOD_FINI (tpm2_key_protector)
     +{
     +  grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
    -+  grub_memset (&grub_tpm2_protector_ctx, 0, sizeof 
(grub_tpm2_protector_ctx));
     +
     +  grub_key_protector_unregister (&grub_tpm2_key_protector);
     +  grub_unregister_extcmd (grub_tpm2_protector_clear_cmd);
     +  grub_unregister_extcmd (grub_tpm2_protector_init_cmd);
     +}
     
    - ## grub-core/tpm2/tpm2key.asn (new) ##
    + ## grub-core/commands/tpm2_key_protector/tpm2.h (new) ##
    +@@
    ++/*
    ++ *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
    ++ *  Copyright (C) 2022 Microsoft Corporation
    ++ *
    ++ *  GRUB is free software: you can redistribute it and/or modify
    ++ *  it under the terms of the GNU General Public License as published by
    ++ *  the Free Software Foundation, either version 3 of the License, or
    ++ *  (at your option) any later version.
    ++ *
    ++ *  GRUB is distributed in the hope that it will be useful,
    ++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ *  GNU General Public License for more details.
    ++ *
    ++ *  You should have received a copy of the GNU General Public License
    ++ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    ++ */
    ++
    ++#ifndef GRUB_TPM2_TPM2_HEADER
    ++#define GRUB_TPM2_TPM2_HEADER 1
    ++
    ++#include <tss2_types.h>
    ++#include <tss2_structs.h>
    ++#include <tpm2_cmd.h>
    ++
    ++/* Well-Known Windows SRK handle */
    ++#define TPM2_SRK_HANDLE 0x81000001
    ++
    ++struct tpm2_sealed_key {
    ++  TPM2B_PUBLIC  public;
    ++  TPM2B_PRIVATE private;
    ++};
    ++typedef struct tpm2_sealed_key tpm2_sealed_key_t;
    ++
    ++#endif /* ! GRUB_TPM2_TPM2_HEADER */
    +
    + ## grub-core/commands/tpm2_key_protector/tpm2_args.h (new) ##
     @@
    ++/*
    ++ *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
    ++ *  Copyright (C) 2022 Microsoft Corporation
    ++ *
    ++ *  GRUB is free software: you can redistribute it and/or modify
    ++ *  it under the terms of the GNU General Public License as published by
    ++ *  the Free Software Foundation, either version 3 of the License, or
    ++ *  (at your option) any later version.
    ++ *
    ++ *  GRUB is distributed in the hope that it will be useful,
    ++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ *  GNU General Public License for more details.
    ++ *
    ++ *  You should have received a copy of the GNU General Public License
    ++ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    ++ */
    ++
    ++#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER
    ++#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1
    ++
    ++#include <grub/err.h>
    ++
    ++#include "tpm2.h"
    ++
    ++struct grub_srk_type
    ++{
    ++  TPMI_ALG_PUBLIC type;
    ++  union {
    ++    TPM_KEY_BITS rsa_bits;
    ++    TPM_ECC_CURVE ecc_curve;
    ++  } detail;
    ++};
    ++typedef struct grub_srk_type grub_srk_type_t;
    ++
    ++grub_err_t
    ++grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
    ++                          grub_uint8_t *pcr_count);
    ++
    ++grub_err_t
    ++grub_tpm2_protector_parse_asymmetric (const char *value,
    ++                                grub_srk_type_t *srk_type);
    ++
    ++grub_err_t
    ++grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank);
    ++
    ++grub_err_t
    ++grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE 
*handle);
    ++
    ++#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */
    +
    + ## grub-core/commands/tpm2_key_protector/tpm2key.asn (new) ##
    +@@
    ++--
    ++-- GRUB: GRand Unified Bootloader
    ++-- Copyright (C) 2024 Free Software Foundation, Inc.
    ++--
    ++-- GRUB is free software: you can redistribute it and/or modify
    ++-- it under the terms of the GNU General Public License as published by
    ++-- the Free Software Foundation, either version 3 of the License, or
    ++-- (at your option) any later version.
     +--
    -+-- TPM 2.0 key file format
    ++-- GRUB is distributed in the hope that it will be useful,
    ++-- but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++-- GNU General Public License for more details.
    ++--
    ++-- You should have received a copy of the GNU General Public License
    ++-- along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    ++--
    ++-- This file describes TPM 2.0 Key File format for libtasn1.
     +--  To generate tpm2key_asn1_tab.c: asn1Parser tpm2key.asn
     +--
     +TPM2KEY {}
    @@ grub-core/tpm2/tpm2key.asn (new)
     +
     +END
     
    - ## grub-core/tpm2/tpm2key.c (new) ##
    + ## grub-core/commands/tpm2_key_protector/tpm2key.c (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2023 SUSE LLC
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ grub-core/tpm2/tpm2key.c (new)
     +#include <grub/list.h>
     +#include <grub/misc.h>
     +#include <grub/mm.h>
    -+#include <grub/tpm2/buffer.h>
    -+#include <grub/tpm2/tpm2key.h>
    ++
    ++#include <tss2_buffer.h>
    ++
    ++#include "tpm2key.h"
     +
     +extern asn1_static_node tpm2key_asn1_tab[];
     +const char *sealed_key_oid = "2.23.133.10.1.5";
    @@ grub-core/tpm2/tpm2key.c (new)
     +  if (ret != ASN1_SUCCESS)
     +    return ret;
     +
    ++  /*
    ++   * ASN.1 INTEGER is encoded in the following format:
    ++   *
    ++   * TAG LENGTH OCTECTS
    ++   *
    ++   * The integer TAG is 02 and LENGTH is the number of followed OCTECTS in
    ++   * big endian. For example:
    ++   *
    ++   *    0x1: 02 01 01
    ++   * 0xabcd: 02 02 ab cd
    ++   *
    ++   * To decribe 0x1, it only takes 1 octect, so LENGTH is 0x01 and the
    ++   * octect is 0x01. On the other hand, 0xabcd requires 2 octects: 'ab" 
and
    ++   * 'cd', so LENGTH is 0x02.
    ++   *
    ++   * This function only expects a uint32 integer, so it rejects any 
integer
    ++   * containing more than 4 octects.
    ++   */
     +  if (data_size > 4)
     +    {
     +      ret = ASN1_MEM_ERROR;
     +      goto error;
     +    }
     +
    -+  /* convert the big-endian integer to host uint32 */
    -+  ptr = (grub_uint8_t *)&tmp + (4 - data_size);
    ++  /* Copy the octects into 'tmp' to make it a big-endian uint32 */
    ++  ptr = (grub_uint8_t *) &tmp + (4 - data_size);
     +  grub_memcpy (ptr, data, data_size);
    ++
    ++  /* Convert the big-endian integer to host uint32 */
     +  tmp = grub_be_to_cpu32 (tmp);
     +
     +  *out = tmp;
    -+error:
    ++ error:
     +  if (data)
     +    grub_free (data);
     +  return ret;
    @@ grub-core/tpm2/tpm2key.c (new)
     +   */
     +  ret = asn1_array2tree (tpm2key_asn1_tab, &tpm2key_asn1, NULL);
     +  if (ret != ASN1_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Failed to parse TPM2KEY ASN.1 array"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Failed to parse TPM2KEY 
ASN.1 array"));
     +
     +  ret = asn1_create_element (tpm2key_asn1, "TPM2KEY.TPMKey", &tpm2key);
     +  if (ret != ASN1_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Failed to create TPM2KEY.TPMKey"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Failed to create 
TPM2KEY.TPMKey"));
     +
     +  ret = asn1_der_decoding (&tpm2key, data, size, NULL);
     +  if (ret != ASN1_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Failed to decode TPM2KEY DER"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Failed to decode 
TPM2KEY DER"));
     +
     +  /* Check if 'type' is Sealed Key or not */
     +  ret = asn1_allocate_and_read (tpm2key, "type", &type_oid, 
&type_oid_size);
     +  if (ret != ASN1_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
    -+                 N_("Not a valid TPM2KEY file"));
    ++    return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("Not a valid TPM2KEY 
file"));
     +
     +  if (grub_memcmp (sealed_key_oid, type_oid, type_oid_size) != 0)
     +    {
    -+      err = grub_error (GRUB_ERR_BAD_FILE_TYPE,
    -+                  N_("Not a valid TPM2KEY file"));
    ++      err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("Not a valid TPM2KEY 
file"));
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/tpm2key.c (new)
     +  ret = asn1_read_value (tpm2key, "secret", NULL, &tmp_size);
     +  if (ret != ASN1_ELEMENT_NOT_FOUND)
     +    {
    -+      err = grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                  N_("\"secret\" not allowed for Sealed Key"));
    ++      err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("\"secret\" not allowed 
for Sealed Key"));
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/tpm2key.c (new)
     +
     +  err = GRUB_ERR_NONE;
     +
    -+error:
    ++ error:
     +  grub_free (type_oid);
     +  grub_free (empty_auth);
     +
    @@ grub-core/tpm2/tpm2key.c (new)
     +
     +  ret = asn1_allocate_and_read (tpm2key, name, data, size);
     +  if (ret != ASN1_SUCCESS)
    -+    return grub_error (GRUB_ERR_READ_ERROR,
    -+                 N_("Failed to retrieve %s"),
    -+                 name);
    ++    return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve %s"), 
name);
     +
     +  return GRUB_ERR_NONE;
     +}
    @@ grub-core/tpm2/tpm2key.c (new)
     +}
     +
     +/*
    ++ * The maximum and minimum number of elements for 'policy' and 
'authPolicy' sequences
    ++ *
    ++ * Although there is no limit for the number of sequences elements, we 
set the upper
    ++ * bound to 99 to make it easier to implement the code.
    ++ *
    ++ * Any 'policy' or 'authPolicy' contains more than 99 commands/policies 
would become
    ++ * extremely complex to manage so it is impractical to support such use 
case.
    ++ */
    ++#define TPM2KEY_ELEMENTS_MAX 99
    ++#define TPM2KEY_ELEMENTS_MIN 1
    ++
    ++/*
     + * The string to fetch 'Policy' from 'authPolicy':
     + *   authPolicy.?XX.Policy
     + */
    @@ grub-core/tpm2/tpm2key.c (new)
     +   * in practice, it takes one or two policy commands to unseal the key,
     +   * so the 99 commands limit is more than enough.
     +   */
    -+  if (policy_n > 100 || policy_n < 1)
    ++  if (policy_n > TPM2KEY_ELEMENTS_MAX || policy_n < TPM2KEY_ELEMENTS_MIN)
     +    return ASN1_VALUE_NOT_VALID;
     +
     +  /*
    @@ grub-core/tpm2/tpm2key.c (new)
     +
     +  return ASN1_SUCCESS;
     +
    -+error:
    -+  if (policy)
    ++ error:
    ++  if (policy != NULL)
     +    {
     +      grub_free (policy->cmd_policy);
     +      grub_free (policy);
    @@ grub-core/tpm2/tpm2key.c (new)
     +    return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve 
authPolicy"));
     +
     +  /* Limit the number of authPolicy elements to two digits (99) */
    -+  if (authpol_n > 100 || authpol_n < 1)
    -+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
    -+                 N_("Invalid number of authPolicy elements"));
    ++  if (authpol_n > TPM2KEY_ELEMENTS_MAX || authpol_n < 
TPM2KEY_ELEMENTS_MIN)
    ++    return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Invalid number of 
authPolicy elements"));
     +
     +  /*
     +   * Iterate the authPolicy elements backwards since grub_list_push() 
prepends
    @@ grub-core/tpm2/tpm2key.c (new)
     +    authpol = grub_zalloc (sizeof (struct tpm2key_authpolicy));
     +    if (authpol == NULL)
     +      {
    -+  err = grub_error (GRUB_ERR_OUT_OF_MEMORY,
    -+                    N_("Failed to allocate memory for authPolicy"));
    ++  err = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("Failed to allocate memory 
for authPolicy"));
     +  goto error;
     +      }
     +    grub_snprintf (authpol_pol, AUTHPOLICY_POL_MAX, 
"authPolicy.?%d.Policy", i);
    @@ grub-core/tpm2/tpm2key.c (new)
     +    ret = tpm2key_get_policy_seq (tpm2key, authpol_pol, 
&authpol->policy_seq);
     +    if (ret != ASN1_SUCCESS)
     +      {
    -+        err = grub_error (GRUB_ERR_READ_ERROR,
    -+                    N_("Failed to retrieve policy from authPolicy"));
    ++        err = grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve 
policy from authPolicy"));
     +        goto error;
     +      }
     +
    @@ grub-core/tpm2/tpm2key.c (new)
     +
     +  return GRUB_ERR_NONE;
     +
    -+error:
    -+  if (authpol)
    ++ error:
    ++  if (authpol != NULL)
     +    {
     +      grub_tpm2key_free_policy_seq (authpol->policy_seq);
     +      grub_free (authpol);
    @@ grub-core/tpm2/tpm2key.c (new)
     +    }
     +}
     
    - ## grub-core/tpm2/tpm2key_asn1_tab.c (new) ##
    -@@
    -+/*
    -+ * This file is generated by 'asn1Parser tpm2key.asn' and the '#include'
    -+ * headers are replaced with the ones in grub2.
    -+ * - 'grub/mm.h' for the definition of 'NULL'
    -+ * - 'libtasn1.h' for the definition of 'asn1_static_node'
    -+ */
    -+
    -+#include <grub/mm.h>
    -+#include <libtasn1.h>
    -+
    -+const asn1_static_node tpm2key_asn1_tab[] = {
    -+  { "TPM2KEY", 536875024, NULL },
    -+  { NULL, 1073741836, NULL },
    -+  { "TPMPolicy", 1610612741, NULL },
    -+  { "CommandCode", 1610620931, NULL },
    -+  { NULL, 2056, "0"},
    -+  { "CommandPolicy", 536879111, NULL },
    -+  { NULL, 2056, "1"},
    -+  { "TPMAuthPolicy", 1610612741, NULL },
    -+  { "Name", 1610637346, NULL },
    -+  { NULL, 2056, "0"},
    -+  { "Policy", 536879115, NULL },
    -+  { NULL, 1073743880, "1"},
    -+  { NULL, 2, "TPMPolicy"},
    -+  { "TPMKey", 536870917, NULL },
    -+  { "type", 1073741836, NULL },
    -+  { "emptyAuth", 1610637316, NULL },
    -+  { NULL, 2056, "0"},
    -+  { "policy", 1610637323, NULL },
    -+  { NULL, 1073743880, "1"},
    -+  { NULL, 2, "TPMPolicy"},
    -+  { "secret", 1610637319, NULL },
    -+  { NULL, 2056, "2"},
    -+  { "authPolicy", 1610637323, NULL },
    -+  { NULL, 1073743880, "3"},
    -+  { NULL, 2, "TPMAuthPolicy"},
    -+  { "description", 1610637346, NULL },
    -+  { NULL, 2056, "4"},
    -+  { "rsaParent", 1610637316, NULL },
    -+  { NULL, 2056, "5"},
    -+  { "parent", 1073741827, NULL },
    -+  { "pubkey", 1073741831, NULL },
    -+  { "privkey", 7, NULL },
    -+  { NULL, 0, NULL }
    -+};
    -
    - ## include/grub/tpm2/internal/args.h (new) ##
    -@@
    -+/*
    -+ *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    -+ *
    -+ *  GRUB is free software: you can redistribute it and/or modify
    -+ *  it under the terms of the GNU General Public License as published by
    -+ *  the Free Software Foundation, either version 3 of the License, or
    -+ *  (at your option) any later version.
    -+ *
    -+ *  GRUB is distributed in the hope that it will be useful,
    -+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    -+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -+ *  GNU General Public License for more details.
    -+ *
    -+ *  You should have received a copy of the GNU General Public License
    -+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    -+ */
    -+
    -+#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER
    -+#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1
    -+
    -+#include <grub/err.h>
    -+#include <grub/tpm2/tpm2.h>
    -+
    -+struct grub_srk_type
    -+{
    -+  TPMI_ALG_PUBLIC type;
    -+  union {
    -+    TPM_KEY_BITS rsa_bits;
    -+    TPM_ECC_CURVE ecc_curve;
    -+  } detail;
    -+};
    -+typedef struct grub_srk_type grub_srk_type_t;
    -+
    -+grub_err_t
    -+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
    -+                          grub_uint8_t *pcr_count);
    -+
    -+grub_err_t
    -+grub_tpm2_protector_parse_asymmetric (const char *value,
    -+                                grub_srk_type_t *srk_type);
    -+
    -+grub_err_t
    -+grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank);
    -+
    -+grub_err_t
    -+grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE 
*handle);
    -+
    -+#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */
    -
    - ## include/grub/tpm2/tpm2key.h (new) ##
    + ## grub-core/commands/tpm2_key_protector/tpm2key.h (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2023 SUSE LLC
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ include/grub/tpm2/tpm2key.h (new)
     +grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq);
     +
     +#endif /* GRUB_TPM2_TPM2KEY_HEADER */
    +
    + ## grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c (new) ##
    +@@
    ++/*
    ++ *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
    ++ *
    ++ *  GRUB is free software: you can redistribute it and/or modify
    ++ *  it under the terms of the GNU General Public License as published by
    ++ *  the Free Software Foundation, either version 3 of the License, or
    ++ *  (at your option) any later version.
    ++ *
    ++ *  GRUB is distributed in the hope that it will be useful,
    ++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ++ *  GNU General Public License for more details.
    ++ *
    ++ *  You should have received a copy of the GNU General Public License
    ++ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
    ++ */
    ++
    ++/*
    ++ *  This file is generated by 'asn1Parser tpm2key.asn' and the '#include'
    ++ *  headers are replaced with the ones in grub2.
    ++ *  - 'grub/mm.h' for the definition of 'NULL'
    ++ *  - 'libtasn1.h' for the definition of 'asn1_static_node'
    ++ */
    ++
    ++#include <grub/mm.h>
    ++#include <libtasn1.h>
    ++
    ++const asn1_static_node tpm2key_asn1_tab[] = {
    ++  { "TPM2KEY", 536875024, NULL },
    ++  { NULL, 1073741836, NULL },
    ++  { "TPMPolicy", 1610612741, NULL },
    ++  { "CommandCode", 1610620931, NULL },
    ++  { NULL, 2056, "0"},
    ++  { "CommandPolicy", 536879111, NULL },
    ++  { NULL, 2056, "1"},
    ++  { "TPMAuthPolicy", 1610612741, NULL },
    ++  { "Name", 1610637346, NULL },
    ++  { NULL, 2056, "0"},
    ++  { "Policy", 536879115, NULL },
    ++  { NULL, 1073743880, "1"},
    ++  { NULL, 2, "TPMPolicy"},
    ++  { "TPMKey", 536870917, NULL },
    ++  { "type", 1073741836, NULL },
    ++  { "emptyAuth", 1610637316, NULL },
    ++  { NULL, 2056, "0"},
    ++  { "policy", 1610637323, NULL },
    ++  { NULL, 1073743880, "1"},
    ++  { NULL, 2, "TPMPolicy"},
    ++  { "secret", 1610637319, NULL },
    ++  { NULL, 2056, "2"},
    ++  { "authPolicy", 1610637323, NULL },
    ++  { NULL, 1073743880, "3"},
    ++  { NULL, 2, "TPMAuthPolicy"},
    ++  { "description", 1610637346, NULL },
    ++  { NULL, 2056, "4"},
    ++  { "rsaParent", 1610637316, NULL },
    ++  { NULL, 2056, "5"},
    ++  { "parent", 1073741827, NULL },
    ++  { "pubkey", 1073741831, NULL },
    ++  { "privkey", 7, NULL },
    ++  { NULL, 0, NULL }
    ++};
12:  2ea9e229d = 17:  5e8d2abed cryptodisk: Support key protectors
13:  0b8ec0df2 ! 18:  37c33fa02 util/grub-protect: Add new tool
    @@ Makefile.util.def: program = {
     +
     +  common = grub-core/kern/emu/argp_common.c;
     +  common = grub-core/osdep/init.c;
    -+  common = grub-core/tpm2/args.c;
    -+  common = grub-core/tpm2/buffer.c;
    -+  common = grub-core/tpm2/mu.c;
    -+  common = grub-core/tpm2/tpm2.c;
    -+  common = grub-core/tpm2/tpm2key_asn1_tab.c;
    ++  common = grub-core/lib/tss2/buffer.c;
    ++  common = grub-core/lib/tss2/tss2_mu.c;
    ++  common = grub-core/lib/tss2/tpm2_cmd.c;
    ++  common = grub-core/commands/tpm2_key_protector/args.c;
    ++  common = grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c;
     +  common = util/grub-protect.c;
     +  common = util/probe.c;
     +
    ++  cflags = '-I$(srcdir)/grub-core/lib/tss2 
-I$(srcdir)/grub-core/commands/tpm2_key_protector';
    ++
     +  ldadd = libgrubmods.a;
     +  ldadd = libgrubgcry.a;
     +  ldadd = libgrubkern.a;
    @@ util/grub-protect.c (new)
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    -+ *  Copyright (C) 2022 Microsoft Corporation
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2023 SUSE LLC
    ++ *  Copyright (C) 2022 Microsoft Corporation
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
     + *  it under the terms of the GNU General Public License as published by
    @@ util/grub-protect.c (new)
     +
     +#include <grub/emu/hostdisk.h>
     +#include <grub/emu/misc.h>
    -+#include <grub/tpm2/buffer.h>
    -+#include <grub/tpm2/internal/args.h>
    -+#include <grub/tpm2/mu.h>
    -+#include <grub/tpm2/tcg2.h>
    -+#include <grub/tpm2/tpm2.h>
    ++
     +#include <grub/util/misc.h>
     +
    ++#include <tss2_buffer.h>
    ++#include <tss2_mu.h>
    ++#include <tcg2.h>
    ++#include <tpm2_args.h>
    ++#include <tpm2.h>
    ++
     +#pragma GCC diagnostic ignored "-Wmissing-prototypes"
     +#pragma GCC diagnostic ignored "-Wmissing-declarations"
     +#include <argp.h>
    @@ util/grub-protect.c (new)
     +static grub_err_t
     +grub_protect_tpm2_seal (TPM2B_DIGEST *policyDigest, TPM_HANDLE srk,
     +                  grub_uint8_t *clearText, grub_size_t clearTextLength,
    -+                  TPM2_SEALED_KEY *sealed_key)
    ++                  tpm2_sealed_key_t *sealed_key)
     +{
     +  TPM_RC rc;
     +  TPMS_AUTH_COMMAND authCommand = { 0 };
    @@ util/grub-protect.c (new)
     +
     +static grub_err_t
     +grub_protect_tpm2_export_tpm2key (const struct grub_protect_args *args,
    -+                            TPM2_SEALED_KEY *sealed_key)
    ++                            tpm2_sealed_key_t *sealed_key)
     +{
     +  const char *sealed_key_oid = "2.23.133.10.1.5";
     +  asn1_node asn1_def = NULL;
    @@ util/grub-protect.c (new)
     +   */
     +  grub_tpm2_buffer_init (&pol_buf);
     +  grub_tpm2_buffer_pack_u16 (&pol_buf, 0);
    -+  grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&pol_buf, &pcr_sel);
    ++  grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&pol_buf, &pcr_sel);
     +
     +  grub_tpm2_buffer_init (&pub_buf);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&pub_buf, &sealed_key->public);
    ++  grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&pub_buf, &sealed_key->public);
     +  grub_tpm2_buffer_init (&priv_buf);
    -+  grub_tpm2_mu_TPM2B_Marshal (&priv_buf, sealed_key->private.size,
    ++  grub_Tss2_MU_TPM2B_Marshal (&priv_buf, sealed_key->private.size,
     +                        sealed_key->private.buffer);
     +  if (pub_buf.error != 0 || priv_buf.error != 0)
     +    return GRUB_ERR_BAD_ARGUMENT;
    @@ util/grub-protect.c (new)
     +    fprintf (stderr, _("Could not write tpm2key file (Error: %u).\n"),
     +       errno);
     +
    -+error:
    ++ error:
     +  grub_free (der_buf);
     +
     +  if (tpm2key)
    @@ util/grub-protect.c (new)
     +
     +static grub_err_t
     +grub_protect_tpm2_export_sealed_key (const char *filepath,
    -+                               TPM2_SEALED_KEY *sealed_key)
    ++                               tpm2_sealed_key_t *sealed_key)
     +{
     +  grub_err_t err;
     +  struct grub_tpm2_buffer buf;
     +
     +  grub_tpm2_buffer_init (&buf);
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&buf, &sealed_key->public);
    -+  grub_tpm2_mu_TPM2B_Marshal (&buf, sealed_key->private.size,
    ++  grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&buf, &sealed_key->public);
    ++  grub_Tss2_MU_TPM2B_Marshal (&buf, sealed_key->private.size,
     +                        sealed_key->private.buffer);
     +  if (buf.error != 0)
     +    return GRUB_ERR_BAD_ARGUMENT;
    @@ util/grub-protect.c (new)
     +  grub_size_t key_size;
     +  TPM_HANDLE srk;
     +  TPM2B_DIGEST policy_digest;
    -+  TPM2_SEALED_KEY sealed_key;
    ++  tpm2_sealed_key_t sealed_key;
     +
     +  err = grub_protect_tpm2_open_device (args->tpm2_device);
     +  if (err != GRUB_ERR_NONE)
    @@ util/grub-protect.c (new)
     +  if (err != GRUB_ERR_NONE)
     +    goto exit3;
     +
    -+  if (args->tpm2_tpm2key)
    ++  if (args->tpm2_tpm2key != 0)
     +    err = grub_protect_tpm2_export_tpm2key (args, &sealed_key);
     +  else
     +    err = grub_protect_tpm2_export_sealed_key (args->tpm2_outfile, 
&sealed_key);
     +  if (err != GRUB_ERR_NONE)
     +    goto exit3;
     +
    -+exit3:
    ++ exit3:
     +  TPM2_FlushContext (srk);
     +
    -+exit2:
    ++ exit2:
     +  grub_free (key);
     +
    -+exit1:
    ++ exit1:
     +  grub_protect_tpm2_close_device ();
     +
     +  return err;
    @@ util/grub-protect.c (new)
     +
     +  err = GRUB_ERR_NONE;
     +
    -+exit2:
    ++ exit2:
     +  TPM2_FlushContext (args->tpm2_srk);
     +
    -+exit1:
    ++ exit1:
     +  grub_protect_tpm2_close_device ();
     +
     +  return GRUB_ERR_NONE;
    @@ util/grub-protect.c (new)
     +  if (err != GRUB_ERR_NONE)
     +    goto exit;
     +
    -+exit:
    ++ exit:
     +  grub_protect_fini ();
     +
     +  return err;
14:  6408f8708 ! 19:  e7191a5d9 tpm2: Support authorized policy
    @@ Metadata
     Author: Gary Lin <glin@suse.com>
     
      ## Commit message ##
    -    tpm2: Support authorized policy
    +    tpm2_key_protector: Support authorized policy
     
         This commit handles the TPM2_PolicyAuthorize command from the key file
         in TPM 2.0 Key File format.
    @@ Commit message
         Signed-off-by: Gary Lin <glin@suse.com>
         Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
     
    - ## grub-core/tpm2/module.c ##
    -@@ grub-core/tpm2/module.c: grub_tpm2_protector_policypcr 
(TPMI_SH_AUTH_SESSION session,
    + ## grub-core/commands/tpm2_key_protector/module.c ##
    +@@ grub-core/commands/tpm2_key_protector/module.c: 
grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session,
        return GRUB_ERR_NONE;
      }
      
    @@ grub-core/tpm2/module.c: grub_tpm2_protector_policypcr 
(TPMI_SH_AUTH_SESSION ses
     +  TPM_RC rc;
     +  grub_err_t err;
     +
    -+  grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
    -+  grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
    -+  grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
    ++  grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
    ++  grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
    ++  grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
     +  if (cmd_buf->error != 0)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Failed to unmarshal the buffer for 
TPM2_PolicyAuthorize"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Failed to unmarshal the 
buffer for TPM2_PolicyAuthorize"));
     +
     +  /* Retrieve Policy Digest */
     +  rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL);
     +  if (rc != TPM_RC_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_DEVICE,
    -+                 N_("Failed to get policy digest (TPM2_PolicyGetDigest: 
0x%x)."),
    -+                 rc);
    ++    return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to get policy 
digest (TPM2_PolicyGetDigest: 0x%x)."), rc);
     +
     +  /* Calculate the digest of the polcy for VerifySignature */
     +  sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature);
     +  if (sig_hash == TPM_ALG_NULL)
    -+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -+                 N_("Failed to get the hash algorithm of the signature"));
    ++    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Failed to get the hash 
algorithm of the signature"));
     +
     +  rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash,
     +            TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
     +  if (rc != TPM_RC_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_DEVICE,
    -+                 N_("Failed to create PCR policy hash (TPM2_Hash: 0x%x)"),
    -+                 rc);
    ++    return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to create PCR 
policy hash (TPM2_Hash: 0x%x)"), rc);
     +
     +  /* Load the public key */
     +  rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER,
     +                    &pubkey_handle, &pubname, NULL);
     +  if (rc != TPM_RC_SUCCESS)
    -+    return grub_error (GRUB_ERR_BAD_DEVICE,
    -+                 N_("Failed to load public key (TPM2_LoadExternal: 
0x%x)"),
    -+                 rc);
    ++    return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to load public key 
(TPM2_LoadExternal: 0x%x)"), rc);
     +
     +  /* Verify the signature against the public key and the policy digest */
     +  rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, 
&signature,
     +                       &verification_ticket, NULL);
     +  if (rc != TPM_RC_SUCCESS)
     +    {
    -+      err = grub_error (GRUB_ERR_BAD_DEVICE,
    -+                  N_("Failed to verify signature (TPM2_VerifySignature: 
0x%x)"),
    -+                  rc);
    ++      err = grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to verify 
signature (TPM2_VerifySignature: 0x%x)"), rc);
     +      goto error;
     +    }
     +
    @@ grub-core/tpm2/module.c: grub_tpm2_protector_policypcr 
(TPMI_SH_AUTH_SESSION ses
     +                       &verification_ticket, NULL);
     +  if (rc != TPM_RC_SUCCESS)
     +    {
    -+      err = grub_error (GRUB_ERR_BAD_DEVICE,
    -+                  N_("Failed to authorize PCR policy 
(TPM2_PolicyAuthorize: 0x%x)"),
    -+                  rc);
    ++      err = grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to authorize PCR 
policy (TPM2_PolicyAuthorize: 0x%x)"), rc);
     +      goto error;
     +    }
     +
     +  err = GRUB_ERR_NONE;
     +
    -+error:
    ++ error:
     +  TPM2_FlushContext (pubkey_handle);
     +
     +  return err;
    @@ grub-core/tpm2/module.c: grub_tpm2_protector_policypcr 
(TPMI_SH_AUTH_SESSION ses
      static grub_err_t
      grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, 
TPMI_SH_AUTH_SESSION session)
      {
    -@@ grub-core/tpm2/module.c: grub_tpm2_protector_enforce_policy 
(tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO
    +@@ grub-core/commands/tpm2_key_protector/module.c: 
grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO
          case TPM_CC_PolicyPCR:
            err = grub_tpm2_protector_policypcr (session, &buf);
            break;
    @@ grub-core/tpm2/module.c: grub_tpm2_protector_enforce_policy 
(tpm2key_policy_t po
     +      err = grub_tpm2_protector_policyauthorize (session, &buf);
     +      break;
          default:
    -       return grub_error (GRUB_ERR_BAD_ARGUMENT,
    -                    N_("Unknown TPM Command: 0x%x"), policy->cmd_code);
    +       return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown TPM Command: 
0x%x"), policy->cmd_code);
    +     }
15:  e1a5ace39 ! 20:  8543bec1c tpm2: Implement NV index
    @@ Metadata
     Author: Patrick Colp <patrick.colp@oracle.com>
     
      ## Commit message ##
    -    tpm2: Implement NV index
    +    tpm2_key_protector: Implement NV index
     
         Currently with the TPM2 protector, only SRK mode is supported and
         NV index support is just a stub. Implement the NV index option.
    @@ Commit message
         Signed-off-by: Gary Lin <glin@suse.com>
         Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
     
    - ## grub-core/tpm2/module.c ##
    -@@ grub-core/tpm2/module.c: static grub_err_t
    - grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context 
*ctx,
    -                           grub_uint8_t **key, grub_size_t *key_size)
    + ## grub-core/commands/tpm2_key_protector/module.c ##
    +@@ grub-core/commands/tpm2_key_protector/module.c: 
grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
    + }
    + 
    + static grub_err_t
    +-grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context 
*ctx __attribute__ ((unused)),
    +-                          grub_uint8_t **key __attribute__ ((unused)),
    +-                          grub_size_t *key_size __attribute__ ((unused)))
    ++grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context 
*ctx,
    ++                          grub_uint8_t **key, grub_size_t *key_size)
      {
    --  (void)ctx;
    --  (void)key;
    --  (void)key_size;
    +-  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("NV Index mode is 
not implemented yet"));
     +  TPM_HANDLE sealed_handle = ctx->nv;
     +  tpm2key_policy_t policy_seq = NULL;
     +  grub_err_t err;
    @@ grub-core/tpm2/module.c: static grub_err_t
     +  if (err == GRUB_ERR_NONE)
     +    while (grub_error_pop ());
     +
    -+exit:
    ++ exit:
     +  TPM2_FlushContext (sealed_handle);
    - 
    --  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
    --               N_("NV Index mode is not implemented yet"));
    ++
     +  grub_tpm2key_free_policy_seq (policy_seq);
     +
     +  return err;
16:  a4e688f8f = 21:  4fdd0da55 cryptodisk: Fallback to passphrase
17:  e8edabbb8 = 22:  fa2ed9dc6 cryptodisk: wipe out the cached keys from 
protectors
18:  06613ec8e = 23:  daa2fe5d6 diskfilter: look up cryptodisk devices first
19:  25427d5b0 ! 24:  7622fa1bd tpm2: Enable tpm2 module for grub-emu
    @@ Metadata
     Author: Gary Lin <glin@suse.com>
     
      ## Commit message ##
    -    tpm2: Enable tpm2 module for grub-emu
    +    tpm2_key_protector: Add grub-emu support
     
    -    As a preparation to test TPM 2.0 TSS stack with grub-emu, the new
    +    As a preparation to test tpm2_key_protector with grub-emu, the new
         option, --tpm-device, is introduced to specify the TPM device for
         grub-emu so that grub-emu can share the emulated TPM device with
         the host.
     
         Since grub-emu can directly access the device node on host, it's easy 
to
         implement the essential TCG2 command submission function with the
    -    read/write functions and enable tpm2 module for grub-emu, so that we 
can
    -    further test TPM key unsealing with grub-emu.
    +    read/write functions and enable tpm2_key_protector module for grub-emu,
    +    so that we can further test TPM2 key unsealing with grub-emu.
     
         Signed-off-by: Gary Lin <glin@suse.com>
         Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
     
      ## grub-core/Makefile.core.def ##
     @@ grub-core/Makefile.core.def: module = {
    -   common = tpm2/tpm2key.c;
    -   common = tpm2/tpm2key_asn1_tab.c;
    -   efi = tpm2/tcg2.c;
    -+  emu = tpm2/tcg2-emu.c;
    +   common = lib/tss2/tpm2_cmd.c;
    +   common = lib/tss2/tss2.c;
    +   efi = lib/efi/tcg2.c;
    ++  emu = lib/tss2/tcg2_emu.c;
        enable = efi;
     +  enable = emu;
    -   cppflags = '-I$(srcdir)/lib/libtasn1-grub';
    +   cppflags = '-I$(srcdir)/lib/tss2';
    + };
    + 
    +@@ grub-core/Makefile.core.def: module = {
    +   common = commands/tpm2_key_protector/tpm2key_asn1_tab.c;
    +   /* The plaform support of tpm2_key_protector depends on the tcg2 
implementation in tss2. */
    +   enable = efi;
    ++  enable = emu;
    +   cppflags = '-I$(srcdir)/lib/tss2 -I$(srcdir)/lib/libtasn1-grub';
      };
      
     
    @@ grub-core/kern/emu/misc.c: grub_util_get_kexecute (void)
     +  return write (grub_util_tpm_fd, input, size);
     +}
     
    - ## grub-core/tpm2/tcg2-emu.c (new) ##
    + ## grub-core/lib/tss2/tcg2_emu.c (new) ##
     @@
     +/*
     + *  GRUB  --  GRand Unified Bootloader
    ++ *  Copyright (C) 2024 Free Software Foundation, Inc.
     + *  Copyright (C) 2024 SUSE LLC
     + *
     + *  GRUB is free software: you can redistribute it and/or modify
    @@ grub-core/tpm2/tcg2-emu.c (new)
     +#include <grub/efi/efi.h>
     +#include <grub/efi/tpm.h>
     +#include <grub/mm.h>
    -+#include <grub/tpm2/buffer.h>
    -+#include <grub/tpm2/tcg2.h>
     +#include <grub/emu/misc.h>
     +
    ++#include <tss2_buffer.h>
    ++#include <tcg2.h>
    ++
     +grub_err_t
     +grub_tcg2_get_max_output_size (grub_size_t *size)
     +{
20:  a52077174 ! 25:  e9847cf50 tests: Add tpm2_test
    @@ Metadata
     Author: Gary Lin <glin@suse.com>
     
      ## Commit message ##
    -    tests: Add tpm2_test
    +    tests: Add tpm2_key_protector_test
     
    -    For the tpm2 module, the TCG2 command submission function is the only
    -    difference between the a QEMU instance and grub-emu. To test TPM key
    -    unsealing with a QEMU instance, it requires an extra OS image to invoke
    -    grub-protect to seal the LUKS key, rather than a simple grub-shell 
rescue
    -    CD image. On the other hand, grub-emu can share the emulated TPM device
    -    with the host, so that we can seal the LUKS key on host and test key
    -    unsealing with grub-emu.
    +    For the tpm2_key_protector module, the TCG2 command submission function
    +    is the only difference between a QEMU instance and grub-emu. To test
    +    TPM2 key unsealing with a QEMU instance, it requires an extra OS image
    +    to invoke grub-protect to seal the LUKS key, rather than a simple
    +    grub-shell rescue CD image. On the other hand, grub-emu can share the
    +    emulated TPM2 device with the host, so that we can seal the LUKS key on
    +    host and test key unsealing with grub-emu.
     
         This test script firstly creates a simple LUKS image to be loaded as a
    -    loopback device in grub-emu. Then an emulated TPM device is created by
    +    loopback device in grub-emu. Then an emulated TPM2 device is created by
         "swtpm chardev" and PCR 0 and 1 are extended.
     
         There are several test cases in the script to test various settings. 
Each
         test case uses grub-protect or tpm2-tools to seal the LUKS password
    -    against PCR 0 and PCR 1. Then grub-emu is launched to load the LUKS 
image,
    +    with PCR 0 and PCR 1. Then grub-emu is launched to load the LUKS image,
         try to mount the image with tpm2_key_protector_init and cryptomount, 
and
         verify the result.
     
    @@ Makefile.util.def: script = {
      
     +script = {
     +  testcase = native;
    -+  name = tpm2_test;
    -+  common = tests/tpm2_test.in;
    ++  name = tpm2_key_protector_test;
    ++  common = tests/tpm2_key_protector_test.in;
     +};
     +
      program = {
        testcase = native;
        name = example_unit_test;
     
    - ## tests/tpm2_test.in (new) ##
    + ## tests/tpm2_key_protector_test.in (new) ##
     @@
     +#! @BUILD_SHEBANG@ -e
     +
     +# Test GRUBs ability to unseal a LUKS key with TPM 2.0
    -+# Copyright (C) 2024  Free Software Foundation, Inc.
    ++# Copyright (C) 2024 Free Software Foundation, Inc.
     +#
     +# GRUB is free software: you can redistribute it and/or modify
     +# it under the terms of the GNU General Public License as published by
-- 
2.35.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]