-
Notifications
You must be signed in to change notification settings - Fork 484
Add XSalsa20 #387
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 XSalsa20 #387
Conversation
|
Hi Larry, some cosmetics - this: should be replaced with: The I am not sure whether to introduce The last doubt I have (for now) is related to |
|
should be replaced with:
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
will do
The xsalsa20_ivctr64 looks to me like a candidate for misuse (with potential security consequences). I'd leave it out till somebody comes with a reasonable use case.
I too struggled with the security implications. It was that or try to keep parallel APIs. I won't feel bad if we yank it.
I am not sure whether to introduce xsalsa20_state; I think using salsa20_state with xsalsa20_*functions is ok.
And you can because xsalsa20_state is defined to salsa20_state in the same way we map xsalsa20_crypt(), _keystream(), and _done() to their salsa20 counterparts. I suggest, however, keeping xsalsa20_state to reduce confusion.
The last doubt I have (for now) is related to unsigned char *subkey - is it necessary?
Not really so long as the user doesn't want a hybrid xsalsa/salsa where the subkey is used more like an ephemeral key. sha256(key+nonce) can accomplish that but the doubleround function is lightweight and more attractive for smaller devices. I can argue this both ways; it comes down to what is our objective?
I will wait a few days. Others might want to chime in.
I have one additional concern. The "#define xsalsa20_state salsa20_state" appears to kill getting xsalsa20_state_size fm misc/crypt/crypt_sizes.c. I still want to play with it some more but python users might just have to remember to use salsa20_state. ...but all the xsalsa mappings work just fine elsewhere. Confusing?
|
|
Ad #ifdef LTC_SALSA20
_SZ_STRINGIFY_T(salsa20_state),
#endif
#ifdef LTC_XSALSA20
_SZ_STRINGIFY_T(xsalsa20_state),
#endif |
sjaeckel
left a comment
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.
Looks good 👍
src/stream/xsalsa20/xsalsa20_setup.c
Outdated
|
|
||
| /* ref: $Format:%D$ */ | ||
| /* git commit: $Format:%H$ */ | ||
| /* commit time: $Format:%ai$ */ No newline at end of file |
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.
can you please add a newline on all newly added files
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.
done
src/headers/tomcrypt_cipher.h
Outdated
| int xsalsa20_test(void); | ||
|
|
||
| #define xsalsa20_state salsa20_state | ||
| #define xsalsa20_ivctr64 salsa20_ivctr64 |
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.
Do we really have to provide this?
IIUC you could use it, but it's dangerous and therefor: will it even be used?
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.
removed
src/headers/tomcrypt_cipher.h
Outdated
|
|
||
| int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, | ||
| const unsigned char *nonce, unsigned long noncelen, | ||
| int rounds, unsigned char *subkey); |
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.
shouldn't there be a unsigned long *subkeylen? :)
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.
added
|
|
||
| /* copy out subkey if not NULL */ | ||
| if (subkey != NULL) XMEMCPY(subkey, secondkey, sizeof(secondkey)); | ||
| return CRYPT_OK; |
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 missing a
#ifdef LTC_CLEAN_STACK
zeromem(secondkey, ...
zeromem(x, ...
...
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.
implemented
src/stream/xsalsa20/xsalsa20_setup.c
Outdated
| st->ivlen = 8; /* set switch to say nonce/IV has been loaded */ | ||
|
|
||
| /* copy out subkey if not NULL */ | ||
| if (subkey != NULL) XMEMCPY(subkey, secondkey, sizeof(secondkey)); |
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.
Instead of copying why not work with the provided buffer if given?
unsigned char secondkey_buf[32], *secondkey = secondkey_buf;
...
if (subkey != NULL) secondkey = subkey;
...
#ifdef LTC_CLEAN_STACK
zeromem(secondkey_buf, ...
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.
implemented
src/stream/xsalsa20/xsalsa20_test.c
Outdated
| */ | ||
| { | ||
| unsigned char key[] = {0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89}; | ||
| unsigned char nonce[] = {0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37}; |
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.
const
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.
done
src/stream/xsalsa20/xsalsa20_test.c
Outdated
| ref: stream3.c/out in nacl-20110221/tests | ||
| */ | ||
| { | ||
| unsigned char key[] = {0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89}; |
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.
const
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.
done
src/stream/xsalsa20/xsalsa20_test.c
Outdated
| */ | ||
| { | ||
| unsigned char key[] = {0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89}; | ||
| unsigned char nonce[] = {0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37}; |
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.
const
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.
done
src/stream/xsalsa20/xsalsa20_test.c
Outdated
| unsigned char key[] = {0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89}; | ||
| unsigned char nonce[] = {0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37}; | ||
| unsigned char subkey[32] = {0}; | ||
| unsigned char expect[] = {0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4}; |
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.
const
src/stream/xsalsa20/xsalsa20_test.c
Outdated
| verify correct generation of a keystream | ||
| */ | ||
| { | ||
| unsigned char key[] = {0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89}; |
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.
const ... and all the others :D
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.
done
|
|
||
| #ifdef LTC_XSALSA20 | ||
|
|
||
| int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, |
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.
shouldn't we use xsalsa20_state here?
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.
see my comment below
src/stream/salsa20/salsa20_ivctr64.c
Outdated
| #include "tomcrypt.h" | ||
|
|
||
| #ifdef LTC_SALSA20 | ||
| #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
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 can be IMO reverted to #ifdef LTC_SALSA20
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.
👍
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'd also prefer to add something like the following in the "cleanup" section of tomcrypt_custom.h where all the other similar cases are handled
#if defined(LTC_XSALSA20) && !defined(LTC_SALSA20)
#error LTC_XSALSA20 requires LTC_SALSA20
#endif
then all the changes to src/stream/salsa20/salsa20_*.c could be reverted
| @param subkeylen [out] number of bytes copied, NULL if not want a copy | ||
| @return CRYPT_OK if successful | ||
| */ | ||
| int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, |
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.
salsa20_state > xsalsa20_state
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.
not sure though if we should remove the xsalsa20_state define and go with only salsa20_state* arguments... it'd be cleaner I guess...
|
I still do not see a use case for I am for: If there is a demand for |
src/stream/xsalsa20/xsalsa20_setup.c
Outdated
| LTC_ARGCHK(keylen == 32); | ||
| LTC_ARGCHK(nonce != NULL); | ||
| LTC_ARGCHK(noncelen == 24); | ||
| LTC_ARGCHK((subkey != NULL && subkeylen != NULL) || |
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.
LTC_ARGCHK(((subkey == NULL) && (subkeylen == NULL)) ||
((subkey != NULL) && (subkeylen != NULL) && (*subkeylen >= 32)));
| @param subkeylen [out] number of bytes copied, NULL if not want a copy | ||
| @return CRYPT_OK if successful | ||
| */ | ||
| int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, |
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.
not sure though if we should remove the xsalsa20_state define and go with only salsa20_state* arguments... it'd be cleaner I guess...
|
|
||
| #ifdef LTC_XSALSA20 | ||
|
|
||
| int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, |
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.
see my comment below
src/stream/salsa20/salsa20_ivctr64.c
Outdated
| #include "tomcrypt.h" | ||
|
|
||
| #ifdef LTC_SALSA20 | ||
| #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
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.
👍
very good point!
👍 |
|
On 6May, 2018, at 12:56 PM, Steffen Jaeckel ***@***.***> wrote:
I still do not see a use case for subkey. How can one reuse the value?
very good point!
I can see using the "hashed" subkey in various situations, none of which couldn't be satisfied with another hash function. The only redeeming value might be the doubleround's space and time.
I doubt we would ever see a request for two reasons: XSalsa's low adoption and library "shoppers" will simply move on. (My usage was predominately prototyping; I'd carve out the pieces I needed and augment with custom code.)
An alternative would be to implement Karel's xsalsa20_setup_ex(&st, key, key_len, nonce, nonce_len, rounds, &subkey, &subkeylen) now. ...but as a "shopper" I'd be much more interested in XChaCha20 with all the bells and whistles.
I am for: xsalsa20_setup(&st, key, key_len, nonce, nonce_len, rounds)
👍
All that said... Clearly this will be the most frequent use case and is *much* cleaner.
Done. (offline I'll keep the existing code should we change our mind)
|
sjaeckel
left a comment
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.
Should be ready after my last comments were worked in! 👍
doc/crypt.tex
Outdated
|
|
||
| xsalsa20_setup() is the only call needed to completely initialize the state. | ||
| The key size must be 32 bytes (256 bits) and nonce size must be 24 bytes (192 | ||
| bits). Rounds must be an even number and if set to 0 it will be changed to 20. |
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.
and if set to 0 it will be changed to 20.
and if set to 0 the default number of rounds, 20, will be used.
src/stream/salsa20/salsa20_ivctr64.c
Outdated
| #include "tomcrypt.h" | ||
|
|
||
| #ifdef LTC_SALSA20 | ||
| #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
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'd also prefer to add something like the following in the "cleanup" section of tomcrypt_custom.h where all the other similar cases are handled
#if defined(LTC_XSALSA20) && !defined(LTC_SALSA20)
#error LTC_XSALSA20 requires LTC_SALSA20
#endif
then all the changes to src/stream/salsa20/salsa20_*.c could be reverted
| int salsa20_keystream(salsa20_state *st, unsigned char *out, unsigned long outlen) | ||
| { | ||
| if (outlen == 0) return CRYPT_OK; /* nothing to do */ | ||
| LTC_ARGCHK(st->ivlen == 8 || st->ivlen == 24); |
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.
there is IMO no need for this check here
|
Providing the check with -#ifdef LTC_SALSA20
+#if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
src/stream/salsa20/salsa20_ivctr64.c
Outdated
| LTC_ARGCHK(iv != NULL); | ||
| /* Salsa20: 64-bit IV (nonce) + 64-bit counter */ | ||
| LTC_ARGCHK(ivlen == 8); | ||
| LTC_ARGCHK(ivlen != 24); |
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.
Are you sure here? What's the idea behind this change?
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 want to prevent invoking salsa20_ivctr64() after calling xsalsa20_setup(). ...unnecessary.
src/headers/tomcrypt_cipher.h
Outdated
| #endif /* LTC_CHACHA */ | ||
|
|
||
| #ifdef LTC_SALSA20 | ||
| #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
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 can IMO stay as it used to be: #ifdef LTC_SALSA20
src/stream/salsa20/salsa20_crypt.c
Outdated
| #include "tomcrypt.h" | ||
|
|
||
| #ifdef LTC_SALSA20 | ||
| #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
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 can IMO stay as it used to be: #ifdef LTC_SALSA20
src/stream/salsa20/salsa20_done.c
Outdated
| #include "tomcrypt.h" | ||
|
|
||
| #ifdef LTC_SALSA20 | ||
| #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
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 can IMO stay as it used to be: #ifdef LTC_SALSA20
| #include "tomcrypt.h" | ||
|
|
||
| #ifdef LTC_SALSA20 | ||
| #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) |
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 can IMO stay as it used to be: #ifdef LTC_SALSA20
|
Larry, there is one more |
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.
Looks good to me. Just please squash it into 2 commits: 1/ update makefiles + 2/ xsalsa20 (and of course rebase on current develop)
|
On 28May, 2018, at 11:49 PM, karel-m ***@***.***> wrote:
@karel-m approved this pull request.
Looks good to me. Just please squash it into 2 commits: 1/ update makefiles + 2/ xsalsa20
Thanks, will do after one more doc update to add one sentence:
"If you define \textit{LTC_XSalsa20} to include \textit{XSalsa20} in a minimal
\textit{libtomcrypt} library build, you must also define \textit{LTC_Salsa20}."
I'll push it tomorrow.
|
sjaeckel
left a comment
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.
👍 LGTM
Please merge after Karel's comments are taken into account (and you finished the docs :) )
sjaeckel
left a comment
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.
Perfect after these minor changes
doc/crypt.tex
Outdated
| and if set to 0 the default number of rounds, 20, will be used. | ||
| \vspace{1mm} | ||
|
|
||
| If you define \textit{LTC_XSalsa20} to include \textit{XSalsa20} in a minimal |
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.
LTC_XSALSA20
doc/crypt.tex
Outdated
| \vspace{1mm} | ||
|
|
||
| If you define \textit{LTC_XSalsa20} to include \textit{XSalsa20} in a minimal | ||
| \textit{libtomcrypt} library build, you must also define \textit{LTC_Salsa20}. |
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.
LTC_SALSA20
|
|
||
| int _sha256(unsigned char *hash, const unsigned char *data, const int datalen) { | ||
| hash_state md; | ||
| sha256_init(&md); |
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.
pretty paranoid, but this would fail to build if someone wants to build w/o sha256
I think it'd be better to use the hash_memory() function instead of this _sha256() ... but I just realized then again we'd have a dependency on the LTC_HASH_HELPERS ... btw. how's this handled in all the other tests? :D
Simply put this function and the second test-case in a #ifdef LTC_SHA256 please
Add XSalsa20 to the suite of stream ciphers.
Checklist