-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feature request] Deterministic mode #3
Comments
Hey @mrdomino, I appreciate your feedback! I can give you some pointers for this, if you want to take a crack at it. Currently, the source of randomness is already abstracted away. We have that /// Randomness source.
typedef struct {
/// Ring buffer to hold random data in.
uint8_t buffer[PASSGEN_RANDOM_BUFFER_LENGTH];
/// Current position in the ring buffer.
size_t pos;
/// Device to read random data from.
void *data;
/// Function used to read more random data.
passgen_random_read_func *read;
/// Function used to close randomness source.
passgen_random_close_func *close;
} passgen_random; The closest thing to this at the moment would be to use the (very insecure) xorshift PRNG, which you can give a seed for deterministic password output:
This means that if you use the same seed, you always get the same password back (at least, unless there are major changes in passgen). However, I mainly implemented this PRNG for deterministic unit tests, it should not really be used to generate strong passwords. What you could do is implement your own source of randomness, which takes as input the You would do this in You'd probably also want to think about how to activate this. Currently, there is a command-line argument
However, this might be somewhat awkward to use. It should also be possible to make this more of a first-class feature and add custom command-line arguments for it, so that you can enable it as such:
To be honest, I think this would be a neat feature and I think it would make sense to have first-class support for it. |
Great! Exciting that you're interested. I would probably not want to support giving the master password on the command line, since that makes it too easy for it to get into a shell history file. Not having given too much thought to it yet, something like The point of |
Makes sense! One thing that might also make sense is storing the (bcrypt/argon2d)-hashed version of the master passphrase in some config file. When you use passgen, it'll prompt you for it:
All that does it verify that you spelled the master passphrase correctly, to make sure you don't accidentally have a typo in it (and thereby generate a password you cannot recover). Besides that, I think the next steps to get this rolling are:
|
The one wrinkle with that is the salt parameter. You would be committing to always being able to retrieve that, on pain of losing all of your passwords. But that might actually be fine in a lot of cases since you're presumably already storing your list of per-site schemas somewhere. Yeah I agree re next steps. My inclination is to try to vendor everything as much as possible, but I'll see what makes sense. I will get on that. |
Oh wait, no, I see what you're saying. Store the hash with salt, but take it on the command line to fill the sponge with. Yep, great idea. I like it. :) |
How would you feel about passgen incurring a dependency on openssl? It seems like openssl has both Keccak and Argon2 these days, so it would be fairly expedient from that perspective relative to trying to depend on separate Keccak and Argon2 libraries. But it's openssl... (openssl is also already packaged for cosmopolitan libc, which is congruent with an ulterior motive that I have to see a cosmopolitan build of passgen.) |
I would also like to see a cosmopolitan build of passgen! I think that is a
great idea.
As for openssl, my current aim is to try to not have any dependencies, for
portability. I like having statically-linked binaries. But this is not a
hard requirement, I’m happy to depend on it if it gives a benefit. Perhaps
that should be an optional feature, so that it is still possible to build
static binaries.
One thing I have done in the past is vendor crypto things from
PolarSSL/mbedTLS. Their implementations are fairly easy to pull out, are
permissively licensed. You don’t get the most performance, but you get good
portability. If we only need a few algorithms (keccak, argon2) then that
might be an idea. It does create a bit of maintenance (having to update
it). Passgen is not vulnerable to any timing side-channel attacks, so we
don’t have to be too worried, only that the implementation is correct and
reproducible.
If you want to play with it, I’m happy to accept patches either way. I
think new features that are useful are always welcome 😊
…On Fri 17. May 2024 at 02:38, Jōshin ***@***.***> wrote:
How would you feel about passgen incurring a dependency on openssl? It
seems like openssl has both Keccak and Argon2 these days, so it would be
fairly expedient from that perspective relative to trying to depend on
separate Keccak and Argon2 libraries. But it's openssl...
(openssl is also already packaged for cosmopolitan libc, which is
congruent with an ulterior motive that I have to see a cosmopolitan build
of passgen.)
—
Reply to this email directly, view it on GitHub
<#3 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAF775AO5MUU7HBH6J36QADZCVGOXAVCNFSM6AAAAABHSLWAJ6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJWGQZDQOBYGI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Yeah, looks like mbedTLS has Keccak in it, though I can't tell yet how accessible the raw sponge is. (The extendable-output functions SHAKE128 and SHAKE256 are apparently still sitting in an open PR.) I would be fine with doing it that way, cosmopolitan libc actually seems to vendor an older version of mbedtls already fwiw. |
All right, I have a hokey minimal toy example that implements all of the relevant cryptographic primitives and nothing else: https://github.com/mrdomino/cosmopolitan/blob/pw/examples/pw.c Notably that's all just out of base cosmopolitan libc, with no external dependencies. Apparently BLAKE2 is a better alternative to Keccak; BLAKE2X is an XOF constructed out of it, that is similar but not identical to what that file does. (That file uses an argon2 hash instead of a BLAKE2 hash as H₀, and uses 32- rather than 64-byte digests because BLAKE2B256 is what cosmo provides.) |
I've started playing around a little bit. My idea was basically use this as a source of randomness (it is a stream cipher):
I'm not sure what you think of this, my thinking was basically that I like XChaCha20 as a stream cipher, and it was easy to make a randomness source out of it :D So far, I've implemented Salsa20 (the predecessor of XChaCha20) as a randomness source for Passgen. I used DJB's public-domain implementation for it. I've also found an implementation of Argon2id that is similarly licensed. I am not too worried about performance or side-channel attacks, so it does not need the most optimized implementation, I think. Next steps would be:
Do you think this scheme is reasonable? I thought it was more "simple" than (ab)using keccak as a stream cipher (if I understoof that correctly). |
Yep, totally. Any good stream cipher with a known key ought to do as a source of pseudorandom bits.
Why argon2id rather than just argon2d? It doesn't seem that there's any need to concern ourselves with side channel attacks in this case, as you say. I'm not all that smart about what to stick where as far as IVs and salts and all go; my thinking was to just use everything relevant to the site as the "password" input to argon2d, maybe even including the schema. I guess the main question is just what needs to be covered by the work factor in order to resist brute-force attacks, and whether the password with a salt of zero is good enough. I think it is - if you're going to use a password that could show up in a rainbow table with this scheme, then you're already doing it very wrong. But if we want to try to save those people from themselves, then including the URL, reset counter, and schema alongside the master password as a pseudo-salt is a marginal step up from salt of zero.
I agree. Fwiw the cosmopolitan implementations of argon2 and blake2 are basically optimized versions of the references, and are licensed permissively; you would just want to include the copyright notice in any distributions somehow. (With cosmopolitan this is already handled for you - like it sticks the copyright notices into the output binary for you, which few other libraries do.)
Yeah it seems good to me. The blake2 XOF is basically just CTR mode for a block cipher, and CTR mode is basically just a way to turn a block cipher into a stream cipher at the end of the day. I agree re next steps. |
Ok well, I just started a new job - while you might think that would impinge on my ability to do this patch, what it actually means is that I now have a use case (generating my corp password) for this, so I will probably be putting some more effort into it. |
Just today I made some progress on this. I might be able to make an MR
later today. I found a very lightweight crypto library that is permissively
licensed, it gives us blake2, argon2 and xchacha20. Should be relatively
straightforward to implement this mode with these primitives. I will keep
you updated.
Cheers,
Patrick
|
Awesome! Eager to see it. |
I just pushed some stuff, I've added the Monocypher library and using that, I implemented the You can also use it. I don't yet have it nicely exported, but this works:
It works, but I'm not fully confident in the code yet, I think I need to write some more tests to make sure that everything is sane. There are some obvious stack overflows in there. But I think it achieves what we want, and it was not even that much code to write. There are three parameters that
Both domain and token are optional (actually, all three are optional, but if you don't supply a master passphrase, it is a bit useless). That means you can use the token as a counter, or you can use it to disambiguate between multiple logins. For example:
Try it and see if this makes sense! If you think this implementation is good enough, the next step would be to implement some command-line switches to make it more usable. |
This is a really cool project. I really like the regex-like language for specifying password schemas.
The main use case I have for a tool like this is as a deterministic password generator (like lesspass or passacre, or see also ssh-keydgen.) Basically I want to be able to use a master password to generate all of my site-specific passwords, so I only need to remember the one master password and don't need to save anything except the schemas, which can be public.
The general idea is to use (the moral equivalent of)
bcrypt(master-password + site-url + reset-counter)
as an entropy seed, feed that into (the moral equivalent of) a Keccak sponge, and take bits out of that instead of using/dev/urandom
or what-have-you.site-url
can optionally contain a username, andreset-counter
gets incremented every time you need to change a password for one site.If this is of interest / not undesirable, then I might be able to take a crack at implementing it.
The text was updated successfully, but these errors were encountered: