Blame SOURCES/0183-pgp-factor-out-rsa_pad.patch

8e15ce
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
8e15ce
From: Daniel Axtens <dja@axtens.net>
8e15ce
Date: Thu, 1 Oct 2020 20:23:48 +1000
8e15ce
Subject: [PATCH] pgp: factor out rsa_pad
8e15ce
8e15ce
rsa_pad does the PKCS#1 v1.5 padding for the RSA signature scheme.
8e15ce
We want to use it in other RSA signature verification applications.
8e15ce
8e15ce
I considered and rejected putting it in lib/crypto.c. That file doesn't
8e15ce
currently require any MPI functions, but rsa_pad does. That's not so
8e15ce
much of a problem for the grub kernel and modules, but crypto.c also
8e15ce
gets built into all the grub utilities. So - despite the utils not
8e15ce
using any asymmetric ciphers -  we would need to built the entire MPI
8e15ce
infrastructure in to them.
8e15ce
8e15ce
A better and simpler solution is just to spin rsa_pad out into its own
8e15ce
PKCS#1 v1.5 module.
8e15ce
8e15ce
Signed-off-by: Daniel Axtens <dja@axtens.net>
8e15ce
---
8e15ce
 grub-core/Makefile.core.def |  8 ++++++
8e15ce
 grub-core/commands/pgp.c    | 28 ++-------------------
8e15ce
 grub-core/lib/pkcs1_v15.c   | 59 +++++++++++++++++++++++++++++++++++++++++++++
8e15ce
 include/grub/pkcs1_v15.h    | 27 +++++++++++++++++++++
8e15ce
 4 files changed, 96 insertions(+), 26 deletions(-)
8e15ce
 create mode 100644 grub-core/lib/pkcs1_v15.c
8e15ce
 create mode 100644 include/grub/pkcs1_v15.h
8e15ce
8e15ce
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
8e15ce
index 81fc274148e..97347ae76f9 100644
8e15ce
--- a/grub-core/Makefile.core.def
8e15ce
+++ b/grub-core/Makefile.core.def
8e15ce
@@ -2510,6 +2510,14 @@ module = {
8e15ce
   cppflags = '$(CPPFLAGS_GCRY)';
8e15ce
 };
8e15ce
 
8e15ce
+module = {
8e15ce
+  name = pkcs1_v15;
8e15ce
+  common = lib/pkcs1_v15.c;
8e15ce
+
8e15ce
+  cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';
8e15ce
+  cppflags = '$(CPPFLAGS_GCRY)';
8e15ce
+};
8e15ce
+
8e15ce
 module = {
8e15ce
   name = all_video;
8e15ce
   common = lib/fake_module.c;
8e15ce
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
8e15ce
index 5daa1e9d00c..2408db4994f 100644
8e15ce
--- a/grub-core/commands/pgp.c
8e15ce
+++ b/grub-core/commands/pgp.c
8e15ce
@@ -24,6 +24,7 @@
8e15ce
 #include <grub/file.h>
8e15ce
 #include <grub/command.h>
8e15ce
 #include <grub/crypto.h>
8e15ce
+#include <grub/pkcs1_v15.h>
8e15ce
 #include <grub/i18n.h>
8e15ce
 #include <grub/gcrypt/gcrypt.h>
8e15ce
 #include <grub/pubkey.h>
8e15ce
@@ -411,32 +412,7 @@ static int
8e15ce
 rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
8e15ce
 	 const gcry_md_spec_t *hash, struct grub_public_subkey *sk)
8e15ce
 {
8e15ce
-  grub_size_t tlen, emlen, fflen;
8e15ce
-  grub_uint8_t *em, *emptr;
8e15ce
-  unsigned nbits = gcry_mpi_get_nbits (sk->mpis[0]);
8e15ce
-  int ret;
8e15ce
-  tlen = hash->mdlen + hash->asnlen;
8e15ce
-  emlen = (nbits + 7) / 8;
8e15ce
-  if (emlen < tlen + 11)
8e15ce
-    return 1;
8e15ce
-
8e15ce
-  em = grub_malloc (emlen);
8e15ce
-  if (!em)
8e15ce
-    return 1;
8e15ce
-
8e15ce
-  em[0] = 0x00;
8e15ce
-  em[1] = 0x01;
8e15ce
-  fflen = emlen - tlen - 3;
8e15ce
-  for (emptr = em + 2; emptr < em + 2 + fflen; emptr++)
8e15ce
-    *emptr = 0xff;
8e15ce
-  *emptr++ = 0x00;
8e15ce
-  grub_memcpy (emptr, hash->asnoid, hash->asnlen);
8e15ce
-  emptr += hash->asnlen;
8e15ce
-  grub_memcpy (emptr, hval, hash->mdlen);
8e15ce
-
8e15ce
-  ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0);
8e15ce
-  grub_free (em);
8e15ce
-  return ret;
8e15ce
+  return grub_crypto_rsa_pad(hmpi, hval, hash, sk->mpis[0]);
8e15ce
 }
8e15ce
 
8e15ce
 struct grub_pubkey_context
8e15ce
diff --git a/grub-core/lib/pkcs1_v15.c b/grub-core/lib/pkcs1_v15.c
8e15ce
new file mode 100644
8e15ce
index 00000000000..dbacd563d01
8e15ce
--- /dev/null
8e15ce
+++ b/grub-core/lib/pkcs1_v15.c
8e15ce
@@ -0,0 +1,59 @@
8e15ce
+/*
8e15ce
+ *  GRUB  --  GRand Unified Bootloader
8e15ce
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
8e15ce
+ *
8e15ce
+ *  GRUB is free software: you can redistribute it and/or modify
8e15ce
+ *  it under the terms of the GNU General Public License as published by
8e15ce
+ *  the Free Software Foundation, either version 3 of the License, or
8e15ce
+ *  (at your option) any later version.
8e15ce
+ *
8e15ce
+ *  GRUB is distributed in the hope that it will be useful,
8e15ce
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
8e15ce
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8e15ce
+ *  GNU General Public License for more details.
8e15ce
+ *
8e15ce
+ *  You should have received a copy of the GNU General Public License
8e15ce
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
8e15ce
+ */
8e15ce
+
8e15ce
+#include <grub/dl.h>
8e15ce
+#include <grub/gcrypt/gcrypt.h>
8e15ce
+
8e15ce
+GRUB_MOD_LICENSE ("GPLv3+");
8e15ce
+
8e15ce
+/*
8e15ce
+ * Given a hash value 'hval', of hash specification 'hash', perform
8e15ce
+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod'
8e15ce
+ * (see RFC 8017 s 9.2) and place the result in 'hmpi'.
8e15ce
+ */
8e15ce
+gcry_err_code_t
8e15ce
+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval,
8e15ce
+		     const gcry_md_spec_t * hash, gcry_mpi_t mod)
8e15ce
+{
8e15ce
+  grub_size_t tlen, emlen, fflen;
8e15ce
+  grub_uint8_t *em, *emptr;
8e15ce
+  unsigned nbits = gcry_mpi_get_nbits (mod);
8e15ce
+  int ret;
8e15ce
+  tlen = hash->mdlen + hash->asnlen;
8e15ce
+  emlen = (nbits + 7) / 8;
8e15ce
+  if (emlen < tlen + 11)
8e15ce
+    return GPG_ERR_TOO_SHORT;
8e15ce
+
8e15ce
+  em = grub_malloc (emlen);
8e15ce
+  if (!em)
8e15ce
+    return 1;
8e15ce
+
8e15ce
+  em[0] = 0x00;
8e15ce
+  em[1] = 0x01;
8e15ce
+  fflen = emlen - tlen - 3;
8e15ce
+  for (emptr = em + 2; emptr < em + 2 + fflen; emptr++)
8e15ce
+    *emptr = 0xff;
8e15ce
+  *emptr++ = 0x00;
8e15ce
+  grub_memcpy (emptr, hash->asnoid, hash->asnlen);
8e15ce
+  emptr += hash->asnlen;
8e15ce
+  grub_memcpy (emptr, hval, hash->mdlen);
8e15ce
+
8e15ce
+  ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0);
8e15ce
+  grub_free (em);
8e15ce
+  return ret;
8e15ce
+}
8e15ce
diff --git a/include/grub/pkcs1_v15.h b/include/grub/pkcs1_v15.h
8e15ce
new file mode 100644
8e15ce
index 00000000000..5c338c84a15
8e15ce
--- /dev/null
8e15ce
+++ b/include/grub/pkcs1_v15.h
8e15ce
@@ -0,0 +1,27 @@
8e15ce
+/*
8e15ce
+ *  GRUB  --  GRand Unified Bootloader
8e15ce
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
8e15ce
+ *
8e15ce
+ *  GRUB is free software: you can redistribute it and/or modify
8e15ce
+ *  it under the terms of the GNU General Public License as published by
8e15ce
+ *  the Free Software Foundation, either version 3 of the License, or
8e15ce
+ *  (at your option) any later version.
8e15ce
+ *
8e15ce
+ *  GRUB is distributed in the hope that it will be useful,
8e15ce
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
8e15ce
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8e15ce
+ *  GNU General Public License for more details.
8e15ce
+ *
8e15ce
+ *  You should have received a copy of the GNU General Public License
8e15ce
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
8e15ce
+ */
8e15ce
+
8e15ce
+/*
8e15ce
+ * Given a hash value 'hval', of hash specification 'hash', perform
8e15ce
+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod'
8e15ce
+ * (See RFC 8017 s 9.2)
8e15ce
+ */
8e15ce
+gcry_err_code_t
8e15ce
+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval,
8e15ce
+		     const gcry_md_spec_t * hash, gcry_mpi_t mod);
8e15ce
+