-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
add and use constant time 32 byte equality function #3999
Conversation
src/device/device_ledger.cpp
Outdated
@@ -127,7 +127,7 @@ namespace hw { | |||
} | |||
|
|||
bool operator==(const crypto::key_derivation &d0, const crypto::key_derivation &d1) { | |||
return !memcmp(&d0, &d1, sizeof(d0)); | |||
return !crypto_verify_32(&d0, &d1, sizeof(d0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@moneromooo-monero I can't find an overload of crypto_verify_32
that takes three parameters. Am I missing/misunderstanding something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably that this file isn't a dep of unit tests nor performance tests so didn't get rebuilt. Fixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, no, its because this is only built if some lib dep is installed.
src/device/device_ledger.cpp
Outdated
@@ -127,7 +127,8 @@ namespace hw { | |||
} | |||
|
|||
bool operator==(const crypto::key_derivation &d0, const crypto::key_derivation &d1) { | |||
return !memcmp(&d0, &d1, sizeof(d0)); | |||
static_assert(sizeof(crypto::key_derivation) == 32, "key_derivation must be 32 bytes"); | |||
return !crypto_verify_32(&d0, &d1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From buildbot:
/home/vagrant/slave/monero-static-ubuntu-amd64/build/src/device/device_ledger.cpp:131:40: error: cannot convert 'const crypto::key_derivation*' to 'const unsigned char*' for argument '1' to 'int crypto_verify_32(const unsigned char*, const unsigned char*)'
return !crypto_verify_32(&d0, &d1);
src/crypto/generic-ops.h
Outdated
@@ -34,13 +34,18 @@ | |||
#include <cstring> | |||
#include <functional> | |||
|
|||
extern "C" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes more sense to do this in the verify.h
file since this is a primarily a C++ project. #iifdef __cplusplus
is the usual way of detecting this at the top and bottom of the file.
6bc05ee
to
e95cfcf
Compare
|
Hmm, looks like the function name
https://build.getmonero.org/builders/monero-static-win64/builds/4832/steps/compile/logs/stdio and OSX:
https://build.getmonero.org/builders/monero-static-osx-10.13/builds/789/steps/compile/logs/stdio Would it make sense to use libsodium's version? |
Weird, I didn't know we were using that... |
Hmm, OSX build is getting this error:
Not sure how to fix it. Win64 build is failing now due to the trivial |
By installing libsodium-devel I think. It's probably not finding headers, which it did not need when it was used via libzmq only. |
src/crypto/generic-ops.h
Outdated
return crypto_verify_32((const unsigned char*)&_v1, (const unsigned char*)&_v2) == 0; \ | ||
if (sizeof(_v1) == 8) \ | ||
return (const uint64_t&)_v1 == (const uint64_t&)_v2; \ | ||
return !memcmp(&_v1, &_v2, sizeof(_v1)); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still not constant time for the case of size other than 32 or 8 bytes, right?
While this may not matter for current usage it is leaving a booby trap for some future usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is correct about 32/8 vs others. The operator doesn't make any claim to be constant time in the first place, so I don't see any booby trap here. If you want constant time, you wouldn't use an operator which does not claim to do so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the purpose of this commit except to implement the operation in constant time (otherwise the original and simpler memcmp would have been just fine). You seem to be suggesting either that the operator now implements (presumably because this is relied upon by its use cases) constant time but this is not 'claimed' or that the operator claims to be constant time but only for 8 and 32 bytes but not other sizes?
Either of these seems quite odd and brittle to me, although I guess the latter would be okay if clearly documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The operator== defined by that macro does not claim to do constant time. It just happens to do so for 32 bytes because we want it for secret keys and secret keys are 32 bytes. The 8 byte case is just drive by really, and on second thoughts maybe the memcmp is better since we might get unaligned 8 bytes if they're not uint64_t.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a bit more complex, but duplicates the macros so there's one specifically for constant time. Still building here so might need updating is tests break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just happens to do so for 32 bytes because we want it for secret keys and secret keys are 32 bytes
This is exactly what I am saying about relying on brittle behavior.
If we want constant time for private keys then there should a specific defined mechanism for getting that.
2440b5c
to
9786c9d
Compare
OSX builds are failing due to libsodium missing, apparently. @Pigeons Could you install it? Edit: I’ve misquoted someone else, sorry:p |
I've installed libsodium on the OSX machines and kicked off the rebuilds. |
9786c9d
to
d2e26c2
Compare
d2e26c2 add and use constant time 32 byte equality function (moneromooo-monero)
Oddly, it looks like while it's way slower than memcmp, the timings for both different and equal are pretty similar for both.