summaryrefslogtreecommitdiff
path: root/config/grub/nvme/patches/0002-luks2/0005-Add-Argon2-algorithm.patch
diff options
context:
space:
mode:
Diffstat (limited to 'config/grub/nvme/patches/0002-luks2/0005-Add-Argon2-algorithm.patch')
-rw-r--r--config/grub/nvme/patches/0002-luks2/0005-Add-Argon2-algorithm.patch2611
1 files changed, 0 insertions, 2611 deletions
diff --git a/config/grub/nvme/patches/0002-luks2/0005-Add-Argon2-algorithm.patch b/config/grub/nvme/patches/0002-luks2/0005-Add-Argon2-algorithm.patch
deleted file mode 100644
index 1c6b4f04..00000000
--- a/config/grub/nvme/patches/0002-luks2/0005-Add-Argon2-algorithm.patch
+++ /dev/null
@@ -1,2611 +0,0 @@
-From 5b63da5c4267933f573ca37ce39a073098c443ba Mon Sep 17 00:00:00 2001
-From: Ax333l <main@axelen.xyz>
-Date: Thu, 17 Aug 2023 00:00:00 +0000
-Subject: [PATCH 3/6] Add Argon2 algorithm
-
-Signed-off-by: Nicholas Johnson <nick@nicholasjohnson.ch>
----
- docs/grub-dev.texi | 64 +++
- grub-core/Makefile.core.def | 8 +
- grub-core/lib/argon2/LICENSE | 314 +++++++++++
- grub-core/lib/argon2/argon2.c | 232 ++++++++
- grub-core/lib/argon2/argon2.h | 264 +++++++++
- grub-core/lib/argon2/blake2/blake2-impl.h | 151 ++++++
- grub-core/lib/argon2/blake2/blake2.h | 89 +++
- grub-core/lib/argon2/blake2/blake2b.c | 388 ++++++++++++++
- .../lib/argon2/blake2/blamka-round-ref.h | 56 ++
- grub-core/lib/argon2/core.c | 506 ++++++++++++++++++
- grub-core/lib/argon2/core.h | 228 ++++++++
- grub-core/lib/argon2/ref.c | 190 +++++++
- 12 files changed, 2490 insertions(+)
- create mode 100644 grub-core/lib/argon2/LICENSE
- create mode 100644 grub-core/lib/argon2/argon2.c
- create mode 100644 grub-core/lib/argon2/argon2.h
- create mode 100644 grub-core/lib/argon2/blake2/blake2-impl.h
- create mode 100644 grub-core/lib/argon2/blake2/blake2.h
- create mode 100644 grub-core/lib/argon2/blake2/blake2b.c
- create mode 100644 grub-core/lib/argon2/blake2/blamka-round-ref.h
- create mode 100644 grub-core/lib/argon2/core.c
- create mode 100644 grub-core/lib/argon2/core.h
- create mode 100644 grub-core/lib/argon2/ref.c
-
-diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
-index a695b02f0..313335a53 100644
---- a/docs/grub-dev.texi
-+++ b/docs/grub-dev.texi
-@@ -503,11 +503,75 @@ GRUB includes some code from other projects, and it is sometimes necessary
- to update it.
-
- @menu
-+* Argon2::
- * Gnulib::
- * jsmn::
- * minilzo::
- @end menu
-
-+@node Argon2
-+@section Argon2
-+
-+Argon2 is a key derivation function used by LUKS2 in order to derive encryption
-+keys from a user-provided password. GRUB imports the official reference
-+implementation of Argon2 from @url{https://github.com/P-H-C/phc-winner-argon2}.
-+In order to make the library usable for GRUB, we need to perform various
-+conversions. This is mainly due to the fact that the imported code makes use of
-+types and functions defined in the C standard library, which isn't available.
-+Furthermore, using the POSIX wrapper library is not possible as the code needs
-+to be part of the kernel.
-+
-+Updating the code can thus be performed like following:
-+
-+@example
-+$ git clone https://github.com/P-H-C/phc-winner-argon2 argon2
-+$ cp argon2/include/argon2.h argon2/src/@{argon2.c,core.c,core.h,ref.c@} \
-+ grub-core/lib/argon2/
-+$ cp argon2/src/blake2/@{blake2-impl.h,blake2.h,blake2b.c,blamka-round-ref.h@} \
-+ grub-core/lib/argon2/blake2/
-+$ sed -e 's/UINT32_C/GRUB_UINT32_C/g' \
-+ -e 's/UINT64_C/GRUB_UINT64_C/g' \
-+ -e 's/UINT32_MAX/GRUB_UINT32_MAX/g' \
-+ -e 's/CHAR_BIT/GRUB_CHAR_BIT/g' \
-+ -e 's/UINT_MAX/GRUB_UINT_MAX/g' \
-+ -e 's/uintptr_t/grub_addr_t/g' \
-+ -e 's/size_t/grub_size_t/g' \
-+ -e 's/uint32_t/grub_uint32_t/g' \
-+ -e 's/uint64_t/grub_uint64_t/g' \
-+ -e 's/uint8_t/grub_uint8_t/g' \
-+ -e 's/memset/grub_memset/g' \
-+ -e 's/memcpy/grub_memcpy/g' \
-+ -e 's/malloc/grub_malloc/g' \
-+ -e 's/free/grub_free/g' \
-+ -e 's/#elif _MSC_VER/#elif defined(_MSC_VER)/' \
-+ grub-core/lib/argon2/@{*,blake2/*@}.@{c,h@} -i
-+@end example
-+
-+Afterwards, you need to perform the following manual steps:
-+
-+@enumerate
-+@item Remove all includes of standard library headers, "encoding.h" and
-+ "thread.h".
-+@item Add includes <grub/mm.h> and <grub/misc.h> to "argon2.h".
-+@item Add include <grub/dl.h> and module license declaration to "argon2.c".
-+@item Remove the following declarations and functions from "argon2.h" and
-+ "argon2.c": argon2_type2string, argon2i_hash_encoded, argon2i_hash_raw,
-+ argon2d_hash_encoded, argon2d_hash_raw, argon2id_hash_encoded,
-+ argon2id_hash_raw, argon2_compare, argon2_verify, argon2i_verify,
-+ argon2d_verify, argon2id_verify, argon2d_ctx, argon2i_ctx, argon2id_ctx,
-+ argon2_verify_ctx, argon2d_verify_ctx, argon2i_verify_ctx,
-+ argon2id_verify_ctx, argon2_encodedlen.
-+@item Move the declaration of `clear_internal_memory()` in "blake2-impl.h" to
-+ "blake2b.c".
-+@item Remove code guarded by the ARGON2_NO_THREADS macro.
-+@item Remove parameters `encoded` and `encodedlen` from `argon2_hash` and remove
-+ the encoding block in that function.
-+@item Remove parameter verifications in `validate_inputs()` for
-+ ARGON2_MIN_PWD_LENGTH, ARGON2_MIN_SECRET, ARGON2_MIN_AD_LENGTH and
-+ ARGON2_MAX_MEMORY to fix compiler warnings.
-+@item Mark the function argon2_ctx as static.
-+@end enumerate
-+
- @node Gnulib
- @section Gnulib
-
-diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
-index d2cf29584..4a06789e5 100644
---- a/grub-core/Makefile.core.def
-+++ b/grub-core/Makefile.core.def
-@@ -1215,6 +1215,14 @@ module = {
- common = lib/json/json.c;
- };
-
-+module = {
-+ name = argon2;
-+ common = lib/argon2/argon2.c;
-+ common = lib/argon2/core.c;
-+ common = lib/argon2/ref.c;
-+ common = lib/argon2/blake2/blake2b.c;
-+};
-+
- module = {
- name = afsplitter;
- common = disk/AFSplitter.c;
-diff --git a/grub-core/lib/argon2/LICENSE b/grub-core/lib/argon2/LICENSE
-new file mode 100644
-index 000000000..97aae2925
---- /dev/null
-+++ b/grub-core/lib/argon2/LICENSE
-@@ -0,0 +1,314 @@
-+Argon2 reference source code package - reference C implementations
-+
-+Copyright 2015
-+Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+
-+You may use this work under the terms of a Creative Commons CC0 1.0
-+License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+these licenses can be found at:
-+
-+- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+
-+The terms of the licenses are reproduced below.
-+
-+--------------------------------------------------------------------------------
-+
-+Creative Commons Legal Code
-+
-+CC0 1.0 Universal
-+
-+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
-+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
-+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
-+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
-+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
-+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
-+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
-+ HEREUNDER.
-+
-+Statement of Purpose
-+
-+The laws of most jurisdictions throughout the world automatically confer
-+exclusive Copyright and Related Rights (defined below) upon the creator
-+and subsequent owner(s) (each and all, an "owner") of an original work of
-+authorship and/or a database (each, a "Work").
-+
-+Certain owners wish to permanently relinquish those rights to a Work for
-+the purpose of contributing to a commons of creative, cultural and
-+scientific works ("Commons") that the public can reliably and without fear
-+of later claims of infringement build upon, modify, incorporate in other
-+works, reuse and redistribute as freely as possible in any form whatsoever
-+and for any purposes, including without limitation commercial purposes.
-+These owners may contribute to the Commons to promote the ideal of a free
-+culture and the further production of creative, cultural and scientific
-+works, or to gain reputation or greater distribution for their Work in
-+part through the use and efforts of others.
-+
-+For these and/or other purposes and motivations, and without any
-+expectation of additional consideration or compensation, the person
-+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
-+is an owner of Copyright and Related Rights in the Work, voluntarily
-+elects to apply CC0 to the Work and publicly distribute the Work under its
-+terms, with knowledge of his or her Copyright and Related Rights in the
-+Work and the meaning and intended legal effect of CC0 on those rights.
-+
-+1. Copyright and Related Rights. A Work made available under CC0 may be
-+protected by copyright and related or neighboring rights ("Copyright and
-+Related Rights"). Copyright and Related Rights include, but are not
-+limited to, the following:
-+
-+ i. the right to reproduce, adapt, distribute, perform, display,
-+ communicate, and translate a Work;
-+ ii. moral rights retained by the original author(s) and/or performer(s);
-+iii. publicity and privacy rights pertaining to a person's image or
-+ likeness depicted in a Work;
-+ iv. rights protecting against unfair competition in regards to a Work,
-+ subject to the limitations in paragraph 4(a), below;
-+ v. rights protecting the extraction, dissemination, use and reuse of data
-+ in a Work;
-+ vi. database rights (such as those arising under Directive 96/9/EC of the
-+ European Parliament and of the Council of 11 March 1996 on the legal
-+ protection of databases, and under any national implementation
-+ thereof, including any amended or successor version of such
-+ directive); and
-+vii. other similar, equivalent or corresponding rights throughout the
-+ world based on applicable law or treaty, and any national
-+ implementations thereof.
-+
-+2. Waiver. To the greatest extent permitted by, but not in contravention
-+of, applicable law, Affirmer hereby overtly, fully, permanently,
-+irrevocably and unconditionally waives, abandons, and surrenders all of
-+Affirmer's Copyright and Related Rights and associated claims and causes
-+of action, whether now known or unknown (including existing as well as
-+future claims and causes of action), in the Work (i) in all territories
-+worldwide, (ii) for the maximum duration provided by applicable law or
-+treaty (including future time extensions), (iii) in any current or future
-+medium and for any number of copies, and (iv) for any purpose whatsoever,
-+including without limitation commercial, advertising or promotional
-+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
-+member of the public at large and to the detriment of Affirmer's heirs and
-+successors, fully intending that such Waiver shall not be subject to
-+revocation, rescission, cancellation, termination, or any other legal or
-+equitable action to disrupt the quiet enjoyment of the Work by the public
-+as contemplated by Affirmer's express Statement of Purpose.
-+
-+3. Public License Fallback. Should any part of the Waiver for any reason
-+be judged legally invalid or ineffective under applicable law, then the
-+Waiver shall be preserved to the maximum extent permitted taking into
-+account Affirmer's express Statement of Purpose. In addition, to the
-+extent the Waiver is so judged Affirmer hereby grants to each affected
-+person a royalty-free, non transferable, non sublicensable, non exclusive,
-+irrevocable and unconditional license to exercise Affirmer's Copyright and
-+Related Rights in the Work (i) in all territories worldwide, (ii) for the
-+maximum duration provided by applicable law or treaty (including future
-+time extensions), (iii) in any current or future medium and for any number
-+of copies, and (iv) for any purpose whatsoever, including without
-+limitation commercial, advertising or promotional purposes (the
-+"License"). The License shall be deemed effective as of the date CC0 was
-+applied by Affirmer to the Work. Should any part of the License for any
-+reason be judged legally invalid or ineffective under applicable law, such
-+partial invalidity or ineffectiveness shall not invalidate the remainder
-+of the License, and in such case Affirmer hereby affirms that he or she
-+will not (i) exercise any of his or her remaining Copyright and Related
-+Rights in the Work or (ii) assert any associated claims and causes of
-+action with respect to the Work, in either case contrary to Affirmer's
-+express Statement of Purpose.
-+
-+4. Limitations and Disclaimers.
-+
-+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
-+ surrendered, licensed or otherwise affected by this document.
-+ b. Affirmer offers the Work as-is and makes no representations or
-+ warranties of any kind concerning the Work, express, implied,
-+ statutory or otherwise, including without limitation warranties of
-+ title, merchantability, fitness for a particular purpose, non
-+ infringement, or the absence of latent or other defects, accuracy, or
-+ the present or absence of errors, whether or not discoverable, all to
-+ the greatest extent permissible under applicable law.
-+ c. Affirmer disclaims responsibility for clearing rights of other persons
-+ that may apply to the Work or any use thereof, including without
-+ limitation any person's Copyright and Related Rights in the Work.
-+ Further, Affirmer disclaims responsibility for obtaining any necessary
-+ consents, permissions or other rights required for any use of the
-+ Work.
-+ d. Affirmer understands and acknowledges that Creative Commons is not a
-+ party to this document and has no duty or obligation with respect to
-+ this CC0 or use of the Work.
-+
-+--------------------------------------------------------------------------------
-+
-+ Apache License
-+ Version 2.0, January 2004
-+ http://www.apache.org/licenses/
-+
-+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-+
-+ 1. Definitions.
-+
-+ "License" shall mean the terms and conditions for use, reproduction,
-+ and distribution as defined by Sections 1 through 9 of this document.
-+
-+ "Licensor" shall mean the copyright owner or entity authorized by
-+ the copyright owner that is granting the License.
-+
-+ "Legal Entity" shall mean the union of the acting entity and all
-+ other entities that control, are controlled by, or are under common
-+ control with that entity. For the purposes of this definition,
-+ "control" means (i) the power, direct or indirect, to cause the
-+ direction or management of such entity, whether by contract or
-+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
-+ outstanding shares, or (iii) beneficial ownership of such entity.
-+
-+ "You" (or "Your") shall mean an individual or Legal Entity
-+ exercising permissions granted by this License.
-+
-+ "Source" form shall mean the preferred form for making modifications,
-+ including but not limited to software source code, documentation
-+ source, and configuration files.
-+
-+ "Object" form shall mean any form resulting from mechanical
-+ transformation or translation of a Source form, including but
-+ not limited to compiled object code, generated documentation,
-+ and conversions to other media types.
-+
-+ "Work" shall mean the work of authorship, whether in Source or
-+ Object form, made available under the License, as indicated by a
-+ copyright notice that is included in or attached to the work
-+ (an example is provided in the Appendix below).
-+
-+ "Derivative Works" shall mean any work, whether in Source or Object
-+ form, that is based on (or derived from) the Work and for which the
-+ editorial revisions, annotations, elaborations, or other modifications
-+ represent, as a whole, an original work of authorship. For the purposes
-+ of this License, Derivative Works shall not include works that remain
-+ separable from, or merely link (or bind by name) to the interfaces of,
-+ the Work and Derivative Works thereof.
-+
-+ "Contribution" shall mean any work of authorship, including
-+ the original version of the Work and any modifications or additions
-+ to that Work or Derivative Works thereof, that is intentionally
-+ submitted to Licensor for inclusion in the Work by the copyright owner
-+ or by an individual or Legal Entity authorized to submit on behalf of
-+ the copyright owner. For the purposes of this definition, "submitted"
-+ means any form of electronic, verbal, or written communication sent
-+ to the Licensor or its representatives, including but not limited to
-+ communication on electronic mailing lists, source code control systems,
-+ and issue tracking systems that are managed by, or on behalf of, the
-+ Licensor for the purpose of discussing and improving the Work, but
-+ excluding communication that is conspicuously marked or otherwise
-+ designated in writing by the copyright owner as "Not a Contribution."
-+
-+ "Contributor" shall mean Licensor and any individual or Legal Entity
-+ on behalf of whom a Contribution has been received by Licensor and
-+ subsequently incorporated within the Work.
-+
-+ 2. Grant of Copyright License. Subject to the terms and conditions of
-+ this License, each Contributor hereby grants to You a perpetual,
-+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-+ copyright license to reproduce, prepare Derivative Works of,
-+ publicly display, publicly perform, sublicense, and distribute the
-+ Work and such Derivative Works in Source or Object form.
-+
-+ 3. Grant of Patent License. Subject to the terms and conditions of
-+ this License, each Contributor hereby grants to You a perpetual,
-+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-+ (except as stated in this section) patent license to make, have made,
-+ use, offer to sell, sell, import, and otherwise transfer the Work,
-+ where such license applies only to those patent claims licensable
-+ by such Contributor that are necessarily infringed by their
-+ Contribution(s) alone or by combination of their Contribution(s)
-+ with the Work to which such Contribution(s) was submitted. If You
-+ institute patent litigation against any entity (including a
-+ cross-claim or counterclaim in a lawsuit) alleging that the Work
-+ or a Contribution incorporated within the Work constitutes direct
-+ or contributory patent infringement, then any patent licenses
-+ granted to You under this License for that Work shall terminate
-+ as of the date such litigation is filed.
-+
-+ 4. Redistribution. You may reproduce and distribute copies of the
-+ Work or Derivative Works thereof in any medium, with or without
-+ modifications, and in Source or Object form, provided that You
-+ meet the following conditions:
-+
-+ (a) You must give any other recipients of the Work or
-+ Derivative Works a copy of this License; and
-+
-+ (b) You must cause any modified files to carry prominent notices
-+ stating that You changed the files; and
-+
-+ (c) You must retain, in the Source form of any Derivative Works
-+ that You distribute, all copyright, patent, trademark, and
-+ attribution notices from the Source form of the Work,
-+ excluding those notices that do not pertain to any part of
-+ the Derivative Works; and
-+
-+ (d) If the Work includes a "NOTICE" text file as part of its
-+ distribution, then any Derivative Works that You distribute must
-+ include a readable copy of the attribution notices contained
-+ within such NOTICE file, excluding those notices that do not
-+ pertain to any part of the Derivative Works, in at least one
-+ of the following places: within a NOTICE text file distributed
-+ as part of the Derivative Works; within the Source form or
-+ documentation, if provided along with the Derivative Works; or,
-+ within a display generated by the Derivative Works, if and
-+ wherever such third-party notices normally appear. The contents
-+ of the NOTICE file are for informational purposes only and
-+ do not modify the License. You may add Your own attribution
-+ notices within Derivative Works that You distribute, alongside
-+ or as an addendum to the NOTICE text from the Work, provided
-+ that such additional attribution notices cannot be construed
-+ as modifying the License.
-+
-+ You may add Your own copyright statement to Your modifications and
-+ may provide additional or different license terms and conditions
-+ for use, reproduction, or distribution of Your modifications, or
-+ for any such Derivative Works as a whole, provided Your use,
-+ reproduction, and distribution of the Work otherwise complies with
-+ the conditions stated in this License.
-+
-+ 5. Submission of Contributions. Unless You explicitly state otherwise,
-+ any Contribution intentionally submitted for inclusion in the Work
-+ by You to the Licensor shall be under the terms and conditions of
-+ this License, without any additional terms or conditions.
-+ Notwithstanding the above, nothing herein shall supersede or modify
-+ the terms of any separate license agreement you may have executed
-+ with Licensor regarding such Contributions.
-+
-+ 6. Trademarks. This License does not grant permission to use the trade
-+ names, trademarks, service marks, or product names of the Licensor,
-+ except as required for reasonable and customary use in describing the
-+ origin of the Work and reproducing the content of the NOTICE file.
-+
-+ 7. Disclaimer of Warranty. Unless required by applicable law or
-+ agreed to in writing, Licensor provides the Work (and each
-+ Contributor provides its Contributions) on an "AS IS" BASIS,
-+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-+ implied, including, without limitation, any warranties or conditions
-+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-+ PARTICULAR PURPOSE. You are solely responsible for determining the
-+ appropriateness of using or redistributing the Work and assume any
-+ risks associated with Your exercise of permissions under this License.
-+
-+ 8. Limitation of Liability. In no event and under no legal theory,
-+ whether in tort (including negligence), contract, or otherwise,
-+ unless required by applicable law (such as deliberate and grossly
-+ negligent acts) or agreed to in writing, shall any Contributor be
-+ liable to You for damages, including any direct, indirect, special,
-+ incidental, or consequential damages of any character arising as a
-+ result of this License or out of the use or inability to use the
-+ Work (including but not limited to damages for loss of goodwill,
-+ work stoppage, computer failure or malfunction, or any and all
-+ other commercial damages or losses), even if such Contributor
-+ has been advised of the possibility of such damages.
-+
-+ 9. Accepting Warranty or Additional Liability. While redistributing
-+ the Work or Derivative Works thereof, You may choose to offer,
-+ and charge a fee for, acceptance of support, warranty, indemnity,
-+ or other liability obligations and/or rights consistent with this
-+ License. However, in accepting such obligations, You may act only
-+ on Your own behalf and on Your sole responsibility, not on behalf
-+ of any other Contributor, and only if You agree to indemnify,
-+ defend, and hold each Contributor harmless for any liability
-+ incurred by, or claims asserted against, such Contributor by reason
-+ of your accepting any such warranty or additional liability.
-diff --git a/grub-core/lib/argon2/argon2.c b/grub-core/lib/argon2/argon2.c
-new file mode 100644
-index 000000000..49532fe80
---- /dev/null
-+++ b/grub-core/lib/argon2/argon2.c
-@@ -0,0 +1,232 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#include <grub/dl.h>
-+
-+#include "argon2.h"
-+#include "core.h"
-+
-+GRUB_MOD_LICENSE ("CC0");
-+
-+static int argon2_ctx(argon2_context *context, argon2_type type) {
-+ /* 1. Validate all inputs */
-+ int result = validate_inputs(context);
-+ grub_uint32_t memory_blocks, segment_length;
-+ argon2_instance_t instance;
-+
-+ if (ARGON2_OK != result) {
-+ return result;
-+ }
-+
-+ if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
-+ return ARGON2_INCORRECT_TYPE;
-+ }
-+
-+ /* 2. Align memory size */
-+ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
-+ memory_blocks = context->m_cost;
-+
-+ if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
-+ memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
-+ }
-+
-+ segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
-+ /* Ensure that all segments have equal length */
-+ memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
-+
-+ instance.version = context->version;
-+ instance.memory = NULL;
-+ instance.passes = context->t_cost;
-+ instance.memory_blocks = memory_blocks;
-+ instance.segment_length = segment_length;
-+ instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
-+ instance.lanes = context->lanes;
-+ instance.threads = context->threads;
-+ instance.type = type;
-+
-+ if (instance.threads > instance.lanes) {
-+ instance.threads = instance.lanes;
-+ }
-+
-+ /* 3. Initialization: Hashing inputs, allocating memory, filling first
-+ * blocks
-+ */
-+ result = initialize(&instance, context);
-+
-+ if (ARGON2_OK != result) {
-+ return result;
-+ }
-+
-+ /* 4. Filling memory */
-+ result = fill_memory_blocks(&instance);
-+
-+ if (ARGON2_OK != result) {
-+ return result;
-+ }
-+ /* 5. Finalization */
-+ finalize(context, &instance);
-+
-+ return ARGON2_OK;
-+}
-+
-+int argon2_hash(const grub_uint32_t t_cost, const grub_uint32_t m_cost,
-+ const grub_uint32_t parallelism, const void *pwd,
-+ const grub_size_t pwdlen, const void *salt, const grub_size_t saltlen,
-+ void *hash, const grub_size_t hashlen, argon2_type type,
-+ const grub_uint32_t version){
-+
-+ argon2_context context;
-+ int result;
-+ grub_uint8_t *out;
-+
-+ if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
-+ return ARGON2_PWD_TOO_LONG;
-+ }
-+
-+ if (saltlen > ARGON2_MAX_SALT_LENGTH) {
-+ return ARGON2_SALT_TOO_LONG;
-+ }
-+
-+ if (hashlen > ARGON2_MAX_OUTLEN) {
-+ return ARGON2_OUTPUT_TOO_LONG;
-+ }
-+
-+ if (hashlen < ARGON2_MIN_OUTLEN) {
-+ return ARGON2_OUTPUT_TOO_SHORT;
-+ }
-+
-+ out = grub_malloc(hashlen);
-+ if (!out) {
-+ return ARGON2_MEMORY_ALLOCATION_ERROR;
-+ }
-+
-+ context.out = (grub_uint8_t *)out;
-+ context.outlen = (grub_uint32_t)hashlen;
-+ context.pwd = CONST_CAST(grub_uint8_t *)pwd;
-+ context.pwdlen = (grub_uint32_t)pwdlen;
-+ context.salt = CONST_CAST(grub_uint8_t *)salt;
-+ context.saltlen = (grub_uint32_t)saltlen;
-+ context.secret = NULL;
-+ context.secretlen = 0;
-+ context.ad = NULL;
-+ context.adlen = 0;
-+ context.t_cost = t_cost;
-+ context.m_cost = m_cost;
-+ context.lanes = parallelism;
-+ context.threads = parallelism;
-+ context.allocate_cbk = NULL;
-+ context.grub_free_cbk = NULL;
-+ context.flags = ARGON2_DEFAULT_FLAGS;
-+ context.version = version;
-+
-+ result = argon2_ctx(&context, type);
-+
-+ if (result != ARGON2_OK) {
-+ clear_internal_memory(out, hashlen);
-+ grub_free(out);
-+ return result;
-+ }
-+
-+ /* if raw hash requested, write it */
-+ if (hash) {
-+ grub_memcpy(hash, out, hashlen);
-+ }
-+
-+ clear_internal_memory(out, hashlen);
-+ grub_free(out);
-+
-+ return ARGON2_OK;
-+}
-+
-+const char *argon2_error_message(int error_code) {
-+ switch (error_code) {
-+ case ARGON2_OK:
-+ return "OK";
-+ case ARGON2_OUTPUT_PTR_NULL:
-+ return "Output pointer is NULL";
-+ case ARGON2_OUTPUT_TOO_SHORT:
-+ return "Output is too short";
-+ case ARGON2_OUTPUT_TOO_LONG:
-+ return "Output is too long";
-+ case ARGON2_PWD_TOO_SHORT:
-+ return "Password is too short";
-+ case ARGON2_PWD_TOO_LONG:
-+ return "Password is too long";
-+ case ARGON2_SALT_TOO_SHORT:
-+ return "Salt is too short";
-+ case ARGON2_SALT_TOO_LONG:
-+ return "Salt is too long";
-+ case ARGON2_AD_TOO_SHORT:
-+ return "Associated data is too short";
-+ case ARGON2_AD_TOO_LONG:
-+ return "Associated data is too long";
-+ case ARGON2_SECRET_TOO_SHORT:
-+ return "Secret is too short";
-+ case ARGON2_SECRET_TOO_LONG:
-+ return "Secret is too long";
-+ case ARGON2_TIME_TOO_SMALL:
-+ return "Time cost is too small";
-+ case ARGON2_TIME_TOO_LARGE:
-+ return "Time cost is too large";
-+ case ARGON2_MEMORY_TOO_LITTLE:
-+ return "Memory cost is too small";
-+ case ARGON2_MEMORY_TOO_MUCH:
-+ return "Memory cost is too large";
-+ case ARGON2_LANES_TOO_FEW:
-+ return "Too few lanes";
-+ case ARGON2_LANES_TOO_MANY:
-+ return "Too many lanes";
-+ case ARGON2_PWD_PTR_MISMATCH:
-+ return "Password pointer is NULL, but password length is not 0";
-+ case ARGON2_SALT_PTR_MISMATCH:
-+ return "Salt pointer is NULL, but salt length is not 0";
-+ case ARGON2_SECRET_PTR_MISMATCH:
-+ return "Secret pointer is NULL, but secret length is not 0";
-+ case ARGON2_AD_PTR_MISMATCH:
-+ return "Associated data pointer is NULL, but ad length is not 0";
-+ case ARGON2_MEMORY_ALLOCATION_ERROR:
-+ return "Memory allocation error";
-+ case ARGON2_FREE_MEMORY_CBK_NULL:
-+ return "The grub_free memory callback is NULL";
-+ case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
-+ return "The allocate memory callback is NULL";
-+ case ARGON2_INCORRECT_PARAMETER:
-+ return "Argon2_Context context is NULL";
-+ case ARGON2_INCORRECT_TYPE:
-+ return "There is no such version of Argon2";
-+ case ARGON2_OUT_PTR_MISMATCH:
-+ return "Output pointer mismatch";
-+ case ARGON2_THREADS_TOO_FEW:
-+ return "Not enough threads";
-+ case ARGON2_THREADS_TOO_MANY:
-+ return "Too many threads";
-+ case ARGON2_MISSING_ARGS:
-+ return "Missing arguments";
-+ case ARGON2_ENCODING_FAIL:
-+ return "Encoding failed";
-+ case ARGON2_DECODING_FAIL:
-+ return "Decoding failed";
-+ case ARGON2_THREAD_FAIL:
-+ return "Threading failure";
-+ case ARGON2_DECODING_LENGTH_FAIL:
-+ return "Some of encoded parameters are too long or too short";
-+ case ARGON2_VERIFY_MISMATCH:
-+ return "The password does not match the supplied hash";
-+ default:
-+ return "Unknown error code";
-+ }
-+}
-diff --git a/grub-core/lib/argon2/argon2.h b/grub-core/lib/argon2/argon2.h
-new file mode 100644
-index 000000000..129f7efbd
---- /dev/null
-+++ b/grub-core/lib/argon2/argon2.h
-@@ -0,0 +1,264 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#ifndef ARGON2_H
-+#define ARGON2_H
-+
-+#include <grub/misc.h>
-+#include <grub/mm.h>
-+
-+#if defined(__cplusplus)
-+extern "C" {
-+#endif
-+
-+/* Symbols visibility control */
-+#ifdef A2_VISCTL
-+#define ARGON2_PUBLIC __attribute__((visibility("default")))
-+#define ARGON2_LOCAL __attribute__ ((visibility ("hidden")))
-+#elif defined(_MSC_VER)
-+#define ARGON2_PUBLIC __declspec(dllexport)
-+#define ARGON2_LOCAL
-+#else
-+#define ARGON2_PUBLIC
-+#define ARGON2_LOCAL
-+#endif
-+
-+/*
-+ * Argon2 input parameter restrictions
-+ */
-+
-+/* Minimum and maximum number of lanes (degree of parallelism) */
-+#define ARGON2_MIN_LANES GRUB_UINT32_C(1)
-+#define ARGON2_MAX_LANES GRUB_UINT32_C(0xFFFFFF)
-+
-+/* Minimum and maximum number of threads */
-+#define ARGON2_MIN_THREADS GRUB_UINT32_C(1)
-+#define ARGON2_MAX_THREADS GRUB_UINT32_C(0xFFFFFF)
-+
-+/* Number of synchronization points between lanes per pass */
-+#define ARGON2_SYNC_POINTS GRUB_UINT32_C(4)
-+
-+/* Minimum and maximum digest size in bytes */
-+#define ARGON2_MIN_OUTLEN GRUB_UINT32_C(4)
-+#define ARGON2_MAX_OUTLEN GRUB_UINT32_C(0xFFFFFFFF)
-+
-+/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
-+#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
-+
-+#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
-+/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */
-+#define ARGON2_MAX_MEMORY_BITS \
-+ ARGON2_MIN(GRUB_UINT32_C(32), (sizeof(void *) * GRUB_CHAR_BIT - 10 - 1))
-+#define ARGON2_MAX_MEMORY \
-+ ARGON2_MIN(GRUB_UINT32_C(0xFFFFFFFF), GRUB_UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
-+
-+/* Minimum and maximum number of passes */
-+#define ARGON2_MIN_TIME GRUB_UINT32_C(1)
-+#define ARGON2_MAX_TIME GRUB_UINT32_C(0xFFFFFFFF)
-+
-+/* Minimum and maximum password length in bytes */
-+#define ARGON2_MIN_PWD_LENGTH GRUB_UINT32_C(0)
-+#define ARGON2_MAX_PWD_LENGTH GRUB_UINT32_C(0xFFFFFFFF)
-+
-+/* Minimum and maximum associated data length in bytes */
-+#define ARGON2_MIN_AD_LENGTH GRUB_UINT32_C(0)
-+#define ARGON2_MAX_AD_LENGTH GRUB_UINT32_C(0xFFFFFFFF)
-+
-+/* Minimum and maximum salt length in bytes */
-+#define ARGON2_MIN_SALT_LENGTH GRUB_UINT32_C(8)
-+#define ARGON2_MAX_SALT_LENGTH GRUB_UINT32_C(0xFFFFFFFF)
-+
-+/* Minimum and maximum key length in bytes */
-+#define ARGON2_MIN_SECRET GRUB_UINT32_C(0)
-+#define ARGON2_MAX_SECRET GRUB_UINT32_C(0xFFFFFFFF)
-+
-+/* Flags to determine which fields are securely wiped (default = no wipe). */
-+#define ARGON2_DEFAULT_FLAGS GRUB_UINT32_C(0)
-+#define ARGON2_FLAG_CLEAR_PASSWORD (GRUB_UINT32_C(1) << 0)
-+#define ARGON2_FLAG_CLEAR_SECRET (GRUB_UINT32_C(1) << 1)
-+
-+/* Global flag to determine if we are wiping internal memory buffers. This flag
-+ * is defined in core.c and defaults to 1 (wipe internal memory). */
-+extern int FLAG_clear_internal_memory;
-+
-+/* Error codes */
-+typedef enum Argon2_ErrorCodes {
-+ ARGON2_OK = 0,
-+
-+ ARGON2_OUTPUT_PTR_NULL = -1,
-+
-+ ARGON2_OUTPUT_TOO_SHORT = -2,
-+ ARGON2_OUTPUT_TOO_LONG = -3,
-+
-+ ARGON2_PWD_TOO_SHORT = -4,
-+ ARGON2_PWD_TOO_LONG = -5,
-+
-+ ARGON2_SALT_TOO_SHORT = -6,
-+ ARGON2_SALT_TOO_LONG = -7,
-+
-+ ARGON2_AD_TOO_SHORT = -8,
-+ ARGON2_AD_TOO_LONG = -9,
-+
-+ ARGON2_SECRET_TOO_SHORT = -10,
-+ ARGON2_SECRET_TOO_LONG = -11,
-+
-+ ARGON2_TIME_TOO_SMALL = -12,
-+ ARGON2_TIME_TOO_LARGE = -13,
-+
-+ ARGON2_MEMORY_TOO_LITTLE = -14,
-+ ARGON2_MEMORY_TOO_MUCH = -15,
-+
-+ ARGON2_LANES_TOO_FEW = -16,
-+ ARGON2_LANES_TOO_MANY = -17,
-+
-+ ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */
-+ ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */
-+ ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */
-+ ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
-+
-+ ARGON2_MEMORY_ALLOCATION_ERROR = -22,
-+
-+ ARGON2_FREE_MEMORY_CBK_NULL = -23,
-+ ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
-+
-+ ARGON2_INCORRECT_PARAMETER = -25,
-+ ARGON2_INCORRECT_TYPE = -26,
-+
-+ ARGON2_OUT_PTR_MISMATCH = -27,
-+
-+ ARGON2_THREADS_TOO_FEW = -28,
-+ ARGON2_THREADS_TOO_MANY = -29,
-+
-+ ARGON2_MISSING_ARGS = -30,
-+
-+ ARGON2_ENCODING_FAIL = -31,
-+
-+ ARGON2_DECODING_FAIL = -32,
-+
-+ ARGON2_THREAD_FAIL = -33,
-+
-+ ARGON2_DECODING_LENGTH_FAIL = -34,
-+
-+ ARGON2_VERIFY_MISMATCH = -35
-+} argon2_error_codes;
-+
-+/* Memory allocator types --- for external allocation */
-+typedef int (*allocate_fptr)(grub_uint8_t **memory, grub_size_t bytes_to_allocate);
-+typedef void (*deallocate_fptr)(grub_uint8_t *memory, grub_size_t bytes_to_allocate);
-+
-+/* Argon2 external data structures */
-+
-+/*
-+ *****
-+ * Context: structure to hold Argon2 inputs:
-+ * output array and its length,
-+ * password and its length,
-+ * salt and its length,
-+ * secret and its length,
-+ * associated data and its length,
-+ * number of passes, amount of used memory (in KBytes, can be rounded up a bit)
-+ * number of parallel threads that will be run.
-+ * All the parameters above affect the output hash value.
-+ * Additionally, two function pointers can be provided to allocate and
-+ * deallocate the memory (if NULL, memory will be allocated internally).
-+ * Also, three flags indicate whether to erase password, secret as soon as they
-+ * are pre-hashed (and thus not needed anymore), and the entire memory
-+ *****
-+ * Simplest situation: you have output array out[8], password is stored in
-+ * pwd[32], salt is stored in salt[16], you do not have keys nor associated
-+ * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with
-+ * 4 parallel lanes.
-+ * You want to erase the password, but you're OK with last pass not being
-+ * erased. You want to use the default memory allocator.
-+ * Then you initialize:
-+ Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false)
-+ */
-+typedef struct Argon2_Context {
-+ grub_uint8_t *out; /* output array */
-+ grub_uint32_t outlen; /* digest length */
-+
-+ grub_uint8_t *pwd; /* password array */
-+ grub_uint32_t pwdlen; /* password length */
-+
-+ grub_uint8_t *salt; /* salt array */
-+ grub_uint32_t saltlen; /* salt length */
-+
-+ grub_uint8_t *secret; /* key array */
-+ grub_uint32_t secretlen; /* key length */
-+
-+ grub_uint8_t *ad; /* associated data array */
-+ grub_uint32_t adlen; /* associated data length */
-+
-+ grub_uint32_t t_cost; /* number of passes */
-+ grub_uint32_t m_cost; /* amount of memory requested (KB) */
-+ grub_uint32_t lanes; /* number of lanes */
-+ grub_uint32_t threads; /* maximum number of threads */
-+
-+ grub_uint32_t version; /* version number */
-+
-+ allocate_fptr allocate_cbk; /* pointer to memory allocator */
-+ deallocate_fptr grub_free_cbk; /* pointer to memory deallocator */
-+
-+ grub_uint32_t flags; /* array of bool options */
-+} argon2_context;
-+
-+/* Argon2 primitive type */
-+typedef enum Argon2_type {
-+ Argon2_d = 0,
-+ Argon2_i = 1,
-+ Argon2_id = 2
-+} argon2_type;
-+
-+/* Version of the algorithm */
-+typedef enum Argon2_version {
-+ ARGON2_VERSION_10 = 0x10,
-+ ARGON2_VERSION_13 = 0x13,
-+ ARGON2_VERSION_NUMBER = ARGON2_VERSION_13
-+} argon2_version;
-+
-+/**
-+ * Hashes a password with Argon2, producing a raw hash at @hash
-+ * @param t_cost Number of iterations
-+ * @param m_cost Sets memory usage to m_cost kibibytes
-+ * @param parallelism Number of threads and compute lanes
-+ * @param pwd Pointer to password
-+ * @param pwdlen Password size in bytes
-+ * @param salt Pointer to salt
-+ * @param saltlen Salt size in bytes
-+ * @param hash Buffer where to write the raw hash - updated by the function
-+ * @param hashlen Desired length of the hash in bytes
-+ * @pre Different parallelism levels will give different results
-+ * @pre Returns ARGON2_OK if successful
-+ */
-+ARGON2_PUBLIC int argon2_hash(const grub_uint32_t t_cost, const grub_uint32_t m_cost,
-+ const grub_uint32_t parallelism, const void *pwd,
-+ const grub_size_t pwdlen, const void *salt,
-+ const grub_size_t saltlen, void *hash,
-+ const grub_size_t hashlen, argon2_type type,
-+ const grub_uint32_t version);
-+
-+/**
-+ * Get the associated error message for given error code
-+ * @return The error message associated with the given error code
-+ */
-+ARGON2_PUBLIC const char *argon2_error_message(int error_code);
-+
-+#if defined(__cplusplus)
-+}
-+#endif
-+
-+#endif
-diff --git a/grub-core/lib/argon2/blake2/blake2-impl.h b/grub-core/lib/argon2/blake2/blake2-impl.h
-new file mode 100644
-index 000000000..3a795680b
---- /dev/null
-+++ b/grub-core/lib/argon2/blake2/blake2-impl.h
-@@ -0,0 +1,151 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#ifndef PORTABLE_BLAKE2_IMPL_H
-+#define PORTABLE_BLAKE2_IMPL_H
-+
-+#if defined(_MSC_VER)
-+#define BLAKE2_INLINE __inline
-+#elif defined(__GNUC__) || defined(__clang__)
-+#define BLAKE2_INLINE __inline__
-+#else
-+#define BLAKE2_INLINE
-+#endif
-+
-+/* Argon2 Team - Begin Code */
-+/*
-+ Not an exhaustive list, but should cover the majority of modern platforms
-+ Additionally, the code will always be correct---this is only a performance
-+ tweak.
-+*/
-+#if (defined(__BYTE_ORDER__) && \
-+ (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \
-+ defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
-+ defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \
-+ defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \
-+ defined(_M_ARM)
-+#define NATIVE_LITTLE_ENDIAN
-+#endif
-+/* Argon2 Team - End Code */
-+
-+static BLAKE2_INLINE grub_uint32_t load32(const void *src) {
-+#if defined(NATIVE_LITTLE_ENDIAN)
-+ grub_uint32_t w;
-+ grub_memcpy(&w, src, sizeof w);
-+ return w;
-+#else
-+ const grub_uint8_t *p = (const grub_uint8_t *)src;
-+ grub_uint32_t w = *p++;
-+ w |= (grub_uint32_t)(*p++) << 8;
-+ w |= (grub_uint32_t)(*p++) << 16;
-+ w |= (grub_uint32_t)(*p++) << 24;
-+ return w;
-+#endif
-+}
-+
-+static BLAKE2_INLINE grub_uint64_t load64(const void *src) {
-+#if defined(NATIVE_LITTLE_ENDIAN)
-+ grub_uint64_t w;
-+ grub_memcpy(&w, src, sizeof w);
-+ return w;
-+#else
-+ const grub_uint8_t *p = (const grub_uint8_t *)src;
-+ grub_uint64_t w = *p++;
-+ w |= (grub_uint64_t)(*p++) << 8;
-+ w |= (grub_uint64_t)(*p++) << 16;
-+ w |= (grub_uint64_t)(*p++) << 24;
-+ w |= (grub_uint64_t)(*p++) << 32;
-+ w |= (grub_uint64_t)(*p++) << 40;
-+ w |= (grub_uint64_t)(*p++) << 48;
-+ w |= (grub_uint64_t)(*p++) << 56;
-+ return w;
-+#endif
-+}
-+
-+static BLAKE2_INLINE void store32(void *dst, grub_uint32_t w) {
-+#if defined(NATIVE_LITTLE_ENDIAN)
-+ grub_memcpy(dst, &w, sizeof w);
-+#else
-+ grub_uint8_t *p = (grub_uint8_t *)dst;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+#endif
-+}
-+
-+static BLAKE2_INLINE void store64(void *dst, grub_uint64_t w) {
-+#if defined(NATIVE_LITTLE_ENDIAN)
-+ grub_memcpy(dst, &w, sizeof w);
-+#else
-+ grub_uint8_t *p = (grub_uint8_t *)dst;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+#endif
-+}
-+
-+static BLAKE2_INLINE grub_uint64_t load48(const void *src) {
-+ const grub_uint8_t *p = (const grub_uint8_t *)src;
-+ grub_uint64_t w = *p++;
-+ w |= (grub_uint64_t)(*p++) << 8;
-+ w |= (grub_uint64_t)(*p++) << 16;
-+ w |= (grub_uint64_t)(*p++) << 24;
-+ w |= (grub_uint64_t)(*p++) << 32;
-+ w |= (grub_uint64_t)(*p++) << 40;
-+ return w;
-+}
-+
-+static BLAKE2_INLINE void store48(void *dst, grub_uint64_t w) {
-+ grub_uint8_t *p = (grub_uint8_t *)dst;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+ w >>= 8;
-+ *p++ = (grub_uint8_t)w;
-+}
-+
-+static BLAKE2_INLINE grub_uint32_t rotr32(const grub_uint32_t w, const unsigned c) {
-+ return (w >> c) | (w << (32 - c));
-+}
-+
-+static BLAKE2_INLINE grub_uint64_t rotr64(const grub_uint64_t w, const unsigned c) {
-+ return (w >> c) | (w << (64 - c));
-+}
-+
-+#endif
-diff --git a/grub-core/lib/argon2/blake2/blake2.h b/grub-core/lib/argon2/blake2/blake2.h
-new file mode 100644
-index 000000000..4e8efeb22
---- /dev/null
-+++ b/grub-core/lib/argon2/blake2/blake2.h
-@@ -0,0 +1,89 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#ifndef PORTABLE_BLAKE2_H
-+#define PORTABLE_BLAKE2_H
-+
-+#include "../argon2.h"
-+
-+#if defined(__cplusplus)
-+extern "C" {
-+#endif
-+
-+enum blake2b_constant {
-+ BLAKE2B_BLOCKBYTES = 128,
-+ BLAKE2B_OUTBYTES = 64,
-+ BLAKE2B_KEYBYTES = 64,
-+ BLAKE2B_SALTBYTES = 16,
-+ BLAKE2B_PERSONALBYTES = 16
-+};
-+
-+#pragma pack(push, 1)
-+typedef struct __blake2b_param {
-+ grub_uint8_t digest_length; /* 1 */
-+ grub_uint8_t key_length; /* 2 */
-+ grub_uint8_t fanout; /* 3 */
-+ grub_uint8_t depth; /* 4 */
-+ grub_uint32_t leaf_length; /* 8 */
-+ grub_uint64_t node_offset; /* 16 */
-+ grub_uint8_t node_depth; /* 17 */
-+ grub_uint8_t inner_length; /* 18 */
-+ grub_uint8_t reserved[14]; /* 32 */
-+ grub_uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
-+ grub_uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
-+} blake2b_param;
-+#pragma pack(pop)
-+
-+typedef struct __blake2b_state {
-+ grub_uint64_t h[8];
-+ grub_uint64_t t[2];
-+ grub_uint64_t f[2];
-+ grub_uint8_t buf[BLAKE2B_BLOCKBYTES];
-+ unsigned buflen;
-+ unsigned outlen;
-+ grub_uint8_t last_node;
-+} blake2b_state;
-+
-+/* Ensure param structs have not been wrongly padded */
-+/* Poor man's static_assert */
-+enum {
-+ blake2_size_check_0 = 1 / !!(GRUB_CHAR_BIT == 8),
-+ blake2_size_check_2 =
-+ 1 / !!(sizeof(blake2b_param) == sizeof(grub_uint64_t) * GRUB_CHAR_BIT)
-+};
-+
-+/* Streaming API */
-+ARGON2_LOCAL int blake2b_init(blake2b_state *S, grub_size_t outlen);
-+ARGON2_LOCAL int blake2b_init_key(blake2b_state *S, grub_size_t outlen, const void *key,
-+ grub_size_t keylen);
-+ARGON2_LOCAL int blake2b_init_param(blake2b_state *S, const blake2b_param *P);
-+ARGON2_LOCAL int blake2b_update(blake2b_state *S, const void *in, grub_size_t inlen);
-+ARGON2_LOCAL int blake2b_final(blake2b_state *S, void *out, grub_size_t outlen);
-+
-+/* Simple API */
-+ARGON2_LOCAL int blake2b(void *out, grub_size_t outlen, const void *in, grub_size_t inlen,
-+ const void *key, grub_size_t keylen);
-+
-+/* Argon2 Team - Begin Code */
-+ARGON2_LOCAL int blake2b_long(void *out, grub_size_t outlen, const void *in, grub_size_t inlen);
-+/* Argon2 Team - End Code */
-+
-+#if defined(__cplusplus)
-+}
-+#endif
-+
-+#endif
-diff --git a/grub-core/lib/argon2/blake2/blake2b.c b/grub-core/lib/argon2/blake2/blake2b.c
-new file mode 100644
-index 000000000..53abd7bef
---- /dev/null
-+++ b/grub-core/lib/argon2/blake2/blake2b.c
-@@ -0,0 +1,388 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#include "blake2.h"
-+#include "blake2-impl.h"
-+
-+static const grub_uint64_t blake2b_IV[8] = {
-+ GRUB_UINT64_C(0x6a09e667f3bcc908), GRUB_UINT64_C(0xbb67ae8584caa73b),
-+ GRUB_UINT64_C(0x3c6ef372fe94f82b), GRUB_UINT64_C(0xa54ff53a5f1d36f1),
-+ GRUB_UINT64_C(0x510e527fade682d1), GRUB_UINT64_C(0x9b05688c2b3e6c1f),
-+ GRUB_UINT64_C(0x1f83d9abfb41bd6b), GRUB_UINT64_C(0x5be0cd19137e2179)};
-+
-+static const unsigned int blake2b_sigma[12][16] = {
-+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
-+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
-+ {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
-+ {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
-+ {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
-+ {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
-+ {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
-+ {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
-+ {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
-+ {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
-+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
-+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
-+};
-+
-+void clear_internal_memory(void *v, grub_size_t n);
-+
-+static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
-+ S->f[1] = (grub_uint64_t)-1;
-+}
-+
-+static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
-+ if (S->last_node) {
-+ blake2b_set_lastnode(S);
-+ }
-+ S->f[0] = (grub_uint64_t)-1;
-+}
-+
-+static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
-+ grub_uint64_t inc) {
-+ S->t[0] += inc;
-+ S->t[1] += (S->t[0] < inc);
-+}
-+
-+static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
-+ clear_internal_memory(S, sizeof(*S)); /* wipe */
-+ blake2b_set_lastblock(S); /* invalidate for further use */
-+}
-+
-+static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
-+ grub_memset(S, 0, sizeof(*S));
-+ grub_memcpy(S->h, blake2b_IV, sizeof(S->h));
-+}
-+
-+int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
-+ const unsigned char *p = (const unsigned char *)P;
-+ unsigned int i;
-+
-+ if (NULL == P || NULL == S) {
-+ return -1;
-+ }
-+
-+ blake2b_init0(S);
-+ /* IV XOR Parameter Block */
-+ for (i = 0; i < 8; ++i) {
-+ S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
-+ }
-+ S->outlen = P->digest_length;
-+ return 0;
-+}
-+
-+/* Sequential blake2b initialization */
-+int blake2b_init(blake2b_state *S, grub_size_t outlen) {
-+ blake2b_param P;
-+
-+ if (S == NULL) {
-+ return -1;
-+ }
-+
-+ if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
-+ blake2b_invalidate_state(S);
-+ return -1;
-+ }
-+
-+ /* Setup Parameter Block for unkeyed BLAKE2 */
-+ P.digest_length = (grub_uint8_t)outlen;
-+ P.key_length = 0;
-+ P.fanout = 1;
-+ P.depth = 1;
-+ P.leaf_length = 0;
-+ P.node_offset = 0;
-+ P.node_depth = 0;
-+ P.inner_length = 0;
-+ grub_memset(P.reserved, 0, sizeof(P.reserved));
-+ grub_memset(P.salt, 0, sizeof(P.salt));
-+ grub_memset(P.personal, 0, sizeof(P.personal));
-+
-+ return blake2b_init_param(S, &P);
-+}
-+
-+int blake2b_init_key(blake2b_state *S, grub_size_t outlen, const void *key,
-+ grub_size_t keylen) {
-+ blake2b_param P;
-+
-+ if (S == NULL) {
-+ return -1;
-+ }
-+
-+ if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
-+ blake2b_invalidate_state(S);
-+ return -1;
-+ }
-+
-+ if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) {
-+ blake2b_invalidate_state(S);
-+ return -1;
-+ }
-+
-+ /* Setup Parameter Block for keyed BLAKE2 */
-+ P.digest_length = (grub_uint8_t)outlen;
-+ P.key_length = (grub_uint8_t)keylen;
-+ P.fanout = 1;
-+ P.depth = 1;
-+ P.leaf_length = 0;
-+ P.node_offset = 0;
-+ P.node_depth = 0;
-+ P.inner_length = 0;
-+ grub_memset(P.reserved, 0, sizeof(P.reserved));
-+ grub_memset(P.salt, 0, sizeof(P.salt));
-+ grub_memset(P.personal, 0, sizeof(P.personal));
-+
-+ if (blake2b_init_param(S, &P) < 0) {
-+ blake2b_invalidate_state(S);
-+ return -1;
-+ }
-+
-+ {
-+ grub_uint8_t block[BLAKE2B_BLOCKBYTES];
-+ grub_memset(block, 0, BLAKE2B_BLOCKBYTES);
-+ grub_memcpy(block, key, keylen);
-+ blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
-+ /* Burn the key from stack */
-+ clear_internal_memory(block, BLAKE2B_BLOCKBYTES);
-+ }
-+ return 0;
-+}
-+
-+static void blake2b_compress(blake2b_state *S, const grub_uint8_t *block) {
-+ grub_uint64_t m[16];
-+ grub_uint64_t v[16];
-+ unsigned int i, r;
-+
-+ for (i = 0; i < 16; ++i) {
-+ m[i] = load64(block + i * sizeof(m[i]));
-+ }
-+
-+ for (i = 0; i < 8; ++i) {
-+ v[i] = S->h[i];
-+ }
-+
-+ v[8] = blake2b_IV[0];
-+ v[9] = blake2b_IV[1];
-+ v[10] = blake2b_IV[2];
-+ v[11] = blake2b_IV[3];
-+ v[12] = blake2b_IV[4] ^ S->t[0];
-+ v[13] = blake2b_IV[5] ^ S->t[1];
-+ v[14] = blake2b_IV[6] ^ S->f[0];
-+ v[15] = blake2b_IV[7] ^ S->f[1];
-+
-+#define G(r, i, a, b, c, d) \
-+ do { \
-+ a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
-+ d = rotr64(d ^ a, 32); \
-+ c = c + d; \
-+ b = rotr64(b ^ c, 24); \
-+ a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
-+ d = rotr64(d ^ a, 16); \
-+ c = c + d; \
-+ b = rotr64(b ^ c, 63); \
-+ } while ((void)0, 0)
-+
-+#define ROUND(r) \
-+ do { \
-+ G(r, 0, v[0], v[4], v[8], v[12]); \
-+ G(r, 1, v[1], v[5], v[9], v[13]); \
-+ G(r, 2, v[2], v[6], v[10], v[14]); \
-+ G(r, 3, v[3], v[7], v[11], v[15]); \
-+ G(r, 4, v[0], v[5], v[10], v[15]); \
-+ G(r, 5, v[1], v[6], v[11], v[12]); \
-+ G(r, 6, v[2], v[7], v[8], v[13]); \
-+ G(r, 7, v[3], v[4], v[9], v[14]); \
-+ } while ((void)0, 0)
-+
-+ for (r = 0; r < 12; ++r) {
-+ ROUND(r);
-+ }
-+
-+ for (i = 0; i < 8; ++i) {
-+ S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
-+ }
-+
-+#undef G
-+#undef ROUND
-+}
-+
-+int blake2b_update(blake2b_state *S, const void *in, grub_size_t inlen) {
-+ const grub_uint8_t *pin = (const grub_uint8_t *)in;
-+
-+ if (inlen == 0) {
-+ return 0;
-+ }
-+
-+ /* Sanity check */
-+ if (S == NULL || in == NULL) {
-+ return -1;
-+ }
-+
-+ /* Is this a reused state? */
-+ if (S->f[0] != 0) {
-+ return -1;
-+ }
-+
-+ if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
-+ /* Complete current block */
-+ grub_size_t left = S->buflen;
-+ grub_size_t fill = BLAKE2B_BLOCKBYTES - left;
-+ grub_memcpy(&S->buf[left], pin, fill);
-+ blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
-+ blake2b_compress(S, S->buf);
-+ S->buflen = 0;
-+ inlen -= fill;
-+ pin += fill;
-+ /* Avoid buffer copies when possible */
-+ while (inlen > BLAKE2B_BLOCKBYTES) {
-+ blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
-+ blake2b_compress(S, pin);
-+ inlen -= BLAKE2B_BLOCKBYTES;
-+ pin += BLAKE2B_BLOCKBYTES;
-+ }
-+ }
-+ grub_memcpy(&S->buf[S->buflen], pin, inlen);
-+ S->buflen += (unsigned int)inlen;
-+ return 0;
-+}
-+
-+int blake2b_final(blake2b_state *S, void *out, grub_size_t outlen) {
-+ grub_uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
-+ unsigned int i;
-+
-+ /* Sanity checks */
-+ if (S == NULL || out == NULL || outlen < S->outlen) {
-+ return -1;
-+ }
-+
-+ /* Is this a reused state? */
-+ if (S->f[0] != 0) {
-+ return -1;
-+ }
-+
-+ blake2b_increment_counter(S, S->buflen);
-+ blake2b_set_lastblock(S);
-+ grub_memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
-+ blake2b_compress(S, S->buf);
-+
-+ for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
-+ store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
-+ }
-+
-+ grub_memcpy(out, buffer, S->outlen);
-+ clear_internal_memory(buffer, sizeof(buffer));
-+ clear_internal_memory(S->buf, sizeof(S->buf));
-+ clear_internal_memory(S->h, sizeof(S->h));
-+ return 0;
-+}
-+
-+int blake2b(void *out, grub_size_t outlen, const void *in, grub_size_t inlen,
-+ const void *key, grub_size_t keylen) {
-+ blake2b_state S;
-+ int ret = -1;
-+
-+ /* Verify parameters */
-+ if (NULL == in && inlen > 0) {
-+ goto fail;
-+ }
-+
-+ if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) {
-+ goto fail;
-+ }
-+
-+ if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) {
-+ goto fail;
-+ }
-+
-+ if (keylen > 0) {
-+ if (blake2b_init_key(&S, outlen, key, keylen) < 0) {
-+ goto fail;
-+ }
-+ } else {
-+ if (blake2b_init(&S, outlen) < 0) {
-+ goto fail;
-+ }
-+ }
-+
-+ if (blake2b_update(&S, in, inlen) < 0) {
-+ goto fail;
-+ }
-+ ret = blake2b_final(&S, out, outlen);
-+
-+fail:
-+ clear_internal_memory(&S, sizeof(S));
-+ return ret;
-+}
-+
-+/* Argon2 Team - Begin Code */
-+int blake2b_long(void *pout, grub_size_t outlen, const void *in, grub_size_t inlen) {
-+ grub_uint8_t *out = (grub_uint8_t *)pout;
-+ blake2b_state blake_state;
-+ grub_uint8_t outlen_bytes[sizeof(grub_uint32_t)] = {0};
-+ int ret = -1;
-+
-+ if (outlen > GRUB_UINT32_MAX) {
-+ goto fail;
-+ }
-+
-+ /* Ensure little-endian byte order! */
-+ store32(outlen_bytes, (grub_uint32_t)outlen);
-+
-+#define TRY(statement) \
-+ do { \
-+ ret = statement; \
-+ if (ret < 0) { \
-+ goto fail; \
-+ } \
-+ } while ((void)0, 0)
-+
-+ if (outlen <= BLAKE2B_OUTBYTES) {
-+ TRY(blake2b_init(&blake_state, outlen));
-+ TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
-+ TRY(blake2b_update(&blake_state, in, inlen));
-+ TRY(blake2b_final(&blake_state, out, outlen));
-+ } else {
-+ grub_uint32_t toproduce;
-+ grub_uint8_t out_buffer[BLAKE2B_OUTBYTES];
-+ grub_uint8_t in_buffer[BLAKE2B_OUTBYTES];
-+ TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
-+ TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
-+ TRY(blake2b_update(&blake_state, in, inlen));
-+ TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
-+ grub_memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
-+ out += BLAKE2B_OUTBYTES / 2;
-+ toproduce = (grub_uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
-+
-+ while (toproduce > BLAKE2B_OUTBYTES) {
-+ grub_memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
-+ TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer,
-+ BLAKE2B_OUTBYTES, NULL, 0));
-+ grub_memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
-+ out += BLAKE2B_OUTBYTES / 2;
-+ toproduce -= BLAKE2B_OUTBYTES / 2;
-+ }
-+
-+ grub_memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
-+ TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL,
-+ 0));
-+ grub_memcpy(out, out_buffer, toproduce);
-+ }
-+fail:
-+ clear_internal_memory(&blake_state, sizeof(blake_state));
-+ return ret;
-+#undef TRY
-+}
-+/* Argon2 Team - End Code */
-diff --git a/grub-core/lib/argon2/blake2/blamka-round-ref.h b/grub-core/lib/argon2/blake2/blamka-round-ref.h
-new file mode 100644
-index 000000000..7f0071ada
---- /dev/null
-+++ b/grub-core/lib/argon2/blake2/blamka-round-ref.h
-@@ -0,0 +1,56 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#ifndef BLAKE_ROUND_MKA_H
-+#define BLAKE_ROUND_MKA_H
-+
-+#include "blake2.h"
-+#include "blake2-impl.h"
-+
-+/* designed by the Lyra PHC team */
-+static BLAKE2_INLINE grub_uint64_t fBlaMka(grub_uint64_t x, grub_uint64_t y) {
-+ const grub_uint64_t m = GRUB_UINT64_C(0xFFFFFFFF);
-+ const grub_uint64_t xy = (x & m) * (y & m);
-+ return x + y + 2 * xy;
-+}
-+
-+#define G(a, b, c, d) \
-+ do { \
-+ a = fBlaMka(a, b); \
-+ d = rotr64(d ^ a, 32); \
-+ c = fBlaMka(c, d); \
-+ b = rotr64(b ^ c, 24); \
-+ a = fBlaMka(a, b); \
-+ d = rotr64(d ^ a, 16); \
-+ c = fBlaMka(c, d); \
-+ b = rotr64(b ^ c, 63); \
-+ } while ((void)0, 0)
-+
-+#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
-+ v12, v13, v14, v15) \
-+ do { \
-+ G(v0, v4, v8, v12); \
-+ G(v1, v5, v9, v13); \
-+ G(v2, v6, v10, v14); \
-+ G(v3, v7, v11, v15); \
-+ G(v0, v5, v10, v15); \
-+ G(v1, v6, v11, v12); \
-+ G(v2, v7, v8, v13); \
-+ G(v3, v4, v9, v14); \
-+ } while ((void)0, 0)
-+
-+#endif
-diff --git a/grub-core/lib/argon2/core.c b/grub-core/lib/argon2/core.c
-new file mode 100644
-index 000000000..0fe5b74cb
---- /dev/null
-+++ b/grub-core/lib/argon2/core.c
-@@ -0,0 +1,506 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+/*For memory wiping*/
-+#ifdef _MSC_VER
-+#include <windows.h>
-+#include <winbase.h> /* For SecureZeroMemory */
-+#endif
-+#if defined __STDC_LIB_EXT1__
-+#define __STDC_WANT_LIB_EXT1__ 1
-+#endif
-+#define VC_GE_2005(version) (version >= 1400)
-+
-+#include "core.h"
-+#include "blake2/blake2.h"
-+#include "blake2/blake2-impl.h"
-+
-+#ifdef GENKAT
-+#include "genkat.h"
-+#endif
-+
-+#if defined(__clang__)
-+#if __has_attribute(optnone)
-+#define NOT_OPTIMIZED __attribute__((optnone))
-+#endif
-+#elif defined(__GNUC__)
-+#define GCC_VERSION \
-+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-+#if GCC_VERSION >= 40400
-+#define NOT_OPTIMIZED __attribute__((optimize("O0")))
-+#endif
-+#endif
-+#ifndef NOT_OPTIMIZED
-+#define NOT_OPTIMIZED
-+#endif
-+
-+/***************Instance and Position constructors**********/
-+void init_block_value(block *b, grub_uint8_t in) { grub_memset(b->v, in, sizeof(b->v)); }
-+
-+void copy_block(block *dst, const block *src) {
-+ grub_memcpy(dst->v, src->v, sizeof(grub_uint64_t) * ARGON2_QWORDS_IN_BLOCK);
-+}
-+
-+void xor_block(block *dst, const block *src) {
-+ int i;
-+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
-+ dst->v[i] ^= src->v[i];
-+ }
-+}
-+
-+static void load_block(block *dst, const void *input) {
-+ unsigned i;
-+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
-+ dst->v[i] = load64((const grub_uint8_t *)input + i * sizeof(dst->v[i]));
-+ }
-+}
-+
-+static void store_block(void *output, const block *src) {
-+ unsigned i;
-+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
-+ store64((grub_uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
-+ }
-+}
-+
-+/***************Memory functions*****************/
-+
-+int allocate_memory(const argon2_context *context, grub_uint8_t **memory,
-+ grub_size_t num, grub_size_t size) {
-+ grub_size_t memory_size = num*size;
-+ if (memory == NULL) {
-+ return ARGON2_MEMORY_ALLOCATION_ERROR;
-+ }
-+
-+ /* 1. Check for multiplication overflow */
-+ if (size != 0 && memory_size / size != num) {
-+ return ARGON2_MEMORY_ALLOCATION_ERROR;
-+ }
-+
-+ /* 2. Try to allocate with appropriate allocator */
-+ if (context->allocate_cbk) {
-+ (context->allocate_cbk)(memory, memory_size);
-+ } else {
-+ *memory = grub_malloc(memory_size);
-+ }
-+
-+ if (*memory == NULL) {
-+ return ARGON2_MEMORY_ALLOCATION_ERROR;
-+ }
-+
-+ return ARGON2_OK;
-+}
-+
-+void grub_free_memory(const argon2_context *context, grub_uint8_t *memory,
-+ grub_size_t num, grub_size_t size) {
-+ grub_size_t memory_size = num*size;
-+ clear_internal_memory(memory, memory_size);
-+ if (context->grub_free_cbk) {
-+ (context->grub_free_cbk)(memory, memory_size);
-+ } else {
-+ grub_free(memory);
-+ }
-+}
-+
-+void NOT_OPTIMIZED secure_wipe_memory(void *v, grub_size_t n) {
-+ static void *(*const volatile grub_memset_sec)(void *, int, grub_size_t) = &grub_memset;
-+ grub_memset_sec(v, 0, n);
-+}
-+
-+/* Memory clear flag defaults to true. */
-+int FLAG_clear_internal_memory = 1;
-+void clear_internal_memory(void *v, grub_size_t n) {
-+ if (FLAG_clear_internal_memory && v) {
-+ secure_wipe_memory(v, n);
-+ }
-+}
-+
-+void finalize(const argon2_context *context, argon2_instance_t *instance) {
-+ if (context != NULL && instance != NULL) {
-+ block blockhash;
-+ grub_uint32_t l;
-+
-+ copy_block(&blockhash, instance->memory + instance->lane_length - 1);
-+
-+ /* XOR the last blocks */
-+ for (l = 1; l < instance->lanes; ++l) {
-+ grub_uint32_t last_block_in_lane =
-+ l * instance->lane_length + (instance->lane_length - 1);
-+ xor_block(&blockhash, instance->memory + last_block_in_lane);
-+ }
-+
-+ /* Hash the result */
-+ {
-+ grub_uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
-+ store_block(blockhash_bytes, &blockhash);
-+ blake2b_long(context->out, context->outlen, blockhash_bytes,
-+ ARGON2_BLOCK_SIZE);
-+ /* clear blockhash and blockhash_bytes */
-+ clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE);
-+ clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
-+ }
-+
-+#ifdef GENKAT
-+ print_tag(context->out, context->outlen);
-+#endif
-+
-+ grub_free_memory(context, (grub_uint8_t *)instance->memory,
-+ instance->memory_blocks, sizeof(block));
-+ }
-+}
-+
-+grub_uint32_t index_alpha(const argon2_instance_t *instance,
-+ const argon2_position_t *position, grub_uint32_t pseudo_rand,
-+ int same_lane) {
-+ /*
-+ * Pass 0:
-+ * This lane : all already finished segments plus already constructed
-+ * blocks in this segment
-+ * Other lanes : all already finished segments
-+ * Pass 1+:
-+ * This lane : (SYNC_POINTS - 1) last segments plus already constructed
-+ * blocks in this segment
-+ * Other lanes : (SYNC_POINTS - 1) last segments
-+ */
-+ grub_uint32_t reference_area_size;
-+ grub_uint64_t relative_position;
-+ grub_uint64_t start_position, absolute_position;
-+
-+ if (0 == position->pass) {
-+ /* First pass */
-+ if (0 == position->slice) {
-+ /* First slice */
-+ reference_area_size =
-+ position->index - 1; /* all but the previous */
-+ } else {
-+ if (same_lane) {
-+ /* The same lane => add current segment */
-+ reference_area_size =
-+ position->slice * instance->segment_length +
-+ position->index - 1;
-+ } else {
-+ reference_area_size =
-+ position->slice * instance->segment_length +
-+ ((position->index == 0) ? (-1) : 0);
-+ }
-+ }
-+ } else {
-+ /* Second pass */
-+ if (same_lane) {
-+ reference_area_size = instance->lane_length -
-+ instance->segment_length + position->index -
-+ 1;
-+ } else {
-+ reference_area_size = instance->lane_length -
-+ instance->segment_length +
-+ ((position->index == 0) ? (-1) : 0);
-+ }
-+ }
-+
-+ /* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
-+ * relative position */
-+ relative_position = pseudo_rand;
-+ relative_position = relative_position * relative_position >> 32;
-+ relative_position = reference_area_size - 1 -
-+ (reference_area_size * relative_position >> 32);
-+
-+ /* 1.2.5 Computing starting position */
-+ start_position = 0;
-+
-+ if (0 != position->pass) {
-+ start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
-+ ? 0
-+ : (position->slice + 1) * instance->segment_length;
-+ }
-+
-+ /* 1.2.6. Computing absolute position */
-+ grub_divmod64 (start_position + relative_position, instance->lane_length,
-+ &absolute_position); /* absolute position */
-+ return absolute_position;
-+}
-+
-+/* Single-threaded version for p=1 case */
-+static int fill_memory_blocks_st(argon2_instance_t *instance) {
-+ grub_uint32_t r, s, l;
-+
-+ for (r = 0; r < instance->passes; ++r) {
-+ for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
-+ for (l = 0; l < instance->lanes; ++l) {
-+ argon2_position_t position = {r, l, (grub_uint8_t)s, 0};
-+ fill_segment(instance, position);
-+ }
-+ }
-+#ifdef GENKAT
-+ internal_kat(instance, r); /* Print all memory blocks */
-+#endif
-+ }
-+ return ARGON2_OK;
-+}
-+
-+int fill_memory_blocks(argon2_instance_t *instance) {
-+ if (instance == NULL || instance->lanes == 0) {
-+ return ARGON2_INCORRECT_PARAMETER;
-+ }
-+ return fill_memory_blocks_st(instance);
-+}
-+
-+int validate_inputs(const argon2_context *context) {
-+ if (NULL == context) {
-+ return ARGON2_INCORRECT_PARAMETER;
-+ }
-+
-+ if (NULL == context->out) {
-+ return ARGON2_OUTPUT_PTR_NULL;
-+ }
-+
-+ /* Validate output length */
-+ if (ARGON2_MIN_OUTLEN > context->outlen) {
-+ return ARGON2_OUTPUT_TOO_SHORT;
-+ }
-+
-+ if (ARGON2_MAX_OUTLEN < context->outlen) {
-+ return ARGON2_OUTPUT_TOO_LONG;
-+ }
-+
-+ /* Validate password (required param) */
-+ if (NULL == context->pwd) {
-+ if (0 != context->pwdlen) {
-+ return ARGON2_PWD_PTR_MISMATCH;
-+ }
-+ }
-+
-+ if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
-+ return ARGON2_PWD_TOO_LONG;
-+ }
-+
-+ /* Validate salt (required param) */
-+ if (NULL == context->salt) {
-+ if (0 != context->saltlen) {
-+ return ARGON2_SALT_PTR_MISMATCH;
-+ }
-+ }
-+
-+ if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
-+ return ARGON2_SALT_TOO_SHORT;
-+ }
-+
-+ if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
-+ return ARGON2_SALT_TOO_LONG;
-+ }
-+
-+ /* Validate secret (optional param) */
-+ if (NULL == context->secret) {
-+ if (0 != context->secretlen) {
-+ return ARGON2_SECRET_PTR_MISMATCH;
-+ }
-+ } else {
-+ if (ARGON2_MAX_SECRET < context->secretlen) {
-+ return ARGON2_SECRET_TOO_LONG;
-+ }
-+ }
-+
-+ /* Validate associated data (optional param) */
-+ if (NULL == context->ad) {
-+ if (0 != context->adlen) {
-+ return ARGON2_AD_PTR_MISMATCH;
-+ }
-+ } else {
-+ if (ARGON2_MAX_AD_LENGTH < context->adlen) {
-+ return ARGON2_AD_TOO_LONG;
-+ }
-+ }
-+
-+ /* Validate memory cost */
-+ if (ARGON2_MIN_MEMORY > context->m_cost) {
-+ return ARGON2_MEMORY_TOO_LITTLE;
-+ }
-+
-+ if (context->m_cost < 8 * context->lanes) {
-+ return ARGON2_MEMORY_TOO_LITTLE;
-+ }
-+
-+ /* Validate time cost */
-+ if (ARGON2_MIN_TIME > context->t_cost) {
-+ return ARGON2_TIME_TOO_SMALL;
-+ }
-+
-+ if (ARGON2_MAX_TIME < context->t_cost) {
-+ return ARGON2_TIME_TOO_LARGE;
-+ }
-+
-+ /* Validate lanes */
-+ if (ARGON2_MIN_LANES > context->lanes) {
-+ return ARGON2_LANES_TOO_FEW;
-+ }
-+
-+ if (ARGON2_MAX_LANES < context->lanes) {
-+ return ARGON2_LANES_TOO_MANY;
-+ }
-+
-+ /* Validate threads */
-+ if (ARGON2_MIN_THREADS > context->threads) {
-+ return ARGON2_THREADS_TOO_FEW;
-+ }
-+
-+ if (ARGON2_MAX_THREADS < context->threads) {
-+ return ARGON2_THREADS_TOO_MANY;
-+ }
-+
-+ if (NULL != context->allocate_cbk && NULL == context->grub_free_cbk) {
-+ return ARGON2_FREE_MEMORY_CBK_NULL;
-+ }
-+
-+ if (NULL == context->allocate_cbk && NULL != context->grub_free_cbk) {
-+ return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
-+ }
-+
-+ return ARGON2_OK;
-+}
-+
-+void fill_first_blocks(grub_uint8_t *blockhash, const argon2_instance_t *instance) {
-+ grub_uint32_t l;
-+ /* Make the first and second block in each lane as G(H0||0||i) or
-+ G(H0||1||i) */
-+ grub_uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
-+ for (l = 0; l < instance->lanes; ++l) {
-+
-+ store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
-+ store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
-+ blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
-+ ARGON2_PREHASH_SEED_LENGTH);
-+ load_block(&instance->memory[l * instance->lane_length + 0],
-+ blockhash_bytes);
-+
-+ store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
-+ blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
-+ ARGON2_PREHASH_SEED_LENGTH);
-+ load_block(&instance->memory[l * instance->lane_length + 1],
-+ blockhash_bytes);
-+ }
-+ clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
-+}
-+
-+void initial_hash(grub_uint8_t *blockhash, argon2_context *context,
-+ argon2_type type) {
-+ blake2b_state BlakeHash;
-+ grub_uint8_t value[sizeof(grub_uint32_t)];
-+
-+ if (NULL == context || NULL == blockhash) {
-+ return;
-+ }
-+
-+ blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
-+
-+ store32(&value, context->lanes);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ store32(&value, context->outlen);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ store32(&value, context->m_cost);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ store32(&value, context->t_cost);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ store32(&value, context->version);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ store32(&value, (grub_uint32_t)type);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ store32(&value, context->pwdlen);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ if (context->pwd != NULL) {
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)context->pwd,
-+ context->pwdlen);
-+
-+ if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
-+ secure_wipe_memory(context->pwd, context->pwdlen);
-+ context->pwdlen = 0;
-+ }
-+ }
-+
-+ store32(&value, context->saltlen);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ if (context->salt != NULL) {
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)context->salt,
-+ context->saltlen);
-+ }
-+
-+ store32(&value, context->secretlen);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ if (context->secret != NULL) {
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)context->secret,
-+ context->secretlen);
-+
-+ if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
-+ secure_wipe_memory(context->secret, context->secretlen);
-+ context->secretlen = 0;
-+ }
-+ }
-+
-+ store32(&value, context->adlen);
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)&value, sizeof(value));
-+
-+ if (context->ad != NULL) {
-+ blake2b_update(&BlakeHash, (const grub_uint8_t *)context->ad,
-+ context->adlen);
-+ }
-+
-+ blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
-+}
-+
-+int initialize(argon2_instance_t *instance, argon2_context *context) {
-+ grub_uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
-+ int result = ARGON2_OK;
-+
-+ if (instance == NULL || context == NULL)
-+ return ARGON2_INCORRECT_PARAMETER;
-+ instance->context_ptr = context;
-+
-+ /* 1. Memory allocation */
-+ result = allocate_memory(context, (grub_uint8_t **)&(instance->memory),
-+ instance->memory_blocks, sizeof(block));
-+ if (result != ARGON2_OK) {
-+ return result;
-+ }
-+
-+ /* 2. Initial hashing */
-+ /* H_0 + 8 extra bytes to produce the first blocks */
-+ /* grub_uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
-+ /* Hashing all inputs */
-+ initial_hash(blockhash, context, instance->type);
-+ /* Zeroing 8 extra bytes */
-+ clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
-+ ARGON2_PREHASH_SEED_LENGTH -
-+ ARGON2_PREHASH_DIGEST_LENGTH);
-+
-+#ifdef GENKAT
-+ initial_kat(blockhash, context, instance->type);
-+#endif
-+
-+ /* 3. Creating first blocks, we always have at least two blocks in a slice
-+ */
-+ fill_first_blocks(blockhash, instance);
-+ /* Clearing the hash */
-+ clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
-+
-+ return ARGON2_OK;
-+}
-diff --git a/grub-core/lib/argon2/core.h b/grub-core/lib/argon2/core.h
-new file mode 100644
-index 000000000..bbcd56998
---- /dev/null
-+++ b/grub-core/lib/argon2/core.h
-@@ -0,0 +1,228 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#ifndef ARGON2_CORE_H
-+#define ARGON2_CORE_H
-+
-+#include "argon2.h"
-+
-+#define CONST_CAST(x) (x)(grub_addr_t)
-+
-+/**********************Argon2 internal constants*******************************/
-+
-+enum argon2_core_constants {
-+ /* Memory block size in bytes */
-+ ARGON2_BLOCK_SIZE = 1024,
-+ ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
-+ ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
-+ ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32,
-+ ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64,
-+
-+ /* Number of pseudo-random values generated by one call to Blake in Argon2i
-+ to
-+ generate reference block positions */
-+ ARGON2_ADDRESSES_IN_BLOCK = 128,
-+
-+ /* Pre-hashing digest length and its extension*/
-+ ARGON2_PREHASH_DIGEST_LENGTH = 64,
-+ ARGON2_PREHASH_SEED_LENGTH = 72
-+};
-+
-+/*************************Argon2 internal data types***********************/
-+
-+/*
-+ * Structure for the (1KB) memory block implemented as 128 64-bit words.
-+ * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
-+ * bounds checking).
-+ */
-+typedef struct block_ { grub_uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
-+
-+/*****************Functions that work with the block******************/
-+
-+/* Initialize each byte of the block with @in */
-+void init_block_value(block *b, grub_uint8_t in);
-+
-+/* Copy block @src to block @dst */
-+void copy_block(block *dst, const block *src);
-+
-+/* XOR @src onto @dst bytewise */
-+void xor_block(block *dst, const block *src);
-+
-+/*
-+ * Argon2 instance: memory pointer, number of passes, amount of memory, type,
-+ * and derived values.
-+ * Used to evaluate the number and location of blocks to construct in each
-+ * thread
-+ */
-+typedef struct Argon2_instance_t {
-+ block *memory; /* Memory pointer */
-+ grub_uint32_t version;
-+ grub_uint32_t passes; /* Number of passes */
-+ grub_uint32_t memory_blocks; /* Number of blocks in memory */
-+ grub_uint32_t segment_length;
-+ grub_uint32_t lane_length;
-+ grub_uint32_t lanes;
-+ grub_uint32_t threads;
-+ argon2_type type;
-+ int print_internals; /* whether to print the memory blocks */
-+ argon2_context *context_ptr; /* points back to original context */
-+} argon2_instance_t;
-+
-+/*
-+ * Argon2 position: where we construct the block right now. Used to distribute
-+ * work between threads.
-+ */
-+typedef struct Argon2_position_t {
-+ grub_uint32_t pass;
-+ grub_uint32_t lane;
-+ grub_uint8_t slice;
-+ grub_uint32_t index;
-+} argon2_position_t;
-+
-+/*Struct that holds the inputs for thread handling FillSegment*/
-+typedef struct Argon2_thread_data {
-+ argon2_instance_t *instance_ptr;
-+ argon2_position_t pos;
-+} argon2_thread_data;
-+
-+/*************************Argon2 core functions********************************/
-+
-+/* Allocates memory to the given pointer, uses the appropriate allocator as
-+ * specified in the context. Total allocated memory is num*size.
-+ * @param context argon2_context which specifies the allocator
-+ * @param memory pointer to the pointer to the memory
-+ * @param size the size in bytes for each element to be allocated
-+ * @param num the number of elements to be allocated
-+ * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
-+ */
-+int allocate_memory(const argon2_context *context, grub_uint8_t **memory,
-+ grub_size_t num, grub_size_t size);
-+
-+/*
-+ * Frees memory at the given pointer, uses the appropriate deallocator as
-+ * specified in the context. Also cleans the memory using clear_internal_memory.
-+ * @param context argon2_context which specifies the deallocator
-+ * @param memory pointer to buffer to be grub_freed
-+ * @param size the size in bytes for each element to be deallocated
-+ * @param num the number of elements to be deallocated
-+ */
-+void grub_free_memory(const argon2_context *context, grub_uint8_t *memory,
-+ grub_size_t num, grub_size_t size);
-+
-+/* Function that securely cleans the memory. This ignores any flags set
-+ * regarding clearing memory. Usually one just calls clear_internal_memory.
-+ * @param mem Pointer to the memory
-+ * @param s Memory size in bytes
-+ */
-+void secure_wipe_memory(void *v, grub_size_t n);
-+
-+/* Function that securely clears the memory if FLAG_clear_internal_memory is
-+ * set. If the flag isn't set, this function does nothing.
-+ * @param mem Pointer to the memory
-+ * @param s Memory size in bytes
-+ */
-+void clear_internal_memory(void *v, grub_size_t n);
-+
-+/*
-+ * Computes absolute position of reference block in the lane following a skewed
-+ * distribution and using a pseudo-random value as input
-+ * @param instance Pointer to the current instance
-+ * @param position Pointer to the current position
-+ * @param pseudo_rand 32-bit pseudo-random value used to determine the position
-+ * @param same_lane Indicates if the block will be taken from the current lane.
-+ * If so we can reference the current segment
-+ * @pre All pointers must be valid
-+ */
-+grub_uint32_t index_alpha(const argon2_instance_t *instance,
-+ const argon2_position_t *position, grub_uint32_t pseudo_rand,
-+ int same_lane);
-+
-+/*
-+ * Function that validates all inputs against predefined restrictions and return
-+ * an error code
-+ * @param context Pointer to current Argon2 context
-+ * @return ARGON2_OK if everything is all right, otherwise one of error codes
-+ * (all defined in <argon2.h>
-+ */
-+int validate_inputs(const argon2_context *context);
-+
-+/*
-+ * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
-+ * password and secret if needed
-+ * @param context Pointer to the Argon2 internal structure containing memory
-+ * pointer, and parameters for time and space requirements.
-+ * @param blockhash Buffer for pre-hashing digest
-+ * @param type Argon2 type
-+ * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
-+ * allocated
-+ */
-+void initial_hash(grub_uint8_t *blockhash, argon2_context *context,
-+ argon2_type type);
-+
-+/*
-+ * Function creates first 2 blocks per lane
-+ * @param instance Pointer to the current instance
-+ * @param blockhash Pointer to the pre-hashing digest
-+ * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
-+ */
-+void fill_first_blocks(grub_uint8_t *blockhash, const argon2_instance_t *instance);
-+
-+/*
-+ * Function allocates memory, hashes the inputs with Blake, and creates first
-+ * two blocks. Returns the pointer to the main memory with 2 blocks per lane
-+ * initialized
-+ * @param context Pointer to the Argon2 internal structure containing memory
-+ * pointer, and parameters for time and space requirements.
-+ * @param instance Current Argon2 instance
-+ * @return Zero if successful, -1 if memory failed to allocate. @context->state
-+ * will be modified if successful.
-+ */
-+int initialize(argon2_instance_t *instance, argon2_context *context);
-+
-+/*
-+ * XORing the last block of each lane, hashing it, making the tag. Deallocates
-+ * the memory.
-+ * @param context Pointer to current Argon2 context (use only the out parameters
-+ * from it)
-+ * @param instance Pointer to current instance of Argon2
-+ * @pre instance->state must point to necessary amount of memory
-+ * @pre context->out must point to outlen bytes of memory
-+ * @pre if context->grub_free_cbk is not NULL, it should point to a function that
-+ * deallocates memory
-+ */
-+void finalize(const argon2_context *context, argon2_instance_t *instance);
-+
-+/*
-+ * Function that fills the segment using previous segments also from other
-+ * threads
-+ * @param context current context
-+ * @param instance Pointer to the current instance
-+ * @param position Current position
-+ * @pre all block pointers must be valid
-+ */
-+void fill_segment(const argon2_instance_t *instance,
-+ argon2_position_t position);
-+
-+/*
-+ * Function that fills the entire memory t_cost times based on the first two
-+ * blocks in each lane
-+ * @param instance Pointer to the current instance
-+ * @return ARGON2_OK if successful, @context->state
-+ */
-+int fill_memory_blocks(argon2_instance_t *instance);
-+
-+#endif
-diff --git a/grub-core/lib/argon2/ref.c b/grub-core/lib/argon2/ref.c
-new file mode 100644
-index 000000000..c933df80d
---- /dev/null
-+++ b/grub-core/lib/argon2/ref.c
-@@ -0,0 +1,190 @@
-+/*
-+ * Argon2 reference source code package - reference C implementations
-+ *
-+ * Copyright 2015
-+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
-+ *
-+ * You may use this work under the terms of a Creative Commons CC0 1.0
-+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
-+ * these licenses can be found at:
-+ *
-+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
-+ * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * You should have received a copy of both of these licenses along with this
-+ * software. If not, they may be obtained at the above URLs.
-+ */
-+
-+#include "argon2.h"
-+#include "core.h"
-+
-+#include "blake2/blamka-round-ref.h"
-+#include "blake2/blake2-impl.h"
-+#include "blake2/blake2.h"
-+
-+
-+/*
-+ * Function fills a new memory block and optionally XORs the old block over the new one.
-+ * @next_block must be initialized.
-+ * @param prev_block Pointer to the previous block
-+ * @param ref_block Pointer to the reference block
-+ * @param next_block Pointer to the block to be constructed
-+ * @param with_xor Whether to XOR into the new block (1) or just overwrite (0)
-+ * @pre all block pointers must be valid
-+ */
-+static void fill_block(const block *prev_block, const block *ref_block,
-+ block *next_block, int with_xor) {
-+ block blockR, block_tmp;
-+ unsigned i;
-+
-+ copy_block(&blockR, ref_block);
-+ xor_block(&blockR, prev_block);
-+ copy_block(&block_tmp, &blockR);
-+ /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */
-+ if (with_xor) {
-+ /* Saving the next block contents for XOR over: */
-+ xor_block(&block_tmp, next_block);
-+ /* Now blockR = ref_block + prev_block and
-+ block_tmp = ref_block + prev_block + next_block */
-+ }
-+
-+ /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
-+ (16,17,..31)... finally (112,113,...127) */
-+ for (i = 0; i < 8; ++i) {
-+ BLAKE2_ROUND_NOMSG(
-+ blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
-+ blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
-+ blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
-+ blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
-+ blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
-+ blockR.v[16 * i + 15]);
-+ }
-+
-+ /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
-+ (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
-+ for (i = 0; i < 8; i++) {
-+ BLAKE2_ROUND_NOMSG(
-+ blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
-+ blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
-+ blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
-+ blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
-+ blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
-+ blockR.v[2 * i + 113]);
-+ }
-+
-+ copy_block(next_block, &block_tmp);
-+ xor_block(next_block, &blockR);
-+}
-+
-+static void next_addresses(block *address_block, block *input_block,
-+ const block *zero_block) {
-+ input_block->v[6]++;
-+ fill_block(zero_block, input_block, address_block, 0);
-+ fill_block(zero_block, address_block, address_block, 0);
-+}
-+
-+void fill_segment(const argon2_instance_t *instance,
-+ argon2_position_t position) {
-+ block *ref_block = NULL, *curr_block = NULL;
-+ block address_block, input_block, zero_block;
-+ grub_uint64_t pseudo_rand, ref_index, ref_lane;
-+ grub_uint32_t prev_offset, curr_offset;
-+ grub_uint32_t starting_index;
-+ grub_uint32_t i;
-+ int data_independent_addressing;
-+
-+ if (instance == NULL) {
-+ return;
-+ }
-+
-+ data_independent_addressing =
-+ (instance->type == Argon2_i) ||
-+ (instance->type == Argon2_id && (position.pass == 0) &&
-+ (position.slice < ARGON2_SYNC_POINTS / 2));
-+
-+ if (data_independent_addressing) {
-+ init_block_value(&zero_block, 0);
-+ init_block_value(&input_block, 0);
-+
-+ input_block.v[0] = position.pass;
-+ input_block.v[1] = position.lane;
-+ input_block.v[2] = position.slice;
-+ input_block.v[3] = instance->memory_blocks;
-+ input_block.v[4] = instance->passes;
-+ input_block.v[5] = instance->type;
-+ }
-+
-+ starting_index = 0;
-+
-+ if ((0 == position.pass) && (0 == position.slice)) {
-+ starting_index = 2; /* we have already generated the first two blocks */
-+
-+ /* Don't forget to generate the first block of addresses: */
-+ if (data_independent_addressing) {
-+ next_addresses(&address_block, &input_block, &zero_block);
-+ }
-+ }
-+
-+ /* Offset of the current block */
-+ curr_offset = position.lane * instance->lane_length +
-+ position.slice * instance->segment_length + starting_index;
-+
-+ if (0 == curr_offset % instance->lane_length) {
-+ /* Last block in this lane */
-+ prev_offset = curr_offset + instance->lane_length - 1;
-+ } else {
-+ /* Previous block */
-+ prev_offset = curr_offset - 1;
-+ }
-+
-+ for (i = starting_index; i < instance->segment_length;
-+ ++i, ++curr_offset, ++prev_offset) {
-+ /*1.1 Rotating prev_offset if needed */
-+ if (curr_offset % instance->lane_length == 1) {
-+ prev_offset = curr_offset - 1;
-+ }
-+
-+ /* 1.2 Computing the index of the reference block */
-+ /* 1.2.1 Taking pseudo-random value from the previous block */
-+ if (data_independent_addressing) {
-+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
-+ next_addresses(&address_block, &input_block, &zero_block);
-+ }
-+ pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
-+ } else {
-+ pseudo_rand = instance->memory[prev_offset].v[0];
-+ }
-+
-+ /* 1.2.2 Computing the lane of the reference block */
-+ grub_divmod64 (pseudo_rand >> 32, instance->lanes, &ref_lane);
-+
-+ if ((position.pass == 0) && (position.slice == 0)) {
-+ /* Can not reference other lanes yet */
-+ ref_lane = position.lane;
-+ }
-+
-+ /* 1.2.3 Computing the number of possible reference block within the
-+ * lane.
-+ */
-+ position.index = i;
-+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
-+ ref_lane == position.lane);
-+
-+ /* 2 Creating a new block */
-+ ref_block =
-+ instance->memory + instance->lane_length * ref_lane + ref_index;
-+ curr_block = instance->memory + curr_offset;
-+ if (ARGON2_VERSION_10 == instance->version) {
-+ /* version 1.2.1 and earlier: overwrite, not XOR */
-+ fill_block(instance->memory + prev_offset, ref_block, curr_block, 0);
-+ } else {
-+ if(0 == position.pass) {
-+ fill_block(instance->memory + prev_offset, ref_block,
-+ curr_block, 0);
-+ } else {
-+ fill_block(instance->memory + prev_offset, ref_block,
-+ curr_block, 1);
-+ }
-+ }
-+ }
-+}
---
-2.39.2
-