Replaced system SQLite with SQLCipher to support encrypted database
This commit is contained in:
88
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_crypt.c
Normal file
88
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_crypt.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
|
||||
* and salsa20-ref.c version 20051118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SALSA20
|
||||
|
||||
#define QUARTERROUND(a,b,c,d) \
|
||||
x[b] ^= (ROL((x[a] + x[d]), 7)); \
|
||||
x[c] ^= (ROL((x[b] + x[a]), 9)); \
|
||||
x[d] ^= (ROL((x[c] + x[b]), 13)); \
|
||||
x[a] ^= (ROL((x[d] + x[c]), 18));
|
||||
|
||||
static void s_salsa20_block(unsigned char *output, const ulong32 *input, int rounds)
|
||||
{
|
||||
ulong32 x[16];
|
||||
int i;
|
||||
XMEMCPY(x, input, sizeof(x));
|
||||
for (i = rounds; i > 0; i -= 2) {
|
||||
QUARTERROUND( 0, 4, 8,12)
|
||||
QUARTERROUND( 5, 9,13, 1)
|
||||
QUARTERROUND(10,14, 2, 6)
|
||||
QUARTERROUND(15, 3, 7,11)
|
||||
QUARTERROUND( 0, 1, 2, 3)
|
||||
QUARTERROUND( 5, 6, 7, 4)
|
||||
QUARTERROUND(10,11, 8, 9)
|
||||
QUARTERROUND(15,12,13,14)
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
x[i] += input[i];
|
||||
STORE32L(x[i], output + 4 * i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Salsa20
|
||||
@param st The Salsa20 state
|
||||
@param in The plaintext (or ciphertext)
|
||||
@param inlen The length of the input (octets)
|
||||
@param out [out] The ciphertext (or plaintext), length inlen
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int salsa20_crypt(salsa20_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
unsigned long i, j;
|
||||
|
||||
if (inlen == 0) return CRYPT_OK; /* nothing to do */
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(st->ivlen == 8 || st->ivlen == 24);
|
||||
|
||||
if (st->ksleft > 0) {
|
||||
j = MIN(st->ksleft, inlen);
|
||||
for (i = 0; i < j; ++i, st->ksleft--) out[i] = in[i] ^ st->kstream[64 - st->ksleft];
|
||||
inlen -= j;
|
||||
if (inlen == 0) return CRYPT_OK;
|
||||
out += j;
|
||||
in += j;
|
||||
}
|
||||
for (;;) {
|
||||
s_salsa20_block(buf, st->input, st->rounds);
|
||||
/* Salsa20: 64-bit IV, increment 64-bit counter */
|
||||
if (0 == ++st->input[8] && 0 == ++st->input[9]) return CRYPT_OVERFLOW;
|
||||
if (inlen <= 64) {
|
||||
for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
|
||||
st->ksleft = 64 - inlen;
|
||||
for (i = inlen; i < 64; ++i) st->kstream[i] = buf[i];
|
||||
return CRYPT_OK;
|
||||
}
|
||||
for (i = 0; i < 64; ++i) out[i] = in[i] ^ buf[i];
|
||||
inlen -= 64;
|
||||
out += 64;
|
||||
in += 64;
|
||||
}
|
||||
}
|
||||
|
||||
#undef QUARTERROUND
|
||||
|
||||
#endif
|
||||
20
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_done.c
Normal file
20
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_done.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SALSA20
|
||||
|
||||
/**
|
||||
Terminate and clear Salsa20 state
|
||||
@param st The Salsa20 state
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int salsa20_done(salsa20_state *st)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
zeromem(st, sizeof(salsa20_state));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
|
||||
* and salsa20-ref.c version 20051118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SALSA20
|
||||
|
||||
/**
|
||||
Set IV + counter data to the Salsa20 state
|
||||
@param st The Salsa20 state
|
||||
@param iv The IV data to add
|
||||
@param ivlen The length of the IV (must be 8)
|
||||
@param counter 64bit (unsigned) initial counter value
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int salsa20_ivctr64(salsa20_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(iv != NULL);
|
||||
/* Salsa20: 64-bit IV (nonce) + 64-bit counter */
|
||||
LTC_ARGCHK(ivlen == 8);
|
||||
|
||||
LOAD32L(st->input[6], iv + 0);
|
||||
LOAD32L(st->input[7], iv + 4);
|
||||
st->input[8] = (ulong32)(counter & 0xFFFFFFFF);
|
||||
st->input[9] = (ulong32)(counter >> 32);
|
||||
st->ksleft = 0;
|
||||
st->ivlen = ivlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
|
||||
* and salsa20-ref.c version 20051118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SALSA20
|
||||
|
||||
/**
|
||||
Generate a stream of random bytes via Salsa20
|
||||
@param st The Salsa20 state
|
||||
@param out [out] The output buffer
|
||||
@param outlen The output length
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int salsa20_keystream(salsa20_state *st, unsigned char *out, unsigned long outlen)
|
||||
{
|
||||
if (outlen == 0) return CRYPT_OK; /* nothing to do */
|
||||
LTC_ARGCHK(out != NULL);
|
||||
XMEMSET(out, 0, outlen);
|
||||
return salsa20_crypt(st, out, outlen, out);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_SALSA20
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Salsa20
|
||||
@param key The key
|
||||
@param keylen The key length
|
||||
@param iv The initial vector
|
||||
@param ivlen The initial vector length
|
||||
@param datain The plaintext (or ciphertext)
|
||||
@param datalen The length of the input and output (octets)
|
||||
@param rounds The number of rounds
|
||||
@param dataout [out] The ciphertext (or plaintext)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int salsa20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds,
|
||||
const unsigned char *iv, unsigned long ivlen, ulong64 counter,
|
||||
const unsigned char *datain, unsigned long datalen, unsigned char *dataout)
|
||||
{
|
||||
salsa20_state st;
|
||||
int err;
|
||||
|
||||
if ((err = salsa20_setup(&st, key, keylen, rounds)) != CRYPT_OK) goto WIPE_KEY;
|
||||
if ((err = salsa20_ivctr64(&st, iv, ivlen, counter)) != CRYPT_OK) goto WIPE_KEY;
|
||||
err = salsa20_crypt(&st, datain, datalen, dataout);
|
||||
WIPE_KEY:
|
||||
salsa20_done(&st);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_SALSA20 */
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
58
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_setup.c
Normal file
58
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_setup.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
|
||||
* and salsa20-ref.c version 20051118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SALSA20
|
||||
|
||||
/**
|
||||
Initialize an Salsa20 context (only the key)
|
||||
@param st [out] The destination of the Salsa20 state
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param rounds Number of rounds (e.g. 20 for Salsa20)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, int rounds)
|
||||
{
|
||||
const char * const sigma = "expand 32-byte k";
|
||||
const char * const tau = "expand 16-byte k";
|
||||
const char *constants;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(keylen == 32 || keylen == 16);
|
||||
|
||||
if (rounds == 0) rounds = 20;
|
||||
LTC_ARGCHK(rounds % 2 == 0); /* number of rounds must be evenly divisible by 2 */
|
||||
|
||||
LOAD32L(st->input[1], key + 0);
|
||||
LOAD32L(st->input[2], key + 4);
|
||||
LOAD32L(st->input[3], key + 8);
|
||||
LOAD32L(st->input[4], key + 12);
|
||||
if (keylen == 32) { /* 256bit */
|
||||
key += 16;
|
||||
constants = sigma;
|
||||
} else { /* 128bit */
|
||||
constants = tau;
|
||||
}
|
||||
LOAD32L(st->input[11], key + 0);
|
||||
LOAD32L(st->input[12], key + 4);
|
||||
LOAD32L(st->input[13], key + 8);
|
||||
LOAD32L(st->input[14], key + 12);
|
||||
LOAD32L(st->input[ 0], constants + 0);
|
||||
LOAD32L(st->input[ 5], constants + 4);
|
||||
LOAD32L(st->input[10], constants + 8);
|
||||
LOAD32L(st->input[15], constants + 12);
|
||||
st->rounds = rounds; /* default is 20 for salsa20 */
|
||||
st->ivlen = 0; /* will be set later by salsa20_ivctr(32|64) */
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
86
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_test.c
Normal file
86
Sources/DataLiteC/libtomcrypt/stream/salsa20/salsa20_test.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
|
||||
* and salsa20-ref.c version 20051118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SALSA20
|
||||
|
||||
int salsa20_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
salsa20_state st;
|
||||
unsigned char k[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };
|
||||
unsigned char n[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a };
|
||||
unsigned char ct[] = { 0x37, 0x37, 0x2e, 0x60, 0xb8, 0xae, 0x88, 0x1f, 0xf8, 0xdf, 0x00, 0x26, 0x6c, 0x30, 0x34, 0x2d,
|
||||
0xa1, 0xd7, 0x79, 0x60, 0x67, 0x72, 0xe0, 0x67, 0x26, 0x22, 0xad, 0x00, 0x9e, 0xd5, 0x59, 0x44,
|
||||
0x51, 0xd9, 0xe6, 0xaa, 0xc9, 0x59, 0x9e, 0x60, 0xff, 0x87, 0x90, 0xc1, 0xc9, 0x1e };
|
||||
unsigned char ct2[] = { 0xec, 0x06, 0x32, 0xb3, 0x83, 0x5c, 0xae, 0x91, 0x01, 0x82, 0x7a, 0x71, 0xd9, 0x7d, 0x45, 0xd7,
|
||||
0xa6, 0x5b, 0xa0, 0x89, 0x9d, 0xd2, 0x6c, 0xaa, 0xbb, 0x2f, 0x5f, 0x30, 0x89, 0x54, 0xff, 0x3e,
|
||||
0x83, 0xc3, 0x34, 0x10, 0xb6, 0xe1, 0xab, 0xe7, 0xf5, 0xab, 0xab, 0xed, 0xa4, 0xff };
|
||||
char pt[] = "Kilroy was here, and there. ...and everywhere!"; /* len = 46 bytes */
|
||||
unsigned long len;
|
||||
unsigned char out[1000];
|
||||
int counter;
|
||||
int rounds;
|
||||
int err;
|
||||
len = XSTRLEN(pt);
|
||||
|
||||
/* crypt piece by piece */
|
||||
counter = 0;
|
||||
rounds = 12;
|
||||
if ((err = salsa20_setup(&st, k, sizeof(k), rounds)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_ivctr64(&st, n, sizeof(n), counter)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_crypt(&st, (unsigned char*)pt + 5, 25, out + 5)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_crypt(&st, (unsigned char*)pt + 30, 10, out + 30)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_crypt(&st, (unsigned char*)pt + 40, len - 40, out + 40)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "SALSA20-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in one go - using salsa20_ivctr64() */
|
||||
counter = 0;
|
||||
rounds = 20;
|
||||
if ((err = salsa20_setup(&st, k, sizeof(k), rounds)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_ivctr64(&st, n, sizeof(n), counter)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_crypt(&st, (unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct2, sizeof(ct2), "SALSA20-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in a single call */
|
||||
if ((err = salsa20_memory(k, sizeof(k), rounds, n, sizeof(n), counter,
|
||||
(unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct2, sizeof(ct2), "SALSA20-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
{
|
||||
/* keystream
|
||||
* http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/verified.test-vectors?rev=161&view=markup
|
||||
* Set 6, vector 0
|
||||
*/
|
||||
unsigned char k3[] = { 0x00, 0x53, 0xA6, 0xF9, 0x4C, 0x9F, 0xF2, 0x45, 0x98, 0xEB, 0x3E, 0x91, 0xE4, 0x37, 0x8A, 0xDD,
|
||||
0x30, 0x83, 0xD6, 0x29, 0x7C, 0xCF, 0x22, 0x75, 0xC8, 0x1B, 0x6E, 0xC1, 0x14, 0x67, 0xBA, 0x0D };
|
||||
unsigned char n3[] = { 0x0D, 0x74, 0xDB, 0x42, 0xA9, 0x10, 0x77, 0xDE };
|
||||
unsigned char ct3[] = { 0xF5, 0xFA, 0xD5, 0x3F, 0x79, 0xF9, 0xDF, 0x58, 0xC4, 0xAE, 0xA0, 0xD0, 0xED, 0x9A, 0x96, 0x01,
|
||||
0xF2, 0x78, 0x11, 0x2C, 0xA7, 0x18, 0x0D, 0x56, 0x5B, 0x42, 0x0A, 0x48, 0x01, 0x96, 0x70, 0xEA,
|
||||
0xF2, 0x4C, 0xE4, 0x93, 0xA8, 0x62, 0x63, 0xF6, 0x77, 0xB4, 0x6A, 0xCE, 0x19, 0x24, 0x77, 0x3D,
|
||||
0x2B, 0xB2, 0x55, 0x71, 0xE1, 0xAA, 0x85, 0x93, 0x75, 0x8F, 0xC3, 0x82, 0xB1, 0x28, 0x0B, 0x71 };
|
||||
int counter3 = 0;
|
||||
int rounds3 = 20;
|
||||
if ((err = salsa20_setup(&st, k3, sizeof(k3), rounds3)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_ivctr64(&st, n3, sizeof(n3), counter3)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_keystream(&st, out, 64)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_done(&st)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, 64, ct3, sizeof(ct3), "SALSA20-TV4", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_XSALSA20
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with XSalsa20
|
||||
@param key The key
|
||||
@param keylen The key length
|
||||
@param nonce The initial vector
|
||||
@param noncelen The initial vector length
|
||||
@param datain The plaintext (or ciphertext)
|
||||
@param datalen The length of the input and output (octets)
|
||||
@param rounds The number of rounds
|
||||
@param dataout [out] The ciphertext (or plaintext)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int xsalsa20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *datain, unsigned long datalen, unsigned char *dataout)
|
||||
{
|
||||
salsa20_state st;
|
||||
int err;
|
||||
|
||||
if ((err = xsalsa20_setup(&st, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) goto WIPE_KEY;
|
||||
err = salsa20_crypt(&st, datain, datalen, dataout);
|
||||
WIPE_KEY:
|
||||
salsa20_done(&st);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_XSALSA20 */
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
126
Sources/DataLiteC/libtomcrypt/stream/salsa20/xsalsa20_setup.c
Normal file
126
Sources/DataLiteC/libtomcrypt/stream/salsa20/xsalsa20_setup.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* "Extending the Salsa20 nonce", https://cr.yp.to/snuffle/xsalsa-20081128.pdf
|
||||
* "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
|
||||
* and salsa20-ref.c version 20051118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt.h"
|
||||
|
||||
#ifdef LTC_XSALSA20
|
||||
|
||||
#define QUARTERROUND(a,b,c,d) \
|
||||
x[b] ^= (ROL((x[a] + x[d]), 7)); \
|
||||
x[c] ^= (ROL((x[b] + x[a]), 9)); \
|
||||
x[d] ^= (ROL((x[c] + x[b]), 13)); \
|
||||
x[a] ^= (ROL((x[d] + x[c]), 18));
|
||||
|
||||
/* use modified salsa20 doubleround (no final addition as in salsa20) */
|
||||
static void s_xsalsa20_doubleround(ulong32 *x, int rounds)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = rounds; i > 0; i -= 2) {
|
||||
/* columnround */
|
||||
QUARTERROUND( 0, 4, 8,12)
|
||||
QUARTERROUND( 5, 9,13, 1)
|
||||
QUARTERROUND(10,14, 2, 6)
|
||||
QUARTERROUND(15, 3, 7,11)
|
||||
/* rowround */
|
||||
QUARTERROUND( 0, 1, 2, 3)
|
||||
QUARTERROUND( 5, 6, 7, 4)
|
||||
QUARTERROUND(10,11, 8, 9)
|
||||
QUARTERROUND(15,12,13,14)
|
||||
}
|
||||
}
|
||||
|
||||
#undef QUARTERROUND
|
||||
|
||||
/**
|
||||
Initialize an XSalsa20 context
|
||||
@param st [out] The destination of the XSalsa20 state
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key, must be 32 (octets)
|
||||
@param nonce The nonce
|
||||
@param noncelen The length of the nonce, must be 24 (octets)
|
||||
@param rounds Number of rounds (must be evenly divisible by 2, default is 20)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
int rounds)
|
||||
{
|
||||
const char * const constants = "expand 32-byte k";
|
||||
const int sti[] = {0, 5, 10, 15, 6, 7, 8, 9}; /* indices used to build subkey fm x */
|
||||
ulong32 x[64]; /* input to & output fm doubleround */
|
||||
unsigned char subkey[32];
|
||||
int i;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(keylen == 32);
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
LTC_ARGCHK(noncelen == 24);
|
||||
if (rounds == 0) rounds = 20;
|
||||
LTC_ARGCHK(rounds % 2 == 0); /* number of rounds must be evenly divisible by 2 */
|
||||
|
||||
/* load the state to "hash" the key */
|
||||
LOAD32L(x[ 0], constants + 0);
|
||||
LOAD32L(x[ 5], constants + 4);
|
||||
LOAD32L(x[10], constants + 8);
|
||||
LOAD32L(x[15], constants + 12);
|
||||
LOAD32L(x[ 1], key + 0);
|
||||
LOAD32L(x[ 2], key + 4);
|
||||
LOAD32L(x[ 3], key + 8);
|
||||
LOAD32L(x[ 4], key + 12);
|
||||
LOAD32L(x[11], key + 16);
|
||||
LOAD32L(x[12], key + 20);
|
||||
LOAD32L(x[13], key + 24);
|
||||
LOAD32L(x[14], key + 28);
|
||||
LOAD32L(x[ 6], nonce + 0);
|
||||
LOAD32L(x[ 7], nonce + 4);
|
||||
LOAD32L(x[ 8], nonce + 8);
|
||||
LOAD32L(x[ 9], nonce + 12);
|
||||
|
||||
/* use modified salsa20 doubleround (no final addition) */
|
||||
s_xsalsa20_doubleround(x, rounds);
|
||||
|
||||
/* extract the subkey */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
STORE32L(x[sti[i]], subkey + 4 * i);
|
||||
}
|
||||
|
||||
/* load the final initial state */
|
||||
LOAD32L(st->input[ 0], constants + 0);
|
||||
LOAD32L(st->input[ 5], constants + 4);
|
||||
LOAD32L(st->input[10], constants + 8);
|
||||
LOAD32L(st->input[15], constants + 12);
|
||||
LOAD32L(st->input[ 1], subkey + 0);
|
||||
LOAD32L(st->input[ 2], subkey + 4);
|
||||
LOAD32L(st->input[ 3], subkey + 8);
|
||||
LOAD32L(st->input[ 4], subkey + 12);
|
||||
LOAD32L(st->input[11], subkey + 16);
|
||||
LOAD32L(st->input[12], subkey + 20);
|
||||
LOAD32L(st->input[13], subkey + 24);
|
||||
LOAD32L(st->input[14], subkey + 28);
|
||||
LOAD32L(st->input[ 6], &(nonce[16]) + 0);
|
||||
LOAD32L(st->input[ 7], &(nonce[16]) + 4);
|
||||
st->input[ 8] = 0;
|
||||
st->input[ 9] = 0;
|
||||
st->rounds = rounds;
|
||||
st->ksleft = 0;
|
||||
st->ivlen = 24; /* set switch to say nonce/IV has been loaded */
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(x, sizeof(x));
|
||||
zeromem(subkey, sizeof(subkey));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
90
Sources/DataLiteC/libtomcrypt/stream/salsa20/xsalsa20_test.c
Normal file
90
Sources/DataLiteC/libtomcrypt/stream/salsa20/xsalsa20_test.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* "Extending the Salsa20 nonce", https://cr.yp.to/snuffle/xsalsa-20081128.pdf
|
||||
* "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
|
||||
* and salsa20-ref.c version 20051118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt.h"
|
||||
|
||||
#ifdef LTC_XSALSA20
|
||||
|
||||
#if defined(LTC_SHA256) && defined(LTC_TEST)
|
||||
static int s_sha256(unsigned char *hash, const unsigned char *data, const int datalen) {
|
||||
hash_state md;
|
||||
sha256_init(&md);
|
||||
sha256_process(&md, data, datalen);
|
||||
sha256_done(&md, hash);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int xsalsa20_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
|
||||
/***************************************************************************
|
||||
* verify a round trip:
|
||||
*/
|
||||
{
|
||||
const 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};
|
||||
const 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};
|
||||
const void *msg = "Kilroy was here!";
|
||||
unsigned char msglen = 17; /* includes trailing NULL */
|
||||
int rounds = 20;
|
||||
unsigned char ciphertext[17];
|
||||
unsigned char msg2[17];
|
||||
salsa20_state st;
|
||||
int err;
|
||||
|
||||
if ((err = xsalsa20_setup(&st, key, 32, nonce, 24, rounds)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_crypt(&st, msg, msglen, ciphertext)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_done(&st)) != CRYPT_OK) return err;
|
||||
|
||||
if ((err = xsalsa20_setup(&st, key, 32, nonce, 24, rounds)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_crypt(&st, ciphertext, msglen, msg2)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_done(&st)) != CRYPT_OK) return err;
|
||||
|
||||
if (compare_testvector(msg, msglen, msg2, msglen, "XSALSA20-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
|
||||
/* round trip with two single function calls */
|
||||
if ((err = xsalsa20_memory(key, sizeof(key), 20, nonce, sizeof(nonce), msg, msglen, ciphertext)) != CRYPT_OK) return err;
|
||||
if ((err = xsalsa20_memory(key, sizeof(key), 20, nonce, sizeof(nonce), ciphertext, msglen, msg2)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(msg, msglen, msg2, msglen, "XSALSA20-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
#ifdef LTC_SHA256
|
||||
/***************************************************************************
|
||||
* verify correct generation of a keystream
|
||||
*/
|
||||
{
|
||||
const 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};
|
||||
const 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};
|
||||
const unsigned char expecthash[] = {0x6a,0x60,0x57,0x65,0x27,0xe0,0x00,0x51,0x6d,0xb0,0xda,0x60,0x46,0x20,0xf6,0xd0,0x95,0x65,0x45,0x39,0xf4,0x86,0x83,0x43,0x64,0xdf,0xd9,0x5a,0x6f,0x3f,0xbe,0xb7};
|
||||
int rounds = 20;
|
||||
unsigned char keystream[91101];
|
||||
unsigned long keystreamlen = 91101;
|
||||
unsigned char hash[32];
|
||||
salsa20_state st;
|
||||
int err;
|
||||
|
||||
if ((err = xsalsa20_setup(&st, key, 32, nonce, 24, rounds)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_keystream(&st, keystream, keystreamlen)) != CRYPT_OK) return err;
|
||||
if ((err = salsa20_done(&st)) != CRYPT_OK) return err;
|
||||
if ((err = s_sha256(hash, keystream, keystreamlen)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(hash, sizeof(hash), expecthash, sizeof(expecthash), "XSALSA20-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user