All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v13 02/13] Import b64dec from gpg-error
  2025-05-24 20:22 [PATCH v13 00/13] Upgrade to libgcrypt 1.11 Vladimir Serbinenko
@ 2025-05-24 20:22 ` Vladimir Serbinenko
  0 siblings, 0 replies; 2+ messages in thread
From: Vladimir Serbinenko @ 2025-05-24 20:22 UTC (permalink / raw)
  To: grub-devel; +Cc: Vladimir Serbinenko

Imported from libgpg-error 1.51

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
---
 grub-core/lib/b64dec.c | 279 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 279 insertions(+)
 create mode 100644 grub-core/lib/b64dec.c

diff --git a/grub-core/lib/b64dec.c b/grub-core/lib/b64dec.c
new file mode 100644
index 000000000..868d98568
--- /dev/null
+++ b/grub-core/lib/b64dec.c
@@ -0,0 +1,279 @@
+/* b64dec.c - Simple Base64 decoder.
+ * Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2008, 2011, 2016 g10 Code GmbH
+ *
+ * This file is part of Libgpg-error.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This file was originally a part of GnuPG.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gpgrt-int.h"
+
+
+/* The reverse base-64 list used for base-64 decoding. */
+static unsigned char const asctobin[128] =
+  {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
+    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+    0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+    0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+    0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+    0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+    0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
+  };
+
+enum decoder_states
+  {
+    s_init, s_idle, s_lfseen, s_beginseen, s_waitheader, s_waitblank, s_begin,
+    s_b64_0, s_b64_1, s_b64_2, s_b64_3,
+    s_waitendtitle, s_waitend
+  };
+
+
+
+/* Allocate and initialize the context for the base64 decoder.  If
+   TITLE is NULL a plain base64 decoding is done.  If it is the empty
+   string the decoder will skip everything until a "-----BEGIN " line
+   has been seen, decoding ends at a "----END " line.  */
+gpgrt_b64state_t
+_gpgrt_b64dec_start (const char *title)
+{
+  gpgrt_b64state_t state;
+  char *t = NULL;
+
+  if (title)
+    {
+      t = xtrystrdup (title);
+      if (!t)
+        return NULL;
+    }
+
+  state = xtrycalloc (1, sizeof (struct _gpgrt_b64state));
+  if (!state)
+    {
+      xfree (t);
+      return NULL;
+    }
+
+  if (t)
+    {
+      state->title = t;
+      state->idx = s_init;
+    }
+  else
+    state->idx = s_b64_0;
+
+  state->using_decoder = 1;
+
+  return state;
+}
+
+
+/* Do in-place decoding of base-64 data of LENGTH in BUFFER.  Stores the
+   new length of the buffer at R_NBYTES. */
+gpg_err_code_t
+_gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, size_t length,
+                    size_t *r_nbytes)
+{
+  enum decoder_states ds = state->idx;
+  unsigned char val = state->radbuf[0];
+  int pos = state->quad_count;
+  char *d, *s;
+
+  if (state->lasterr)
+    return state->lasterr;
+
+  if (state->stop_seen)
+    {
+      *r_nbytes = 0;
+      state->lasterr = GPG_ERR_EOF;
+      xfree (state->title);
+      state->title = NULL;
+      return state->lasterr;
+    }
+
+  for (s=d=buffer; length && !state->stop_seen; length--, s++)
+    {
+    again:
+      switch (ds)
+        {
+        case s_idle:
+          if (*s == '\n')
+            {
+              ds = s_lfseen;
+              pos = 0;
+            }
+          break;
+        case s_init:
+          ds = s_lfseen;
+          /* Fall through */
+        case s_lfseen:
+          if (*s != "-----BEGIN "[pos])
+            {
+              ds = s_idle;
+              goto again;
+            }
+          else if (pos == 10)
+            {
+              pos = 0;
+              ds = s_beginseen;
+            }
+          else
+            pos++;
+          break;
+        case s_beginseen:
+          if (*s != "PGP "[pos])
+            ds = s_begin; /* Not a PGP armor.  */
+          else if (pos == 3)
+            ds = s_waitheader;
+          else
+            pos++;
+          break;
+        case s_waitheader:
+          if (*s == '\n')
+            ds = s_waitblank;
+          break;
+        case s_waitblank:
+          if (*s == '\n')
+            ds = s_b64_0; /* blank line found.  */
+          else if (*s == ' ' || *s == '\r' || *s == '\t')
+            ; /* Ignore spaces. */
+          else
+            {
+              /* Armor header line.  Note that we don't care that our
+               * FSM accepts a header prefixed with spaces.  */
+              ds = s_waitheader; /* Wait for next header.  */
+            }
+          break;
+        case s_begin:
+          if (*s == '\n')
+            ds = s_b64_0;
+          break;
+        case s_b64_0:
+        case s_b64_1:
+        case s_b64_2:
+        case s_b64_3:
+          {
+            int c;
+
+            if (*s == '-' && state->title)
+              {
+                /* Not a valid Base64 character: assume end
+                   header.  */
+                ds = s_waitend;
+              }
+            else if (*s == '=')
+              {
+                /* Pad character: stop */
+                if (ds == s_b64_1)
+                  *d++ = val;
+                ds = state->title? s_waitendtitle : s_waitend;
+              }
+            else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == '\t')
+              ; /* Skip white spaces. */
+            else if ( (*s & 0x80)
+                      || (c = asctobin[*(unsigned char *)s]) == 255)
+              {
+                /* Skip invalid encodings.  */
+                state->invalid_encoding = 1;
+              }
+            else if (ds == s_b64_0)
+              {
+                val = c << 2;
+                ds = s_b64_1;
+              }
+            else if (ds == s_b64_1)
+              {
+                val |= (c>>4)&3;
+                *d++ = val;
+                val = (c<<4)&0xf0;
+                ds = s_b64_2;
+              }
+            else if (ds == s_b64_2)
+              {
+                val |= (c>>2)&15;
+                *d++ = val;
+                val = (c<<6)&0xc0;
+                ds = s_b64_3;
+              }
+            else
+              {
+                val |= c&0x3f;
+                *d++ = val;
+                ds = s_b64_0;
+              }
+          }
+          break;
+        case s_waitendtitle:
+          if (*s == '-')
+            ds = s_waitend;
+          break;
+        case s_waitend:
+          if ( *s == '\n')
+            state->stop_seen = 1;
+          break;
+        default:
+          gpgrt_assert (!"invalid state");
+        }
+    }
+
+
+  state->idx = ds;
+  state->radbuf[0] = val;
+  state->quad_count = pos;
+  *r_nbytes = (d -(char*) buffer);
+  return 0;
+}
+
+
+/* Return an error code in case an encoding error has been found
+   during decoding. */
+gpg_err_code_t
+_gpgrt_b64dec_finish (gpgrt_b64state_t state)
+{
+  gpg_error_t err;
+
+  if (!state)
+    return 0;  /* Already released.  */
+
+  if (!state->using_decoder)
+    err = GPG_ERR_CONFLICT;  /* State was allocated for the encoder.  */
+  else if (state->lasterr)
+    err = state->lasterr;
+  else
+    {
+      xfree (state->title);
+      err = state->invalid_encoding? GPG_ERR_BAD_DATA : 0;
+    }
+  xfree (state);
+
+  return err;
+}
-- 
2.49.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v13 02/13] Import b64dec from gpg-error
       [not found] <mailman.4447.1748118291.3672.grub-devel@gnu.org>
@ 2025-05-27  9:57 ` Avnish Chouhan
  0 siblings, 0 replies; 2+ messages in thread
From: Avnish Chouhan @ 2025-05-27  9:57 UTC (permalink / raw)
  To: phcoder; +Cc: grub-devel-request, grub-devel

> Message: 2
> Date: Sat, 24 May 2025 20:22:54 +0000
> From: Vladimir Serbinenko <phcoder@gmail.com>
> To: grub-devel@gnu.org
> Cc: Vladimir Serbinenko <phcoder@gmail.com>
> Subject: [PATCH v13 02/13] Import b64dec from gpg-error
> Message-ID: <20250524202424.840406-3-phcoder@gmail.com>
> 
> Imported from libgpg-error 1.51
> 
> Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
> ---
>  grub-core/lib/b64dec.c | 279 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 279 insertions(+)
>  create mode 100644 grub-core/lib/b64dec.c
> 
> diff --git a/grub-core/lib/b64dec.c b/grub-core/lib/b64dec.c
> new file mode 100644
> index 000000000..868d98568
> --- /dev/null
> +++ b/grub-core/lib/b64dec.c
> @@ -0,0 +1,279 @@
> +/* b64dec.c - Simple Base64 decoder.
> + * Copyright (C) 2008, 2011 Free Software Foundation, Inc.
> + * Copyright (C) 2008, 2011, 2016 g10 Code GmbH
> + *
> + * This file is part of Libgpg-error.
> + *
> + * This file is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as
> + * published by the Free Software Foundation; either version 2.1 of
> + * the License, or (at your option) any later version.
> + *
> + * This file is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public 
> License
> + * along with this program; if not, see 
> <https://www.gnu.org/licenses/>.
> + * SPDX-License-Identifier: LGPL-2.1-or-later
> + *
> + * This file was originally a part of GnuPG.
> + */
> +
> +#include <config.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "gpgrt-int.h"
> +
> +
> +/* The reverse base-64 list used for base-64 decoding. */
> +static unsigned char const asctobin[128] =
> +  {
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
> +    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
> +    0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
> +    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
> +    0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
> +    0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
> +    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
> +    0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
> +    0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
> +  };
> +
> +enum decoder_states
> +  {
> +    s_init, s_idle, s_lfseen, s_beginseen, s_waitheader, s_waitblank, 
> s_begin,
> +    s_b64_0, s_b64_1, s_b64_2, s_b64_3,
> +    s_waitendtitle, s_waitend
> +  };
> +
> +
> +
> +/* Allocate and initialize the context for the base64 decoder.  If
> +   TITLE is NULL a plain base64 decoding is done.  If it is the empty
> +   string the decoder will skip everything until a "-----BEGIN " line
> +   has been seen, decoding ends at a "----END " line.  */

Hi Vladimir,

The multiline comments seems little off. Something like this below.

/*
  * ...
  * ...
  */


> +gpgrt_b64state_t
> +_gpgrt_b64dec_start (const char *title)
> +{
> +  gpgrt_b64state_t state;
> +  char *t = NULL;
> +
> +  if (title)
> +    {
> +      t = xtrystrdup (title);
> +      if (!t)
> +        return NULL;
> +    }
> +
> +  state = xtrycalloc (1, sizeof (struct _gpgrt_b64state));
> +  if (!state)
> +    {
> +      xfree (t);
> +      return NULL;
> +    }
> +
> +  if (t)
> +    {
> +      state->title = t;
> +      state->idx = s_init;
> +    }
> +  else
> +    state->idx = s_b64_0;
> +
> +  state->using_decoder = 1;
> +
> +  return state;
> +}
> +
> +
> +/* Do in-place decoding of base-64 data of LENGTH in BUFFER.  Stores 
> the
> +   new length of the buffer at R_NBYTES. */

Same as mentioned above!

> +gpg_err_code_t
> +_gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer, size_t 
> length,
> +                    size_t *r_nbytes)
> +{
> +  enum decoder_states ds = state->idx;
> +  unsigned char val = state->radbuf[0];
> +  int pos = state->quad_count;
> +  char *d, *s;
> +
> +  if (state->lasterr)
> +    return state->lasterr;
> +
> +  if (state->stop_seen)
> +    {
> +      *r_nbytes = 0;
> +      state->lasterr = GPG_ERR_EOF;
> +      xfree (state->title);
> +      state->title = NULL;
> +      return state->lasterr;
> +    }
> +
> +  for (s=d=buffer; length && !state->stop_seen; length--, s++)
> +    {
> +    again:
> +      switch (ds)
> +        {
> +        case s_idle:
> +          if (*s == '\n')
> +            {
> +              ds = s_lfseen;
> +              pos = 0;
> +            }
> +          break;
> +        case s_init:
> +          ds = s_lfseen;
> +          /* Fall through */
> +        case s_lfseen:
> +          if (*s != "-----BEGIN "[pos])
> +            {
> +              ds = s_idle;
> +              goto again;
> +            }
> +          else if (pos == 10)
> +            {
> +              pos = 0;
> +              ds = s_beginseen;
> +            }
> +          else
> +            pos++;
> +          break;
> +        case s_beginseen:
> +          if (*s != "PGP "[pos])
> +            ds = s_begin; /* Not a PGP armor.  */
> +          else if (pos == 3)
> +            ds = s_waitheader;
> +          else
> +            pos++;
> +          break;
> +        case s_waitheader:
> +          if (*s == '\n')
> +            ds = s_waitblank;
> +          break;
> +        case s_waitblank:
> +          if (*s == '\n')
> +            ds = s_b64_0; /* blank line found.  */
> +          else if (*s == ' ' || *s == '\r' || *s == '\t')
> +            ; /* Ignore spaces. */
> +          else
> +            {
> +              /* Armor header line.  Note that we don't care that our
> +               * FSM accepts a header prefixed with spaces.  */

Same as mentioned above!

> +              ds = s_waitheader; /* Wait for next header.  */
> +            }
> +          break;
> +        case s_begin:
> +          if (*s == '\n')
> +            ds = s_b64_0;
> +          break;
> +        case s_b64_0:
> +        case s_b64_1:
> +        case s_b64_2:
> +        case s_b64_3:
> +          {
> +            int c;
> +
> +            if (*s == '-' && state->title)
> +              {
> +                /* Not a valid Base64 character: assume end
> +                   header.  */

Same as mentioned above!

> +                ds = s_waitend;
> +              }
> +            else if (*s == '=')
> +              {
> +                /* Pad character: stop */
> +                if (ds == s_b64_1)
> +                  *d++ = val;
> +                ds = state->title? s_waitendtitle : s_waitend;
> +              }
> +            else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == 
> '\t')
> +              ; /* Skip white spaces. */
> +            else if ( (*s & 0x80)
> +                      || (c = asctobin[*(unsigned char *)s]) == 255)
> +              {
> +                /* Skip invalid encodings.  */
> +                state->invalid_encoding = 1;
> +              }
> +            else if (ds == s_b64_0)
> +              {
> +                val = c << 2;
> +                ds = s_b64_1;
> +              }
> +            else if (ds == s_b64_1)
> +              {
> +                val |= (c>>4)&3;
> +                *d++ = val;
> +                val = (c<<4)&0xf0;
> +                ds = s_b64_2;
> +              }
> +            else if (ds == s_b64_2)
> +              {
> +                val |= (c>>2)&15;
> +                *d++ = val;
> +                val = (c<<6)&0xc0;
> +                ds = s_b64_3;
> +              }
> +            else
> +              {
> +                val |= c&0x3f;
> +                *d++ = val;
> +                ds = s_b64_0;
> +              }
> +          }
> +          break;
> +        case s_waitendtitle:
> +          if (*s == '-')
> +            ds = s_waitend;
> +          break;
> +        case s_waitend:
> +          if ( *s == '\n')
> +            state->stop_seen = 1;
> +          break;
> +        default:
> +          gpgrt_assert (!"invalid state");
> +        }
> +    }
> +
> +
> +  state->idx = ds;
> +  state->radbuf[0] = val;
> +  state->quad_count = pos;
> +  *r_nbytes = (d -(char*) buffer);
> +  return 0;
> +}
> +
> +
> +/* Return an error code in case an encoding error has been found
> +   during decoding. */

Same as mentioned above!

Thank you!

Regards,
Avnish Chouhan

> +gpg_err_code_t
> +_gpgrt_b64dec_finish (gpgrt_b64state_t state)
> +{
> +  gpg_error_t err;
> +
> +  if (!state)
> +    return 0;  /* Already released.  */
> +
> +  if (!state->using_decoder)
> +    err = GPG_ERR_CONFLICT;  /* State was allocated for the encoder.  
> */
> +  else if (state->lasterr)
> +    err = state->lasterr;
> +  else
> +    {
> +      xfree (state->title);
> +      err = state->invalid_encoding? GPG_ERR_BAD_DATA : 0;
> +    }
> +  xfree (state);
> +
> +  return err;
> +}
> --
> 2.49.0
> 
> 
> 
> 
> ------------------------------

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-05-27  9:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.4447.1748118291.3672.grub-devel@gnu.org>
2025-05-27  9:57 ` [PATCH v13 02/13] Import b64dec from gpg-error Avnish Chouhan
2025-05-24 20:22 [PATCH v13 00/13] Upgrade to libgcrypt 1.11 Vladimir Serbinenko
2025-05-24 20:22 ` [PATCH v13 02/13] Import b64dec from gpg-error Vladimir Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.