Grub2 Password complexity and verification with the old password

2021-10-03 Thread bit_cof...@163.com
Hi,
Currently, when changing the GRUB2 password, the old password is not verified 
and the password complexity is not checked. As a result, the GRUB2 password may 
be cracked by brute force. Does the community have any development plans for 
this? Recently I have been trying to develop code to verify the complexity of 
the new password and to verify the old password of user.cfg when changing the 
password. I hope to present it to the community.

thanks



bit_cof...@163.com
___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


A new parameter is added for grub-mkpasswd-pbkdf2 tool to specify a specific salt value.

2021-10-06 Thread bit_cof...@163.com
From 0892b79339cd0ab93642a6e5d1b240bcfcae5471 Mon Sep 17 00:00:00 2001
From: liuxin 
Date: Wed, 6 Oct 2021 20:45:28 +0800
Subject: [PATCH] A new parameter is added for grub-mkpasswd-pbkdf2 tool to 
specify a specific salt value.

 After a specific salt value is specified, the output password
 is the same every time. It is convenient for the operating system of the
 release version to use this function for password verification.

---
 util/grub-mkpasswd-pbkdf2.c | 88 +++--
 1 file changed, 85 insertions(+), 3 deletions(-)

diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c
index 5805f3c10..4ce9d21a4 100644
--- a/util/grub-mkpasswd-pbkdf2.c
+++ b/util/grub-mkpasswd-pbkdf2.c
@@ -33,6 +33,9 @@
 
 #define _GNU_SOURCE 1
 
+#define GRUB_PARAM_SUCCESS 0
+#define GRUB_PARAM_ERROR   1
+
 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
 #pragma GCC diagnostic ignored "-Wmissing-declarations"
 #include 
@@ -46,6 +49,7 @@ static struct argp_option options[] = {
   {"iteration-count",  'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 
0},
   {"buflen",  'l', N_("NUM"), 0, N_("Length of generated hash"), 0},
   {"salt",  's', N_("NUM"), 0, N_("Length of salt"), 0},
+  {"salt arg", 'a', N_("VARCHAR"), 0, N_("preset salt var(hex code)"), 0},
   { 0, 0, 0, 0, 0, 0 }
 };
 
@@ -54,8 +58,48 @@ struct arguments
   unsigned int count;
   unsigned int buflen;
   unsigned int saltlen;
+  char *salt;
 };
 
+static int
+illegal_char(char t)
+{
+  char legalstr[] = "0123456789ABCDEF";
+  for (int i = 0; i < grub_strlen(legalstr); ++i)
+{
+  if (t == legalstr[i])
+ return GRUB_PARAM_SUCCESS;
+}
+  return GRUB_PARAM_ERROR;
+}
+
+static int
+check_salt_verify(const char *arg)
+{
+  grub_size_t len = grub_strlen(arg);
+  if (len <= 0 || len >= GRUB_SIZE_MAX)
+{
+  fprintf (stderr, _("salt length may be empty or too long!\n"));
+  return GRUB_PARAM_ERROR;
+}
+  if (len % 2 !=0)
+{
+  fprintf (stderr, _("the salt value length is an even number!\n"));
+  return GRUB_PARAM_ERROR;
+}
+  for (int i = 0; i < len; ++i)
+{
+  if(illegal_char(arg[i]))
+ {
+  fprintf (stderr,
+_("only hexadecimal numbers consisting of " \
+"digits and uppercase letters are supported\n"));
+  return GRUB_PARAM_ERROR;
+ }
+}
+  return GRUB_PARAM_SUCCESS;
+}
+
 static error_t
 argp_parser (int key, char *arg, struct argp_state *state)
 {
@@ -76,6 +120,12 @@ argp_parser (int key, char *arg, struct argp_state *state)
 case 's':
   arguments->saltlen = strtoul (arg, NULL, 0);
   break;
+case 'a':
+  if (check_salt_verify(arg))
+ return ARGP_ERR_UNKNOWN;
+  arguments->saltlen = grub_strlen(arg) / 2;
+  arguments->salt = arg;
+  break;
 default:
   return ARGP_ERR_UNKNOWN;
 }
@@ -110,13 +160,36 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n)
   *hex = 0;
 }
 
+static void
+hextobyte(const char *hex, grub_uint8_t *bin, grub_size_t n)
+{
+  while(n)
+{
+  grub_uint8_t tmp = 0x00;
+  if (*hex <= '9' && *hex >= '0')
+tmp += (grub_uint8_t)((*hex - '0') << 4 & 0xf0);
+  else
+tmp += (grub_uint8_t)((*hex - 'A' + 10) << 4 & 0xf0);
+  hex++;
+  if (*hex <= '9' && *hex >= '0')
+tmp += (grub_uint8_t)((*hex - '0') & 0x0f);
+  else
+tmp += (grub_uint8_t)((*hex - 'A' + 10) & 0x0f);
+  *bin = tmp;
+  bin++;
+  hex++;
+  n -= 2;
+}
+}
+
 int
 main (int argc, char *argv[])
 {
   struct arguments arguments = {
 .count = 1,
 .buflen = 64,
-.saltlen = 64
+.saltlen = 64,
+.salt = NULL
   };
   char *result, *ptr;
   gcry_err_code_t gcry_err;
@@ -133,6 +206,14 @@ main (int argc, char *argv[])
   exit(1);
 }
 
+  if (arguments.salt !=NULL &&
+  grub_strlen(arguments.salt) != 2 * arguments.saltlen)
+{
+  fprintf (stderr, "%s",
+ _("If the -a parameter is set, don't set the -s parameter again\n"));
+  exit(1);
+}
+
   buf = xmalloc (arguments.buflen);
   salt = xmalloc (arguments.saltlen);
   
@@ -160,8 +241,9 @@ main (int argc, char *argv[])
   grub_util_error ("%s", _("passwords don't match"));
 }
   memset (pass2, 0, sizeof (pass2));
-
-  if (grub_get_random (salt, arguments.saltlen))
+  if (arguments.salt != NULL)
+hextobyte(arguments.salt, salt, arguments.saltlen * 2);
+  else if (grub_get_random (salt, arguments.saltlen))
 {
   memset (pass1, 0, sizeof (pass1));
   free (buf);
-- 
2.30.0




bit_cof...@163.com
___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel