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 */