Skip to content

Conversation

@buggywhip
Copy link
Contributor

Add XSalsa20 to the suite of stream ciphers.

Checklist

  • documentation is added or updated
  • tests are added or updated

@buggywhip buggywhip changed the title initial load Add XSalsa20 May 4, 2018
@buggywhip buggywhip requested review from karel-m and sjaeckel May 4, 2018 07:59
@karel-m
Copy link
Member

karel-m commented May 4, 2018

Hi Larry,

some cosmetics - this:

/* ref:         HEAD -> develop */
/* git commit:  af67321bf3cde1a470c679e459ebb8189e38c9bd */
/* commit time: 2018-04-13 09:42:47 +0200 *

should be replaced with:

/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */

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 am not sure whether to introduce xsalsa20_state; I think using salsa20_state with xsalsa20_* functions is ok.

The last doubt I have (for now) is related to unsigned char *subkey - is it necessary?

@buggywhip
Copy link
Contributor Author

buggywhip commented May 4, 2018 via email

@karel-m
Copy link
Member

karel-m commented May 4, 2018

Ad crypt_sizes.c maybe

#ifdef LTC_SALSA20
    _SZ_STRINGIFY_T(salsa20_state),
#endif
#ifdef LTC_XSALSA20
    _SZ_STRINGIFY_T(xsalsa20_state),
#endif

Copy link
Member

@sjaeckel sjaeckel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 👍


/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */ No newline at end of file
Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

int xsalsa20_test(void);

#define xsalsa20_state salsa20_state
#define xsalsa20_ivctr64 salsa20_ivctr64
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed


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);
Copy link
Member

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? :)

Copy link
Contributor Author

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;
Copy link
Member

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, ...
...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implemented

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));
Copy link
Member

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, ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implemented

*/
{
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};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

*/
{
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};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

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};
Copy link
Member

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

Copy link
Contributor Author

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,
Copy link
Member

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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my comment below

#include "tomcrypt.h"

#ifdef LTC_SALSA20
#if defined(LTC_SALSA20) || defined(LTC_XSALSA20)
Copy link
Member

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

salsa20_state > xsalsa20_state

Copy link
Member

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...

@karel-m
Copy link
Member

karel-m commented May 6, 2018

I still do not see a use case for subkey. How can one reuse the value?

I am for: xsalsa20_setup(&st, key, key_len, nonce, nonce_len, rounds)

If there is a demand for subkey we can introduce xsalsa20_setup_ex(&st, key, key_len, nonce, nonce_len, rounds, &subkey, &subkeylen)

LTC_ARGCHK(keylen == 32);
LTC_ARGCHK(nonce != NULL);
LTC_ARGCHK(noncelen == 24);
LTC_ARGCHK((subkey != NULL && subkeylen != NULL) ||
Copy link
Member

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,
Copy link
Member

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my comment below

#include "tomcrypt.h"

#ifdef LTC_SALSA20
#if defined(LTC_SALSA20) || defined(LTC_XSALSA20)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@sjaeckel
Copy link
Member

sjaeckel commented May 6, 2018

I still do not see a use case for subkey. How can one reuse the value?

very good point!

I am for: xsalsa20_setup(&st, key, key_len, nonce, nonce_len, rounds)

👍

@buggywhip
Copy link
Contributor Author

buggywhip commented May 6, 2018 via email

Copy link
Member

@sjaeckel sjaeckel left a 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.
Copy link
Member

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.

#include "tomcrypt.h"

#ifdef LTC_SALSA20
#if defined(LTC_SALSA20) || defined(LTC_XSALSA20)
Copy link
Member

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);
Copy link
Member

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

@karel-m
Copy link
Member

karel-m commented May 28, 2018

Providing the check with #error LTC_XSALSA20 requires LTC_SALSA20 in tomcrypt_custom.h I think we do not need any of these:

-#ifdef LTC_SALSA20
+#if defined(LTC_SALSA20) || defined(LTC_XSALSA20)

LTC_ARGCHK(iv != NULL);
/* Salsa20: 64-bit IV (nonce) + 64-bit counter */
LTC_ARGCHK(ivlen == 8);
LTC_ARGCHK(ivlen != 24);
Copy link
Member

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?

Copy link
Contributor Author

@buggywhip buggywhip May 28, 2018

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.

#endif /* LTC_CHACHA */

#ifdef LTC_SALSA20
#if defined(LTC_SALSA20) || defined(LTC_XSALSA20)
Copy link
Member

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)
Copy link
Member

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)
Copy link
Member

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)
Copy link
Member

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

@karel-m
Copy link
Member

karel-m commented May 29, 2018

Larry, there is one more #if defined(LTC_SALSA20) || defined(LTC_XSALSA20) in salsa20_ivctr64.c that can be IMO reverted.

Copy link
Member

@karel-m karel-m left a 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)

@buggywhip
Copy link
Contributor Author

buggywhip commented May 29, 2018 via email

sjaeckel
sjaeckel previously approved these changes May 29, 2018
Copy link
Member

@sjaeckel sjaeckel left a 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 sjaeckel dismissed their stale review May 31, 2018 08:09

Re-review by request

Copy link
Member

@sjaeckel sjaeckel left a 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
Copy link
Member

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}.
Copy link
Member

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);
Copy link
Member

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

@buggywhip buggywhip merged commit 82ac9a2 into develop May 31, 2018
@buggywhip buggywhip deleted the add_xsalsa20 branch May 31, 2018 23:42
@fperrad fperrad mentioned this pull request Jun 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants