grub-devel
[Top][All Lists]
Advanced

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

Re: hdparm --security-unlock with password prompt


From: Andrei Borzenkov
Subject: Re: hdparm --security-unlock with password prompt
Date: Thu, 21 Apr 2016 21:24:13 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0

21.04.2016 17:56, Philippe Kueck пишет:
> Hi all,
> 
> here's a patch for unlocking the ATA password from grub command line. As
> mentioned in [1] it does not prompt for a password at boot but enables
> the hdparm module to support the security unlock feature.
> In case anyone asks, the patch is GPL.
> 
> Kind regards
> 
> Philippe
> 
> [1] https://www.unixadm.org/needful-things/ataunlock#using-grub2
> 

Unfortunately I do not think we can have optional value, so your example
on this page likely won't work. I.e. how can we distinguish between
missing option value and missing argument? This will need to be two
options - --security-unlock and --security-passphrase (pick your name).

I was under impression that we must supply password to unlock disk.
Could you explain how empty passphrase works?

> 
> 0999-ATA-Security-Unlock.patch
> 
> 
> --- grub-2.02~beta2/grub-core/commands/hdparm.c.ataunlock
> +++ grub-2.02~beta2/grub-core/commands/hdparm.c
> @@ -34,6 +34,7 @@ static const struct grub_arg_option opti
>                             "(1=low, ..., 254=high, 255=off)."),
>                             0, ARG_TYPE_INT},
>    {"power",           'C', 0, N_("Display power mode."), 0, ARG_TYPE_NONE},
> +  {"security-unlock", -1, 0, N_("Unlock ATA security."), 0, ARG_TYPE_STRING},
>    {"security-freeze", 'F', 0, N_("Freeze ATA security settings until 
> reset."),
>                             0, ARG_TYPE_NONE},
>    {"health",          'H', 0, N_("Display SMART health status."), 0, 
> ARG_TYPE_NONE},
> @@ -66,7 +67,7 @@ static int quiet = 0;
>  static grub_err_t
>  grub_hdparm_do_ata_cmd (grub_ata_t ata, grub_uint8_t cmd,
>                       grub_uint8_t features, grub_uint8_t sectors,
> -                     void * buffer, int size)
> +                     void * buffer, int size, int write)
>  {
>    struct grub_disk_ata_pass_through_parms apt;
>    grub_memset (&apt, 0, sizeof (apt));
> @@ -78,6 +79,7 @@ grub_hdparm_do_ata_cmd (grub_ata_t ata,
>  
>    apt.buffer = buffer;
>    apt.size = size;
> +  apt.write = write;
>  
>    if (ata->dev->readwrite (ata, &apt, 0))
>      return grub_errno;
> @@ -136,7 +138,7 @@ grub_hdparm_simple_cmd (const char * msg
>    if (! quiet && msg)
>      grub_printf ("%s", msg);
>  
> -  grub_err_t err = grub_hdparm_do_ata_cmd (ata, cmd, 0, 0, NULL, 0);
> +  grub_err_t err = grub_hdparm_do_ata_cmd (ata, cmd, 0, 0, NULL, 0, 0);
>  
>    if (! quiet && msg)
>      grub_printf ("%s\n", ! err ? "" : ": not supported");
> @@ -157,7 +159,7 @@ grub_hdparm_set_val_cmd (const char * ms
>      }
>  
>    grub_err_t err = grub_hdparm_do_ata_cmd (ata, cmd, features, sectors,
> -                                        NULL, 0);
> +                                        NULL, 0, 0);
>  
>    if (! quiet && msg)
>      grub_printf ("%s\n", ! err ? "" : ": not supported");
> @@ -274,6 +276,11 @@ static int get_int_arg (const struct gru
>    return (state->set ? (int)grub_strtoul (state->arg, 0, 0) : -1);
>  }
>  
> +static char get_string_arg (const struct grub_arg_list *state)
> +{
> +  return (state->set ? state->arg : "");
> +}
> +
>  static grub_err_t
>  grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args)
>  {
> @@ -298,6 +305,7 @@ grub_cmd_hdparm (grub_extcmd_context_t c
>    int i = 0;
>    int apm          = get_int_arg (&state[i++]);
>    int power        = state[i++].set;
> +  char *passphrase = get_string_arg (&state[i++]);
>    int sec_freeze   = state[i++].set;
>    int health       = state[i++].set;
>    int aam          = get_int_arg (&state[i++]);
> @@ -368,6 +376,23 @@ grub_cmd_hdparm (grub_extcmd_context_t c
>       grub_printf ("%s\n", err ? ": not supported" : "");
>      }
>  
> +  if (grub_strcmp(passphrase, "") == 0)

That's rather elaborate way to check for empty string.

> +    {
> +      // security unlock data: 512 bytes
> +      // word 0: 0x00 user password, 0x01 master password
> +      // word 1-16: password (32 bytes)
> +      // word 17-255: reserved
> +      grub_uint16_t sudata[256];
> +      grub_memset (&sudata, 0, sizeof(sudata));
> +      grub_strncpy((char*)sudata+2, passphrase, 32);

But we just checked that passphrase is empty. What do you copy here?

> +      if (grub_hdparm_do_ata_cmd (ata, GRUB_ATA_CMD_SECURITY_UNLOCK,
> +             0, 1, sudata, sizeof(sudata), 1)) {
> +        if (! quiet) grub_printf ("Unlock failed\n");
> +      } else {
> +        if (! quiet) grub_printf ("Unlock succeeded\n");
> +      }
> +    }
> +
>    if (sec_freeze)
>      grub_hdparm_simple_cmd ("Freeze security settings", ata,
>                              GRUB_ATA_CMD_SECURITY_FREEZE_LOCK);
> @@ -377,7 +402,7 @@ grub_cmd_hdparm (grub_extcmd_context_t c
>      {
>        grub_uint16_t buf[GRUB_DISK_SECTOR_SIZE / 2];
>        if (grub_hdparm_do_ata_cmd (ata, GRUB_ATA_CMD_IDENTIFY_DEVICE,
> -          0, 0, buf, sizeof (buf)))
> +          0, 0, buf, sizeof (buf), 0))
>       grub_printf ("Cannot read ATA IDENTIFY data\n");
>        else
>       {
> --- grub-2.02~beta2/include/grub/ata.h.ataunlock
> +++ grub-2.02~beta2/include/grub/ata.h
> @@ -86,6 +86,7 @@ enum grub_ata_commands
>      GRUB_ATA_CMD_READ_SECTORS_DMA    = 0xc8,
>      GRUB_ATA_CMD_READ_SECTORS_DMA_EXT        = 0x25,
>  
> +    GRUB_ATA_CMD_SECURITY_UNLOCK     = 0xf2,
>      GRUB_ATA_CMD_SECURITY_FREEZE_LOCK        = 0xf5,
>      GRUB_ATA_CMD_SET_FEATURES                = 0xef,
>      GRUB_ATA_CMD_SLEEP                       = 0xe6,
> 
> 
> 
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/grub-devel




reply via email to

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