On Mon, Aug 14, 2023 at 05:47:35PM +0000, Lucas wrote:
> Klemens Nanni <k...@openbsd.org> wrote:
> > @@ -1117,13 +1117,6 @@ bio_changepass(char *dev)
> >  
> >     /* Current passphrase. */
> >     bio_kdf_derive(&kdfinfo1, &kdfhint, "Old passphrase: ", 0);
> > -
> > -   /*
> > -    * Unless otherwise specified, keep the previous number of rounds as
> > -    * long as we're using the same KDF.
> > -    */
> > -   if (kdfhint.generic.type == SR_CRYPTOKDFT_BCRYPT_PBKDF && !rflag)
> > -           rflag = kdfhint.rounds;
> >  
> >     /* New passphrase. */
> >     bio_kdf_generate(&kdfinfo2);
> 
> This will potentially downgrade the amount of rounds on password change
> if `-r` is omitted, which is not ideal imo. What about the following to
> keep the previous amount of rounds if its bigger than the automatic
> estimate?

Thanks, I like the idea.

> @@ -968,17 +968,20 @@ bio_kdf_generate(struct sr_crypto_kdfinfo *kdfinfo)
>  }
>  
>  void
> -bio_kdf_generate(struct sr_crypto_kdfinfo *kdfinfo)
> +bio_kdf_generate(struct sr_crypto_kdfinfo *kdfinfo, int hint_rounds)
>  {
>       if (!kdfinfo)
>               errx(1, "invalid KDF info");
>  
> -     if (rflag == -1)
> +     if (rflag == -1) {
>               rflag = bcrypt_pbkdf_autorounds();
> +             if (rflag < hint_rounds)
> +                     rflag = hint_rounds;
> +     }

But this can be contained in bio_changepass() alone without clutter.

> @@ -1119,14 +1122,14 @@ bio_changepass(char *dev)
>       bio_kdf_derive(&kdfinfo1, &kdfhint, "Old passphrase: ", 0);
>  
>       /*
> -      * Unless otherwise specified, keep the previous number of rounds as
> -      * long as we're using the same KDF.
> +      * Broadcast the previous number of rounds as long as we're using the
> +      * same KDF.
>        */
> -     if (kdfhint.generic.type == SR_CRYPTOKDFT_BCRYPT_PBKDF && !rflag)
> -             rflag = kdfhint.rounds;
> +     if (kdfhint.generic.type == SR_CRYPTOKDFT_BCRYPT_PBKDF)
> +             hint_rounds = kdfhint.rounds;
>  
>       /* New passphrase. */
> -     bio_kdf_generate(&kdfinfo2);
> +     bio_kdf_generate(&kdfinfo2, hint_rounds);
>  
>       kdfpair.kdfinfo1 = &kdfinfo1;
>       kdfpair.kdfsize1 = sizeof(kdfinfo1);

New diff makes "-r auto" default use MAX(auto, previous) when changing
passphrases, while "-r N" sticks to N rounds.

Also updated another internal error check wrt. new minimum.

Feedback? OK?


Index: bioctl.8
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.8,v
retrieving revision 1.111
diff -u -p -r1.111 bioctl.8
--- bioctl.8    6 Jul 2023 21:08:50 -0000       1.111
+++ bioctl.8    15 Aug 2023 07:50:08 -0000
@@ -282,11 +282,12 @@ passphrase into a key, in order to creat
 passphrase of an existing encrypted volume.
 A larger number of iterations takes more time, but offers increased resistance
 against passphrase guessing attacks.
-If
+By default, or if
 .Ar rounds
-is specified as "auto", the number of rounds will be automatically determined
-based on system performance.
-Otherwise the minimum is 4 rounds and the default is 16.
+is specified as
+.Cm auto ,
+the number of rounds will automatically be based on system performance.
+The minimum is 16 rounds.
 .It Fl s
 Read the passphrase for the selected crypto volume from
 .Pa /dev/stdin
Index: bioctl.c
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.c,v
retrieving revision 1.151
diff -u -p -r1.151 bioctl.c
--- bioctl.c    18 Oct 2022 07:04:20 -0000      1.151
+++ bioctl.c    15 Aug 2023 08:35:05 -0000
@@ -89,7 +89,7 @@ int                   devh = -1;
 int                    human;
 int                    verbose;
 u_int32_t              cflags = 0;
-int                    rflag = 0;
+int                    rflag = -1;     /* auto */
 char                   *password;
 
 void                   *bio_cookie;
@@ -182,7 +182,7 @@ main(int argc, char *argv[])
                                rflag = -1;
                                break;
                        }
-                       rflag = strtonum(optarg, 4, 1<<30, &errstr);
+                       rflag = strtonum(optarg, 16, 1<<30, &errstr);
                        if (errstr != NULL)
                                errx(1, "number of KDF rounds is %s: %s",
                                    errstr, optarg);
@@ -978,7 +978,7 @@ bio_kdf_generate(struct sr_crypto_kdfinf
 
        kdfinfo->pbkdf.generic.len = sizeof(kdfinfo->pbkdf);
        kdfinfo->pbkdf.generic.type = SR_CRYPTOKDFT_BCRYPT_PBKDF;
-       kdfinfo->pbkdf.rounds = rflag ? rflag : 16;
+       kdfinfo->pbkdf.rounds = rflag;
 
        kdfinfo->flags = SR_CRYPTOKDF_KEY | SR_CRYPTOKDF_HINT;
        kdfinfo->len = sizeof(*kdfinfo);
@@ -1118,12 +1118,14 @@ bio_changepass(char *dev)
        /* Current passphrase. */
        bio_kdf_derive(&kdfinfo1, &kdfhint, "Old passphrase: ", 0);
 
-       /*
-        * Unless otherwise specified, keep the previous number of rounds as
-        * long as we're using the same KDF.
-        */
-       if (kdfhint.generic.type == SR_CRYPTOKDFT_BCRYPT_PBKDF && !rflag)
-               rflag = kdfhint.rounds;
+       if (rflag == -1) {
+               rflag = bcrypt_pbkdf_autorounds();
+
+               /* Use previous number of rounds for the same KDF if higher. */
+               if (kdfhint.generic.type == SR_CRYPTOKDFT_BCRYPT_PBKDF &&
+                   rflag < kdfhint.rounds)
+                       rflag = kdfhint.rounds;
+       }
 
        /* New passphrase. */
        bio_kdf_generate(&kdfinfo2);
@@ -1326,7 +1328,7 @@ derive_key(u_int32_t type, int rounds, u
            type != SR_CRYPTOKDFT_BCRYPT_PBKDF)
                errx(1, "unknown KDF type %d", type);
 
-       if (rounds < (type == SR_CRYPTOKDFT_PKCS5_PBKDF2 ? 1000 : 4))
+       if (rounds < (type == SR_CRYPTOKDFT_PKCS5_PBKDF2 ? 1000 : 16))
                errx(1, "number of KDF rounds is too small: %d", rounds);
 
        /* get passphrase */

Reply via email to