Replaced system SQLite with SQLCipher to support encrypted database
This commit is contained in:
93
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_crypt.c
Normal file
93
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_crypt.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* chacha-ref.c version 20080118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA
|
||||
|
||||
#define QUARTERROUND(a,b,c,d) \
|
||||
x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
|
||||
x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
|
||||
x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 8); \
|
||||
x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 7);
|
||||
|
||||
static void s_chacha_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(1, 5, 9,13)
|
||||
QUARTERROUND(2, 6,10,14)
|
||||
QUARTERROUND(3, 7,11,15)
|
||||
QUARTERROUND(0, 5,10,15)
|
||||
QUARTERROUND(1, 6,11,12)
|
||||
QUARTERROUND(2, 7, 8,13)
|
||||
QUARTERROUND(3, 4, 9,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 ChaCha
|
||||
@param st The ChaCha 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 chacha_crypt(chacha_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 != 0);
|
||||
|
||||
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_chacha_block(buf, st->input, st->rounds);
|
||||
if (st->ivlen == 8) {
|
||||
/* IV-64bit, increment 64bit counter */
|
||||
if (0 == ++st->input[12] && 0 == ++st->input[13]) return CRYPT_OVERFLOW;
|
||||
}
|
||||
else {
|
||||
/* IV-96bit, increment 32bit counter */
|
||||
if (0 == ++st->input[12]) 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/chacha/chacha_done.c
Normal file
20
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_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_CHACHA
|
||||
|
||||
/**
|
||||
Terminate and clear ChaCha state
|
||||
@param st The ChaCha state
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha_done(chacha_state *st)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
zeromem(st, sizeof(chacha_state));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
37
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_ivctr32.c
Normal file
37
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_ivctr32.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* chacha-ref.c version 20080118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA
|
||||
|
||||
/**
|
||||
Set IV + counter data to the ChaCha state
|
||||
@param st The ChaCha20 state
|
||||
@param iv The IV data to add
|
||||
@param ivlen The length of the IV (must be 12)
|
||||
@param counter 32bit (unsigned) initial counter value
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(iv != NULL);
|
||||
/* 96bit IV + 32bit counter */
|
||||
LTC_ARGCHK(ivlen == 12);
|
||||
|
||||
st->input[12] = counter;
|
||||
LOAD32L(st->input[13], iv + 0);
|
||||
LOAD32L(st->input[14], iv + 4);
|
||||
LOAD32L(st->input[15], iv + 8);
|
||||
st->ksleft = 0;
|
||||
st->ivlen = ivlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
37
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_ivctr64.c
Normal file
37
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_ivctr64.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* chacha-ref.c version 20080118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA
|
||||
|
||||
/**
|
||||
Set IV + counter data to the ChaCha state
|
||||
@param st The ChaCha20 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 chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(iv != NULL);
|
||||
/* 64bit IV + 64bit counter */
|
||||
LTC_ARGCHK(ivlen == 8);
|
||||
|
||||
st->input[12] = (ulong32)(counter & 0xFFFFFFFF);
|
||||
st->input[13] = (ulong32)(counter >> 32);
|
||||
LOAD32L(st->input[14], iv + 0);
|
||||
LOAD32L(st->input[15], iv + 4);
|
||||
st->ksleft = 0;
|
||||
st->ivlen = ivlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* chacha-ref.c version 20080118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA
|
||||
|
||||
/**
|
||||
Generate a stream of random bytes via ChaCha
|
||||
@param st The ChaCha20 state
|
||||
@param out [out] The output buffer
|
||||
@param outlen The output length
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha_keystream(chacha_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 chacha_crypt(st, out, outlen, out);
|
||||
}
|
||||
|
||||
#endif
|
||||
57
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_memory.c
Normal file
57
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_memory.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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_CHACHA
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with ChaCha
|
||||
@param key The key
|
||||
@param keylen The key length
|
||||
@param rounds The number of rounds
|
||||
@param iv The initial vector
|
||||
@param ivlen The initial vector length
|
||||
@param counter initial counter value, either ignored, 32- or 64-bit, depending on ivlen
|
||||
@param datain The plaintext (or ciphertext)
|
||||
@param datalen The length of the input and output (octets)
|
||||
@param dataout [out] The ciphertext (or plaintext)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int chacha_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)
|
||||
{
|
||||
chacha_state st;
|
||||
int err;
|
||||
const unsigned char *iv_ = iv;
|
||||
unsigned long ivlen_ = ivlen;
|
||||
ulong64 counter_ = counter;
|
||||
|
||||
if (ivlen == 16) {
|
||||
LOAD64L(counter_, iv);
|
||||
iv_ += 8;
|
||||
ivlen_ -=8;
|
||||
}
|
||||
|
||||
LTC_ARGCHK(ivlen_ <= 8 || counter_ < CONST64(4294967296)); /* 2**32 */
|
||||
|
||||
if ((err = chacha_setup(&st, key, keylen, rounds)) != CRYPT_OK) goto WIPE_KEY;
|
||||
if (ivlen_ > 8) {
|
||||
if ((err = chacha_ivctr32(&st, iv_, ivlen_, (ulong32)counter_)) != CRYPT_OK) goto WIPE_KEY;
|
||||
} else {
|
||||
if ((err = chacha_ivctr64(&st, iv_, ivlen_, counter_)) != CRYPT_OK) goto WIPE_KEY;
|
||||
}
|
||||
err = chacha_crypt(&st, datain, datalen, dataout);
|
||||
WIPE_KEY:
|
||||
chacha_done(&st);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_CHACHA */
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
56
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_setup.c
Normal file
56
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_setup.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* chacha-ref.c version 20080118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA
|
||||
|
||||
/**
|
||||
Initialize an ChaCha context (only the key)
|
||||
@param st [out] The destination of the ChaCha state
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param rounds Number of rounds (e.g. 20 for ChaCha20)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int chacha_setup(chacha_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;
|
||||
|
||||
LOAD32L(st->input[4], key + 0);
|
||||
LOAD32L(st->input[5], key + 4);
|
||||
LOAD32L(st->input[6], key + 8);
|
||||
LOAD32L(st->input[7], key + 12);
|
||||
if (keylen == 32) { /* 256bit */
|
||||
key += 16;
|
||||
constants = sigma;
|
||||
} else { /* 128bit */
|
||||
constants = tau;
|
||||
}
|
||||
LOAD32L(st->input[8], key + 0);
|
||||
LOAD32L(st->input[9], key + 4);
|
||||
LOAD32L(st->input[10], key + 8);
|
||||
LOAD32L(st->input[11], key + 12);
|
||||
LOAD32L(st->input[0], constants + 0);
|
||||
LOAD32L(st->input[1], constants + 4);
|
||||
LOAD32L(st->input[2], constants + 8);
|
||||
LOAD32L(st->input[3], constants + 12);
|
||||
st->rounds = rounds; /* e.g. 20 for chacha20 */
|
||||
st->ivlen = 0; /* will be set later by chacha_ivctr(32|64) */
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
74
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_test.c
Normal file
74
Sources/DataLiteC/libtomcrypt/stream/chacha/chacha_test.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* chacha-ref.c version 20080118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA
|
||||
|
||||
int chacha_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
unsigned long len;
|
||||
unsigned char out[1000];
|
||||
/* https://tools.ietf.org/html/rfc7539#section-2.4.2 */
|
||||
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, 0x00, 0x00, 0x00, 0x00 };
|
||||
unsigned char ct[] = { 0x6E, 0x2E, 0x35, 0x9A, 0x25, 0x68, 0xF9, 0x80, 0x41, 0xBA, 0x07, 0x28, 0xDD, 0x0D, 0x69, 0x81,
|
||||
0xE9, 0x7E, 0x7A, 0xEC, 0x1D, 0x43, 0x60, 0xC2, 0x0A, 0x27, 0xAF, 0xCC, 0xFD, 0x9F, 0xAE, 0x0B,
|
||||
0xF9, 0x1B, 0x65, 0xC5, 0x52, 0x47, 0x33, 0xAB, 0x8F, 0x59, 0x3D, 0xAB, 0xCD, 0x62, 0xB3, 0x57,
|
||||
0x16, 0x39, 0xD6, 0x24, 0xE6, 0x51, 0x52, 0xAB, 0x8F, 0x53, 0x0C, 0x35, 0x9F, 0x08, 0x61, 0xD8,
|
||||
0x07, 0xCA, 0x0D, 0xBF, 0x50, 0x0D, 0x6A, 0x61, 0x56, 0xA3, 0x8E, 0x08, 0x8A, 0x22, 0xB6, 0x5E,
|
||||
0x52, 0xBC, 0x51, 0x4D, 0x16, 0xCC, 0xF8, 0x06, 0x81, 0x8C, 0xE9, 0x1A, 0xB7, 0x79, 0x37, 0x36,
|
||||
0x5A, 0xF9, 0x0B, 0xBF, 0x74, 0xA3, 0x5B, 0xE6, 0xB4, 0x0B, 0x8E, 0xED, 0xF2, 0x78, 0x5E, 0x42,
|
||||
0x87, 0x4D };
|
||||
char pt[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
|
||||
chacha_state st;
|
||||
int err;
|
||||
|
||||
len = XSTRLEN(pt);
|
||||
|
||||
/* crypt piece by piece - using chacha_ivctr32() */
|
||||
if ((err = chacha_setup(&st, k, sizeof(k), 20)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_ivctr32(&st, n, sizeof(n), 1)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st, (unsigned char*)pt, 35, out )) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st, (unsigned char*)pt + 35, 35, out + 35)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st, (unsigned char*)pt + 70, 5, out + 70)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st, (unsigned char*)pt + 75, 5, out + 75)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st, (unsigned char*)pt + 80, len - 80, out + 80)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "CHACHA-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in one go - using chacha_ivctr32() */
|
||||
if ((err = chacha_setup(&st, k, sizeof(k), 20)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_ivctr32(&st, n, sizeof(n), 1)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st, (unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "CHACHA-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in one go - using chacha_ivctr64() */
|
||||
if ((err = chacha_setup(&st, k, sizeof(k), 20)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_ivctr64(&st, n + 4, sizeof(n) - 4, 1)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st, (unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "CHACHA-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in a single call using 32-bit counter with a value of 1 */
|
||||
if ((err = chacha_memory(k, sizeof(k), 20,
|
||||
n, sizeof(n), 1, (unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "CHACHA-TV4", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in a single call using 64-bit counter with a value of 1 */
|
||||
if ((err = chacha_memory(k, sizeof(k), 20,
|
||||
n + 4, sizeof(n) - 4, 1, (unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "CHACHA-TV5", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
453
Sources/DataLiteC/libtomcrypt/stream/rabbit/rabbit.c
Normal file
453
Sources/DataLiteC/libtomcrypt/stream/rabbit/rabbit.c
Normal file
@@ -0,0 +1,453 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/******************************************************************************
|
||||
* This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
|
||||
* and should run on any conforming C implementation (C90 or later).
|
||||
*
|
||||
* This implementation supports any key length up to 128 bits (16 bytes) and
|
||||
* works in increments of 8-bit bytes. Keys must be submitted as whole bytes
|
||||
* and shorter keys will be right-null-padded to 16 bytes. Likewise, an iv
|
||||
* may be any length up to 8 bytes and will be padded out to 8 bytes.
|
||||
*
|
||||
* The eSTREAM submission was rather picky about the calling sequence of
|
||||
* ECRYPT_process_blocks() and ECRYPT_process_bytes(). That version allowed
|
||||
* calling ECRYPT_process_blocks() multiple times for a multiple of whole
|
||||
* 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
|
||||
* were supported correctly. This implementation handles the keystream
|
||||
* differently and rabbit_crypt() may be called as many times as desired,
|
||||
* crypting any number of bytes each time.
|
||||
*
|
||||
* http://www.ecrypt.eu.org/stream/e2-rabbit.html
|
||||
*
|
||||
* NB: One of the test vectors distributed by the eSTREAM site in the file
|
||||
* "rabbit_p3source.zip" is in error. Referring to "test-vectors.txt"
|
||||
* in that ZIP file, the 3rd line in "out1" should be
|
||||
* "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
|
||||
*
|
||||
* Here is the original legal notice accompanying the Rabbit submission
|
||||
* to the EU eSTREAM competition.
|
||||
*---------------------------------------------------------------------------
|
||||
* Copyright (C) Cryptico A/S. All rights reserved.
|
||||
*
|
||||
* YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
|
||||
*
|
||||
* This software is developed by Cryptico A/S and/or its suppliers.
|
||||
* All title and intellectual property rights in and to the software,
|
||||
* including but not limited to patent rights and copyrights, are owned
|
||||
* by Cryptico A/S and/or its suppliers.
|
||||
*
|
||||
* The software may be used solely for non-commercial purposes
|
||||
* without the prior written consent of Cryptico A/S. For further
|
||||
* information on licensing terms and conditions please contact
|
||||
* Cryptico A/S at info@cryptico.com
|
||||
*
|
||||
* Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
|
||||
* are either trademarks or registered trademarks of Cryptico A/S.
|
||||
*
|
||||
* Cryptico A/S shall not in any way be liable for any use of this
|
||||
* software. The software is provided "as is" without any express or
|
||||
* implied warranty.
|
||||
*---------------------------------------------------------------------------
|
||||
* On October 6, 2008, Rabbit was "released into the public domain and
|
||||
* may be used freely for any purpose."
|
||||
* http://www.ecrypt.eu.org/stream/rabbitpf.html
|
||||
* https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_RABBIT
|
||||
|
||||
/* local/private prototypes (NB: rabbit_ctx and rabbit_state are different) */
|
||||
static LTC_INLINE ulong32 ss_rabbit_g_func(ulong32 x);
|
||||
static LTC_INLINE void ss_rabbit_next_state(rabbit_ctx *p_instance);
|
||||
static LTC_INLINE void ss_rabbit_gen_1_block(rabbit_state* st, unsigned char *out);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
|
||||
/* the upper 32 bits XOR the lower 32 bits */
|
||||
static LTC_INLINE ulong32 ss_rabbit_g_func(ulong32 x)
|
||||
{
|
||||
ulong32 a, b, h, l;
|
||||
|
||||
/* Construct high and low argument for squaring */
|
||||
a = x & 0xFFFF;
|
||||
b = x >> 16;
|
||||
|
||||
/* Calculate high and low result of squaring */
|
||||
h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
|
||||
l = x * x;
|
||||
|
||||
/* Return high XOR low */
|
||||
return (ulong32)(h^l);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* Calculate the next internal state */
|
||||
static LTC_INLINE void ss_rabbit_next_state(rabbit_ctx *p_instance)
|
||||
{
|
||||
ulong32 g[8], c_old[8], i;
|
||||
|
||||
/* Save old counter values */
|
||||
for (i=0; i<8; i++) {
|
||||
c_old[i] = p_instance->c[i];
|
||||
}
|
||||
|
||||
/* Calculate new counter values */
|
||||
p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
|
||||
p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
|
||||
p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
|
||||
p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
|
||||
p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
|
||||
p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
|
||||
p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
|
||||
p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
|
||||
p_instance->carry = (p_instance->c[7] < c_old[7]);
|
||||
|
||||
/* Calculate the g-values */
|
||||
for (i=0;i<8;i++) {
|
||||
g[i] = ss_rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
|
||||
}
|
||||
|
||||
/* Calculate new state values */
|
||||
p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
|
||||
p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
|
||||
p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
|
||||
p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
|
||||
p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
|
||||
p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
|
||||
p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
|
||||
p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static LTC_INLINE void ss_rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
|
||||
{
|
||||
ulong32 *ptr;
|
||||
|
||||
/* Iterate the work context once */
|
||||
ss_rabbit_next_state(&(st->work_ctx));
|
||||
|
||||
/* Generate 16 bytes of pseudo-random data */
|
||||
ptr = (ulong32*)&(st->work_ctx.x);
|
||||
STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
|
||||
STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
|
||||
STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
|
||||
STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* Key setup */
|
||||
int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
ulong32 k0, k1, k2, k3, i;
|
||||
unsigned char tmpkey[16] = {0};
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(keylen <= 16);
|
||||
|
||||
/* init state */
|
||||
XMEMSET(st, 0, sizeof(rabbit_state));
|
||||
|
||||
/* pad key in tmpkey */
|
||||
XMEMCPY(tmpkey, key, keylen);
|
||||
|
||||
/* Generate four subkeys */
|
||||
LOAD32L(k0, tmpkey+ 0);
|
||||
LOAD32L(k1, tmpkey+ 4);
|
||||
LOAD32L(k2, tmpkey+ 8);
|
||||
LOAD32L(k3, tmpkey+12);
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
/* done with tmpkey, wipe it */
|
||||
zeromem(tmpkey, sizeof(tmpkey));
|
||||
#endif
|
||||
|
||||
/* Generate initial state variables */
|
||||
st->master_ctx.x[0] = k0;
|
||||
st->master_ctx.x[2] = k1;
|
||||
st->master_ctx.x[4] = k2;
|
||||
st->master_ctx.x[6] = k3;
|
||||
st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
|
||||
st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
|
||||
st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
|
||||
st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);
|
||||
|
||||
/* Generate initial counter values */
|
||||
st->master_ctx.c[0] = ROLc(k2, 16);
|
||||
st->master_ctx.c[2] = ROLc(k3, 16);
|
||||
st->master_ctx.c[4] = ROLc(k0, 16);
|
||||
st->master_ctx.c[6] = ROLc(k1, 16);
|
||||
st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
|
||||
st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
|
||||
st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
|
||||
st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
|
||||
|
||||
/* Clear carry bit */
|
||||
st->master_ctx.carry = 0;
|
||||
|
||||
/* Iterate the master context four times */
|
||||
for (i=0; i<4; i++) {
|
||||
ss_rabbit_next_state(&(st->master_ctx));
|
||||
}
|
||||
|
||||
/* Modify the counters */
|
||||
for (i=0; i<8; i++) {
|
||||
st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
|
||||
}
|
||||
|
||||
/* Copy master instance to work instance */
|
||||
for (i=0; i<8; i++) {
|
||||
st->work_ctx.x[i] = st->master_ctx.x[i];
|
||||
st->work_ctx.c[i] = st->master_ctx.c[i];
|
||||
}
|
||||
st->work_ctx.carry = st->master_ctx.carry;
|
||||
/* ...and prepare block for crypt() */
|
||||
XMEMSET(&(st->block), 0, sizeof(st->block));
|
||||
st->unused = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* IV setup */
|
||||
int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
|
||||
{
|
||||
ulong32 i0, i1, i2, i3, i;
|
||||
unsigned char tmpiv[8] = {0};
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(iv != NULL || ivlen == 0);
|
||||
LTC_ARGCHK(ivlen <= 8);
|
||||
|
||||
/* pad iv in tmpiv */
|
||||
if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);
|
||||
|
||||
/* Generate four subvectors */
|
||||
LOAD32L(i0, tmpiv+0);
|
||||
LOAD32L(i2, tmpiv+4);
|
||||
i1 = (i0>>16) | (i2&0xFFFF0000);
|
||||
i3 = (i2<<16) | (i0&0x0000FFFF);
|
||||
|
||||
/* Modify counter values */
|
||||
st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
|
||||
st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
|
||||
st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
|
||||
st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
|
||||
st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
|
||||
st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
|
||||
st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
|
||||
st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;
|
||||
|
||||
/* Copy state variables */
|
||||
for (i=0; i<8; i++) {
|
||||
st->work_ctx.x[i] = st->master_ctx.x[i];
|
||||
}
|
||||
st->work_ctx.carry = st->master_ctx.carry;
|
||||
|
||||
/* Iterate the work context four times */
|
||||
for (i=0; i<4; i++) {
|
||||
ss_rabbit_next_state(&(st->work_ctx));
|
||||
}
|
||||
|
||||
/* reset keystream buffer and unused count */
|
||||
XMEMSET(&(st->block), 0, sizeof(st->block));
|
||||
st->unused = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Crypt a chunk of any size (encrypt/decrypt) */
|
||||
int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
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);
|
||||
|
||||
if (st->unused > 0) {
|
||||
j = MIN(st->unused, inlen);
|
||||
for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
|
||||
inlen -= j;
|
||||
if (inlen == 0) return CRYPT_OK;
|
||||
out += j;
|
||||
in += j;
|
||||
}
|
||||
for (;;) {
|
||||
/* gen a block for buf */
|
||||
ss_rabbit_gen_1_block(st, buf);
|
||||
if (inlen <= 16) {
|
||||
/* XOR and send to out */
|
||||
for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
|
||||
st->unused = 16 - inlen;
|
||||
/* copy remainder to block */
|
||||
for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
|
||||
return CRYPT_OK;
|
||||
}
|
||||
/* XOR entire buf and send to out */
|
||||
for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
|
||||
inlen -= 16;
|
||||
out += 16;
|
||||
in += 16;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int rabbit_keystream(rabbit_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 rabbit_crypt(st, out, outlen, out);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int rabbit_done(rabbit_state *st)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
|
||||
zeromem(st, sizeof(rabbit_state));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int rabbit_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
rabbit_state st;
|
||||
int err;
|
||||
unsigned char out[1000] = { 0 };
|
||||
{
|
||||
/* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
|
||||
http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
|
||||
*/
|
||||
|
||||
/* --- Test 1 (generate whole blocks) --------------------------------- */
|
||||
|
||||
{
|
||||
unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
|
||||
0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
|
||||
unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
|
||||
char pt[64] = { 0 };
|
||||
unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
|
||||
0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
|
||||
0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
|
||||
0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
|
||||
0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
|
||||
0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
|
||||
0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
|
||||
0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
|
||||
unsigned long ptlen = sizeof(pt);
|
||||
|
||||
/* crypt 64 nulls */
|
||||
if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* --- Test 2 (generate unusual number of bytes each time) ------------ */
|
||||
|
||||
{
|
||||
unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
|
||||
0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
|
||||
unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
|
||||
char pt[39] = { 0 };
|
||||
unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
|
||||
0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
|
||||
0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
|
||||
0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
|
||||
0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D };
|
||||
unsigned long ptlen = sizeof(pt);
|
||||
|
||||
/* crypt piece by piece (hit at least one 16-byte boundary) */
|
||||
if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 11, out + 5)) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30, 2, out + 30)) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32, 7, out + 32)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* --- Test 3 (use non-null data) ------------------------------------- */
|
||||
|
||||
{
|
||||
unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
|
||||
0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
|
||||
unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
|
||||
char pt[] = "Kilroy was here, there, and everywhere!";
|
||||
unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8, 0xf9, 0xd6, 0xd6, 0xbd,
|
||||
0xae, 0x59, 0x65, 0xf2, 0x75, 0x58, 0x1a, 0x54,
|
||||
0xea, 0xec, 0x34, 0x9d, 0x8f, 0xb4, 0x6b, 0x60,
|
||||
0x79, 0x1b, 0xea, 0x16, 0xcb, 0xef, 0x46, 0x87,
|
||||
0x60, 0xa6, 0x55, 0x14, 0xff, 0xca, 0xac };
|
||||
unsigned long ptlen = XSTRLEN(pt);
|
||||
unsigned char out2[1000] = { 0 };
|
||||
unsigned char nulls[1000] = { 0 };
|
||||
|
||||
/* crypt piece by piece */
|
||||
if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 29, out + 5)) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34, 5, out + 34)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* --- Test 4 (crypt in a single call) ------------------------------------ */
|
||||
|
||||
if ((err = rabbit_memory(k, sizeof(k), iv, sizeof(iv),
|
||||
(unsigned char*)pt, sizeof(pt), out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV4", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
/* use 'out' (ciphertext) in the next decryption test */
|
||||
|
||||
/* --- Test 5 (decrypt ciphertext) ------------------------------------ */
|
||||
|
||||
/* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
|
||||
if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
|
||||
if ((err = rabbit_crypt(&st, out, ptlen, out2)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV5", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* --- Test 6 (wipe state, incl key) ---------------------------------- */
|
||||
|
||||
if ((err = rabbit_done(&st)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV6", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
40
Sources/DataLiteC/libtomcrypt/stream/rabbit/rabbit_memory.c
Normal file
40
Sources/DataLiteC/libtomcrypt/stream/rabbit/rabbit_memory.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/* The implementation is based on:
|
||||
* chacha-ref.c version 20080118
|
||||
* Public domain from D. J. Bernstein
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_RABBIT
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Rabbit
|
||||
@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 dataout [out] The ciphertext (or plaintext)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int rabbit_memory(const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *iv, unsigned long ivlen,
|
||||
const unsigned char *datain, unsigned long datalen,
|
||||
unsigned char *dataout)
|
||||
{
|
||||
rabbit_state st;
|
||||
int err;
|
||||
|
||||
if ((err = rabbit_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY;
|
||||
if ((err = rabbit_setiv(&st, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY;
|
||||
err = rabbit_crypt(&st, datain, datalen, dataout);
|
||||
WIPE_KEY:
|
||||
rabbit_done(&st);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_RABBIT */
|
||||
101
Sources/DataLiteC/libtomcrypt/stream/rc4/rc4_stream.c
Normal file
101
Sources/DataLiteC/libtomcrypt/stream/rc4/rc4_stream.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_RC4_STREAM
|
||||
|
||||
/**
|
||||
Initialize an RC4 context (only the key)
|
||||
@param st [out] The destination of the RC4 state
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (8 - 256 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
unsigned char tmp, *s;
|
||||
int x, y;
|
||||
unsigned long j;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */
|
||||
|
||||
s = st->buf;
|
||||
for (x = 0; x < 256; x++) {
|
||||
s[x] = x;
|
||||
}
|
||||
|
||||
for (j = x = y = 0; x < 256; x++) {
|
||||
y = (y + s[x] + key[j++]) & 255;
|
||||
if (j == keylen) {
|
||||
j = 0;
|
||||
}
|
||||
tmp = s[x]; s[x] = s[y]; s[y] = tmp;
|
||||
}
|
||||
st->x = 0;
|
||||
st->y = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4
|
||||
@param st The RC4 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 rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
|
||||
{
|
||||
unsigned char x, y, *s, tmp;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
x = st->x;
|
||||
y = st->y;
|
||||
s = st->buf;
|
||||
while (inlen--) {
|
||||
x = (x + 1) & 255;
|
||||
y = (y + s[x]) & 255;
|
||||
tmp = s[x]; s[x] = s[y]; s[y] = tmp;
|
||||
tmp = (s[x] + s[y]) & 255;
|
||||
*out++ = *in++ ^ s[tmp];
|
||||
}
|
||||
st->x = x;
|
||||
st->y = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Generate a stream of random bytes via RC4
|
||||
@param st The RC420 state
|
||||
@param out [out] The output buffer
|
||||
@param outlen The output length
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int rc4_stream_keystream(rc4_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 rc4_stream_crypt(st, out, outlen, out);
|
||||
}
|
||||
|
||||
/**
|
||||
Terminate and clear RC4 state
|
||||
@param st The RC4 state
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int rc4_stream_done(rc4_state *st)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
zeromem(st, sizeof(rc4_state));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
31
Sources/DataLiteC/libtomcrypt/stream/rc4/rc4_stream_memory.c
Normal file
31
Sources/DataLiteC/libtomcrypt/stream/rc4/rc4_stream_memory.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_RC4_STREAM
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4
|
||||
@param key The key
|
||||
@param keylen The key length
|
||||
@param datain The plaintext (or ciphertext)
|
||||
@param datalen The length of the input and output (octets)
|
||||
@param dataout [out] The ciphertext (or plaintext)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int rc4_stream_memory(const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *datain, unsigned long datalen,
|
||||
unsigned char *dataout)
|
||||
{
|
||||
rc4_state st;
|
||||
int err;
|
||||
|
||||
if ((err = rc4_stream_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY;
|
||||
err = rc4_stream_crypt(&st, datain, datalen, dataout);
|
||||
WIPE_KEY:
|
||||
rc4_stream_done(&st);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_RC4_STREAM */
|
||||
33
Sources/DataLiteC/libtomcrypt/stream/rc4/rc4_test.c
Normal file
33
Sources/DataLiteC/libtomcrypt/stream/rc4/rc4_test.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_RC4_STREAM
|
||||
|
||||
int rc4_stream_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
rc4_state st;
|
||||
int err;
|
||||
const unsigned char key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
|
||||
const unsigned char pt[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
|
||||
const unsigned char ct[] = { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 };
|
||||
unsigned char buf[10];
|
||||
|
||||
if ((err = rc4_stream_setup(&st, key, sizeof(key))) != CRYPT_OK) return err;
|
||||
if ((err = rc4_stream_crypt(&st, pt, sizeof(pt), buf)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(buf, sizeof(ct), ct, sizeof(ct), "RC4-TV1", 0)) return CRYPT_FAIL_TESTVECTOR;
|
||||
if ((err = rc4_stream_done(&st)) != CRYPT_OK) return err;
|
||||
|
||||
/* crypt in a single call */
|
||||
if ((err = rc4_stream_memory(key, sizeof(key), pt, sizeof(pt), buf)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(buf, sizeof(ct), ct, sizeof(ct), "RC4-TV2", 0)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
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
|
||||
347
Sources/DataLiteC/libtomcrypt/stream/sober128/sober128_stream.c
Normal file
347
Sources/DataLiteC/libtomcrypt/stream/sober128/sober128_stream.c
Normal file
@@ -0,0 +1,347 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file sober128_stream.c
|
||||
Implementation of SOBER-128 by Tom St Denis.
|
||||
Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
|
||||
*/
|
||||
|
||||
#ifdef LTC_SOBER128
|
||||
|
||||
#ifndef LTC_SOBER128TAB_C
|
||||
#define LTC_SOBER128TAB_C
|
||||
#include "sober128tab.c"
|
||||
#endif
|
||||
|
||||
/* don't change these... */
|
||||
#define N 17
|
||||
#define INITKONST 0x6996c53a /* value of KONST to use during key loading */
|
||||
#define KEYP 15 /* where to insert key words */
|
||||
#define FOLDP 4 /* where to insert non-linear feedback */
|
||||
|
||||
static ulong32 BYTE2WORD(const unsigned char *b)
|
||||
{
|
||||
ulong32 t;
|
||||
LOAD32L(t, b);
|
||||
return t;
|
||||
}
|
||||
|
||||
static void XORWORD(ulong32 w, const unsigned char *in, unsigned char *out)
|
||||
{
|
||||
ulong32 t;
|
||||
LOAD32L(t, in);
|
||||
t ^= w;
|
||||
STORE32L(t, out);
|
||||
}
|
||||
|
||||
/* give correct offset for the current position of the register,
|
||||
* where logically R[0] is at position "zero".
|
||||
*/
|
||||
#define OFF(zero, i) (((zero)+(i)) % N)
|
||||
|
||||
/* step the LFSR */
|
||||
/* After stepping, "zero" moves right one place */
|
||||
#define STEP(R,z) \
|
||||
R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
|
||||
|
||||
static void cycle(ulong32 *R)
|
||||
{
|
||||
ulong32 t;
|
||||
int i;
|
||||
|
||||
STEP(R,0);
|
||||
t = R[0];
|
||||
for (i = 1; i < N; ++i) {
|
||||
R[i-1] = R[i];
|
||||
}
|
||||
R[N-1] = t;
|
||||
}
|
||||
|
||||
/* Return a non-linear function of some parts of the register.
|
||||
*/
|
||||
#define NLFUNC(st,z) \
|
||||
{ \
|
||||
t = st->R[OFF(z,0)] + st->R[OFF(z,16)]; \
|
||||
t ^= Sbox[(t >> 24) & 0xFF]; \
|
||||
t = RORc(t, 8); \
|
||||
t = ((t + st->R[OFF(z,1)]) ^ st->konst) + st->R[OFF(z,6)]; \
|
||||
t ^= Sbox[(t >> 24) & 0xFF]; \
|
||||
t = t + st->R[OFF(z,13)]; \
|
||||
}
|
||||
|
||||
static ulong32 nltap(const sober128_state *st)
|
||||
{
|
||||
ulong32 t;
|
||||
NLFUNC(st, 0);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Save the current register state
|
||||
*/
|
||||
static void s128_savestate(sober128_state *st)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < N; ++i) {
|
||||
st->initR[i] = st->R[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* initialise to previously saved register state
|
||||
*/
|
||||
static void s128_reloadstate(sober128_state *st)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < N; ++i) {
|
||||
st->R[i] = st->initR[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialise "konst"
|
||||
*/
|
||||
static void s128_genkonst(sober128_state *st)
|
||||
{
|
||||
ulong32 newkonst;
|
||||
|
||||
do {
|
||||
cycle(st->R);
|
||||
newkonst = nltap(st);
|
||||
} while ((newkonst & 0xFF000000) == 0);
|
||||
st->konst = newkonst;
|
||||
}
|
||||
|
||||
/* Load key material into the register
|
||||
*/
|
||||
#define ADDKEY(k) \
|
||||
st->R[KEYP] += (k);
|
||||
|
||||
#define XORNL(nl) \
|
||||
st->R[FOLDP] ^= (nl);
|
||||
|
||||
/* nonlinear diffusion of register for key */
|
||||
#define DROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); st->R[OFF((z+1),FOLDP)] ^= t;
|
||||
static void s128_diffuse(sober128_state *st)
|
||||
{
|
||||
ulong32 t;
|
||||
/* relies on FOLD == N == 17! */
|
||||
DROUND(0);
|
||||
DROUND(1);
|
||||
DROUND(2);
|
||||
DROUND(3);
|
||||
DROUND(4);
|
||||
DROUND(5);
|
||||
DROUND(6);
|
||||
DROUND(7);
|
||||
DROUND(8);
|
||||
DROUND(9);
|
||||
DROUND(10);
|
||||
DROUND(11);
|
||||
DROUND(12);
|
||||
DROUND(13);
|
||||
DROUND(14);
|
||||
DROUND(15);
|
||||
DROUND(16);
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize an Sober128 context (only the key)
|
||||
@param st [out] The destination of the Sober128 state
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
ulong32 i, k;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(keylen > 0);
|
||||
|
||||
/* keylen must be multiple of 4 bytes */
|
||||
if ((keylen & 3) != 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* Register initialised to Fibonacci numbers */
|
||||
st->R[0] = 1;
|
||||
st->R[1] = 1;
|
||||
for (i = 2; i < N; ++i) {
|
||||
st->R[i] = st->R[i-1] + st->R[i-2];
|
||||
}
|
||||
st->konst = INITKONST;
|
||||
|
||||
for (i = 0; i < keylen; i += 4) {
|
||||
k = BYTE2WORD(&key[i]);
|
||||
ADDKEY(k);
|
||||
cycle(st->R);
|
||||
XORNL(nltap(st));
|
||||
}
|
||||
|
||||
/* also fold in the length of the key */
|
||||
ADDKEY(keylen);
|
||||
|
||||
/* now diffuse */
|
||||
s128_diffuse(st);
|
||||
s128_genkonst(st);
|
||||
s128_savestate(st);
|
||||
st->nbuf = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Set IV to the Sober128 state
|
||||
@param st The Sober12820 state
|
||||
@param iv The IV data to add
|
||||
@param ivlen The length of the IV (must be 12)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int sober128_stream_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen)
|
||||
{
|
||||
ulong32 i, k;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(iv != NULL);
|
||||
LTC_ARGCHK(ivlen > 0);
|
||||
|
||||
/* ok we are adding an IV then... */
|
||||
s128_reloadstate(st);
|
||||
|
||||
/* ivlen must be multiple of 4 bytes */
|
||||
if ((ivlen & 3) != 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ivlen; i += 4) {
|
||||
k = BYTE2WORD(&iv[i]);
|
||||
ADDKEY(k);
|
||||
cycle(st->R);
|
||||
XORNL(nltap(st));
|
||||
}
|
||||
|
||||
/* also fold in the length of the key */
|
||||
ADDKEY(ivlen);
|
||||
|
||||
/* now diffuse */
|
||||
s128_diffuse(st);
|
||||
st->nbuf = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* XOR pseudo-random bytes into buffer
|
||||
*/
|
||||
#define SROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); XORWORD(t, in+(z*4), out+(z*4));
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128
|
||||
@param st The Sober128 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 sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
|
||||
{
|
||||
ulong32 t;
|
||||
|
||||
if (inlen == 0) return CRYPT_OK; /* nothing to do */
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(st != NULL);
|
||||
|
||||
/* handle any previously buffered bytes */
|
||||
while (st->nbuf != 0 && inlen != 0) {
|
||||
*out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF);
|
||||
st->sbuf >>= 8;
|
||||
st->nbuf -= 8;
|
||||
--inlen;
|
||||
}
|
||||
|
||||
#ifndef LTC_SMALL_CODE
|
||||
/* do lots at a time, if there's enough to do */
|
||||
while (inlen >= N*4) {
|
||||
SROUND(0);
|
||||
SROUND(1);
|
||||
SROUND(2);
|
||||
SROUND(3);
|
||||
SROUND(4);
|
||||
SROUND(5);
|
||||
SROUND(6);
|
||||
SROUND(7);
|
||||
SROUND(8);
|
||||
SROUND(9);
|
||||
SROUND(10);
|
||||
SROUND(11);
|
||||
SROUND(12);
|
||||
SROUND(13);
|
||||
SROUND(14);
|
||||
SROUND(15);
|
||||
SROUND(16);
|
||||
out += 4*N;
|
||||
in += 4*N;
|
||||
inlen -= 4*N;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* do small or odd size buffers the slow way */
|
||||
while (4 <= inlen) {
|
||||
cycle(st->R);
|
||||
t = nltap(st);
|
||||
XORWORD(t, in, out);
|
||||
out += 4;
|
||||
in += 4;
|
||||
inlen -= 4;
|
||||
}
|
||||
|
||||
/* handle any trailing bytes */
|
||||
if (inlen != 0) {
|
||||
cycle(st->R);
|
||||
st->sbuf = nltap(st);
|
||||
st->nbuf = 32;
|
||||
while (st->nbuf != 0 && inlen != 0) {
|
||||
*out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF);
|
||||
st->sbuf >>= 8;
|
||||
st->nbuf -= 8;
|
||||
--inlen;
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int sober128_stream_keystream(sober128_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 sober128_stream_crypt(st, out, outlen, out);
|
||||
}
|
||||
|
||||
/**
|
||||
Terminate and clear Sober128 state
|
||||
@param st The Sober128 state
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int sober128_stream_done(sober128_state *st)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
zeromem(st, sizeof(sober128_state));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#undef N
|
||||
#undef INITKONST
|
||||
#undef KEYP
|
||||
#undef FOLDP
|
||||
#undef OFF
|
||||
#undef STEP
|
||||
#undef NLFUNC
|
||||
#undef ADDKEY
|
||||
#undef XORNL
|
||||
#undef DROUND
|
||||
#undef SROUND
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SOBER128_STREAM
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with SOBER128
|
||||
@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 dataout [out] The ciphertext (or plaintext)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sober128_stream_memory(const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *iv, unsigned long ivlen,
|
||||
const unsigned char *datain, unsigned long datalen,
|
||||
unsigned char *dataout)
|
||||
{
|
||||
sober128_state st;
|
||||
int err;
|
||||
|
||||
if ((err = sober128_stream_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY;
|
||||
if ((err = sober128_stream_setiv(&st, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY;
|
||||
err = sober128_stream_crypt(&st, datain, datalen, dataout);
|
||||
WIPE_KEY:
|
||||
sober128_stream_done(&st);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_SOBER128_STREAM */
|
||||
@@ -0,0 +1,43 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SOBER128
|
||||
|
||||
int sober128_stream_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
unsigned char key[16] = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79,
|
||||
0x20, 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x73 };
|
||||
unsigned char iv[4] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
unsigned char out[20] = { 0x43, 0x50, 0x0c, 0xcf, 0x89, 0x91, 0x9f, 0x1d,
|
||||
0xaa, 0x37, 0x74, 0x95, 0xf4, 0xb4, 0x58, 0xc2,
|
||||
0x40, 0x37, 0x8b, 0xbb };
|
||||
int err, len = 20;
|
||||
unsigned char src[20], dst[20];
|
||||
sober128_state st;
|
||||
|
||||
XMEMSET(src, 0, len); /* input */
|
||||
if ((err = sober128_stream_setup(&st, key, sizeof(key))) != CRYPT_OK) return err;
|
||||
if ((err = sober128_stream_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
|
||||
if ((err = sober128_stream_crypt(&st, src, len, dst)) != CRYPT_OK) return err;
|
||||
if ((err = sober128_stream_done(&st)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(dst, len, out, len, "SOBER-128-TV1", 0)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* crypt in a single call */
|
||||
if ((err = sober128_stream_memory(key, sizeof(key), iv, sizeof(iv),
|
||||
src, len, dst)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(dst, len, out, len, "SOBER-128-TV2", 0)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
166
Sources/DataLiteC/libtomcrypt/stream/sober128/sober128tab.c
Normal file
166
Sources/DataLiteC/libtomcrypt/stream/sober128/sober128tab.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file sober128tab.c
|
||||
SOBER-128 Tables
|
||||
*/
|
||||
|
||||
#ifdef LTC_SOBER128TAB_C
|
||||
|
||||
/* $ID$ */
|
||||
/* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */
|
||||
/* Multiplication table for Turing using 0xD02B4367 */
|
||||
static const ulong32 Multab[256] = {
|
||||
0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9,
|
||||
0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478,
|
||||
0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746,
|
||||
0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697,
|
||||
0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A,
|
||||
0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB,
|
||||
0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5,
|
||||
0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04,
|
||||
0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2,
|
||||
0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613,
|
||||
0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D,
|
||||
0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC,
|
||||
0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51,
|
||||
0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80,
|
||||
0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE,
|
||||
0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F,
|
||||
0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F,
|
||||
0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE,
|
||||
0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90,
|
||||
0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41,
|
||||
0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC,
|
||||
0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D,
|
||||
0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703,
|
||||
0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2,
|
||||
0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14,
|
||||
0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5,
|
||||
0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB,
|
||||
0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A,
|
||||
0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787,
|
||||
0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656,
|
||||
0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568,
|
||||
0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9,
|
||||
0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748,
|
||||
0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699,
|
||||
0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7,
|
||||
0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476,
|
||||
0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB,
|
||||
0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A,
|
||||
0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34,
|
||||
0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5,
|
||||
0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523,
|
||||
0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2,
|
||||
0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC,
|
||||
0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D,
|
||||
0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0,
|
||||
0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61,
|
||||
0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F,
|
||||
0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E,
|
||||
0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E,
|
||||
0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F,
|
||||
0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71,
|
||||
0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0,
|
||||
0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D,
|
||||
0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC,
|
||||
0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2,
|
||||
0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433,
|
||||
0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5,
|
||||
0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24,
|
||||
0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A,
|
||||
0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB,
|
||||
0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566,
|
||||
0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7,
|
||||
0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789,
|
||||
0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658,
|
||||
};
|
||||
|
||||
/* $ID$ */
|
||||
/* Sbox for SOBER-128 */
|
||||
/*
|
||||
* This is really the combination of two SBoxes; the least significant
|
||||
* 24 bits comes from:
|
||||
* 8->32 Sbox generated by Millan et. al. at Queensland University of
|
||||
* Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter,
|
||||
* "On the Design of 8*32 S-boxes". Unpublished report, by the
|
||||
* Information Systems Research Centre,
|
||||
* Queensland University of Technology, 1999.
|
||||
*
|
||||
* The most significant 8 bits are the Skipjack "F table", which can be
|
||||
* found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf .
|
||||
* In this optimised table, though, the intent is to XOR the word from
|
||||
* the table selected by the high byte with the input word. Thus, the
|
||||
* high byte is actually the Skipjack F-table entry XORED with its
|
||||
* table index.
|
||||
*/
|
||||
static const ulong32 Sbox[256] = {
|
||||
0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4,
|
||||
0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae,
|
||||
0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c,
|
||||
0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35,
|
||||
0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e,
|
||||
0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b,
|
||||
0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f,
|
||||
0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1,
|
||||
0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd,
|
||||
0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3,
|
||||
0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f,
|
||||
0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36,
|
||||
0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf,
|
||||
0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816,
|
||||
0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d,
|
||||
0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af,
|
||||
0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6,
|
||||
0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418,
|
||||
0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0,
|
||||
0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd,
|
||||
0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088,
|
||||
0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759,
|
||||
0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895,
|
||||
0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66,
|
||||
0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc,
|
||||
0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1,
|
||||
0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911,
|
||||
0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e,
|
||||
0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515,
|
||||
0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133,
|
||||
0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226,
|
||||
0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084,
|
||||
0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb,
|
||||
0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184,
|
||||
0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420,
|
||||
0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02,
|
||||
0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655,
|
||||
0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c,
|
||||
0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418,
|
||||
0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473,
|
||||
0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a,
|
||||
0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0,
|
||||
0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21,
|
||||
0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36,
|
||||
0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5,
|
||||
0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6,
|
||||
0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0,
|
||||
0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795,
|
||||
0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0,
|
||||
0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78,
|
||||
0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da,
|
||||
0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a,
|
||||
0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118,
|
||||
0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed,
|
||||
0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd,
|
||||
0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b,
|
||||
0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921,
|
||||
0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e,
|
||||
0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5,
|
||||
0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8,
|
||||
0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376,
|
||||
0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a,
|
||||
0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8,
|
||||
0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40,
|
||||
};
|
||||
|
||||
#endif /* LTC_SOBER128TAB_C */
|
||||
813
Sources/DataLiteC/libtomcrypt/stream/sosemanuk/sosemanuk.c
Normal file
813
Sources/DataLiteC/libtomcrypt/stream/sosemanuk/sosemanuk.c
Normal file
@@ -0,0 +1,813 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/*
|
||||
* This LTC implementation was adapted from:
|
||||
* http://www.ecrypt.eu.org/stream/e2-sosemanuk.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* SOSEMANUK reference implementation.
|
||||
*
|
||||
* This code is supposed to run on any conforming C implementation (C90
|
||||
* or later).
|
||||
*
|
||||
* (c) 2005 X-CRYPT project. This software is provided 'as-is', without
|
||||
* any express or implied warranty. In no event will the authors be held
|
||||
* liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to no restriction.
|
||||
*
|
||||
* Technical remarks and questions can be addressed to
|
||||
* <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_SOSEMANUK
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
/*
|
||||
* We want (and sometimes need) to perform explicit truncations to 32 bits.
|
||||
*/
|
||||
#define T32(x) ((x) & (ulong32)0xFFFFFFFF)
|
||||
|
||||
/*
|
||||
* Some of our functions will be tagged as "inline" to help the compiler
|
||||
* optimize things. We use "inline" only if the compiler is advanced
|
||||
* enough to understand it; C99 compilers, and pre-C99 versions of gcc,
|
||||
* understand enough "inline" for our purposes.
|
||||
*/
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
/*
|
||||
* Serpent S-boxes, implemented in bitslice mode. These circuits have
|
||||
* been published by Dag Arne Osvik ("Speeding up Serpent", published in
|
||||
* the 3rd AES Candidate Conference) and work on five 32-bit registers:
|
||||
* the four inputs, and a fifth scratch register. There are meant to be
|
||||
* quite fast on Pentium-class processors. These are not the fastest
|
||||
* published, but they are "fast enough" and they are unencumbered as
|
||||
* far as intellectual property is concerned (note: these are rewritten
|
||||
* from the article itself, and hence are not covered by the GPL on
|
||||
* Dag's code, which was not used here).
|
||||
*
|
||||
* The output bits are permuted. Here is the correspondance:
|
||||
* S0: 1420
|
||||
* S1: 2031
|
||||
* S2: 2314
|
||||
* S3: 1234
|
||||
* S4: 1403
|
||||
* S5: 1302
|
||||
* S6: 0142
|
||||
* S7: 4310
|
||||
* (for instance, the output of S0 is in "r1, r4, r2, r0").
|
||||
*/
|
||||
|
||||
#define S0(r0, r1, r2, r3, r4) do { \
|
||||
r3 ^= r0; r4 = r1; \
|
||||
r1 &= r3; r4 ^= r2; \
|
||||
r1 ^= r0; r0 |= r3; \
|
||||
r0 ^= r4; r4 ^= r3; \
|
||||
r3 ^= r2; r2 |= r1; \
|
||||
r2 ^= r4; r4 = ~r4; \
|
||||
r4 |= r1; r1 ^= r3; \
|
||||
r1 ^= r4; r3 |= r0; \
|
||||
r1 ^= r3; r4 ^= r3; \
|
||||
} while (0)
|
||||
|
||||
#define S1(r0, r1, r2, r3, r4) do { \
|
||||
r0 = ~r0; r2 = ~r2; \
|
||||
r4 = r0; r0 &= r1; \
|
||||
r2 ^= r0; r0 |= r3; \
|
||||
r3 ^= r2; r1 ^= r0; \
|
||||
r0 ^= r4; r4 |= r1; \
|
||||
r1 ^= r3; r2 |= r0; \
|
||||
r2 &= r4; r0 ^= r1; \
|
||||
r1 &= r2; \
|
||||
r1 ^= r0; r0 &= r2; \
|
||||
r0 ^= r4; \
|
||||
} while (0)
|
||||
|
||||
#define S2(r0, r1, r2, r3, r4) do { \
|
||||
r4 = r0; r0 &= r2; \
|
||||
r0 ^= r3; r2 ^= r1; \
|
||||
r2 ^= r0; r3 |= r4; \
|
||||
r3 ^= r1; r4 ^= r2; \
|
||||
r1 = r3; r3 |= r4; \
|
||||
r3 ^= r0; r0 &= r1; \
|
||||
r4 ^= r0; r1 ^= r3; \
|
||||
r1 ^= r4; r4 = ~r4; \
|
||||
} while (0)
|
||||
|
||||
#define S3(r0, r1, r2, r3, r4) do { \
|
||||
r4 = r0; r0 |= r3; \
|
||||
r3 ^= r1; r1 &= r4; \
|
||||
r4 ^= r2; r2 ^= r3; \
|
||||
r3 &= r0; r4 |= r1; \
|
||||
r3 ^= r4; r0 ^= r1; \
|
||||
r4 &= r0; r1 ^= r3; \
|
||||
r4 ^= r2; r1 |= r0; \
|
||||
r1 ^= r2; r0 ^= r3; \
|
||||
r2 = r1; r1 |= r3; \
|
||||
r1 ^= r0; \
|
||||
} while (0)
|
||||
|
||||
#define S4(r0, r1, r2, r3, r4) do { \
|
||||
r1 ^= r3; r3 = ~r3; \
|
||||
r2 ^= r3; r3 ^= r0; \
|
||||
r4 = r1; r1 &= r3; \
|
||||
r1 ^= r2; r4 ^= r3; \
|
||||
r0 ^= r4; r2 &= r4; \
|
||||
r2 ^= r0; r0 &= r1; \
|
||||
r3 ^= r0; r4 |= r1; \
|
||||
r4 ^= r0; r0 |= r3; \
|
||||
r0 ^= r2; r2 &= r3; \
|
||||
r0 = ~r0; r4 ^= r2; \
|
||||
} while (0)
|
||||
|
||||
#define S5(r0, r1, r2, r3, r4) do { \
|
||||
r0 ^= r1; r1 ^= r3; \
|
||||
r3 = ~r3; r4 = r1; \
|
||||
r1 &= r0; r2 ^= r3; \
|
||||
r1 ^= r2; r2 |= r4; \
|
||||
r4 ^= r3; r3 &= r1; \
|
||||
r3 ^= r0; r4 ^= r1; \
|
||||
r4 ^= r2; r2 ^= r0; \
|
||||
r0 &= r3; r2 = ~r2; \
|
||||
r0 ^= r4; r4 |= r3; \
|
||||
r2 ^= r4; \
|
||||
} while (0)
|
||||
|
||||
#define S6(r0, r1, r2, r3, r4) do { \
|
||||
r2 = ~r2; r4 = r3; \
|
||||
r3 &= r0; r0 ^= r4; \
|
||||
r3 ^= r2; r2 |= r4; \
|
||||
r1 ^= r3; r2 ^= r0; \
|
||||
r0 |= r1; r2 ^= r1; \
|
||||
r4 ^= r0; r0 |= r3; \
|
||||
r0 ^= r2; r4 ^= r3; \
|
||||
r4 ^= r0; r3 = ~r3; \
|
||||
r2 &= r4; \
|
||||
r2 ^= r3; \
|
||||
} while (0)
|
||||
|
||||
#define S7(r0, r1, r2, r3, r4) do { \
|
||||
r4 = r1; r1 |= r2; \
|
||||
r1 ^= r3; r4 ^= r2; \
|
||||
r2 ^= r1; r3 |= r4; \
|
||||
r3 &= r0; r4 ^= r2; \
|
||||
r3 ^= r1; r1 |= r4; \
|
||||
r1 ^= r0; r0 |= r4; \
|
||||
r0 ^= r2; r1 ^= r4; \
|
||||
r2 ^= r1; r1 &= r0; \
|
||||
r1 ^= r4; r2 = ~r2; \
|
||||
r2 |= r0; \
|
||||
r4 ^= r2; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* The Serpent linear transform.
|
||||
*/
|
||||
#define SERPENT_LT(x0, x1, x2, x3) do { \
|
||||
x0 = ROLc(x0, 13); \
|
||||
x2 = ROLc(x2, 3); \
|
||||
x1 = x1 ^ x0 ^ x2; \
|
||||
x3 = x3 ^ x2 ^ T32(x0 << 3); \
|
||||
x1 = ROLc(x1, 1); \
|
||||
x3 = ROLc(x3, 7); \
|
||||
x0 = x0 ^ x1 ^ x3; \
|
||||
x2 = x2 ^ x3 ^ T32(x1 << 7); \
|
||||
x0 = ROLc(x0, 5); \
|
||||
x2 = ROLc(x2, 22); \
|
||||
} while (0)
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
/*
|
||||
* Initialize Sosemanuk's state by providing a key. The key is an array of
|
||||
* 1 to 32 bytes.
|
||||
* @param st The Sosemanuk state
|
||||
* @param key Key
|
||||
* @param keylen Length of key in bytes
|
||||
* @return CRYPT_OK on success
|
||||
*/
|
||||
int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
/*
|
||||
* This key schedule is actually a truncated Serpent key schedule.
|
||||
* The key-derived words (w_i) are computed within the eight
|
||||
* local variables w0 to w7, which are reused again and again.
|
||||
*/
|
||||
|
||||
#define SKS(S, o0, o1, o2, o3, d0, d1, d2, d3) do { \
|
||||
ulong32 r0, r1, r2, r3, r4; \
|
||||
r0 = w ## o0; \
|
||||
r1 = w ## o1; \
|
||||
r2 = w ## o2; \
|
||||
r3 = w ## o3; \
|
||||
S(r0, r1, r2, r3, r4); \
|
||||
st->kc[i ++] = r ## d0; \
|
||||
st->kc[i ++] = r ## d1; \
|
||||
st->kc[i ++] = r ## d2; \
|
||||
st->kc[i ++] = r ## d3; \
|
||||
} while (0)
|
||||
|
||||
#define SKS0 SKS(S0, 4, 5, 6, 7, 1, 4, 2, 0)
|
||||
#define SKS1 SKS(S1, 0, 1, 2, 3, 2, 0, 3, 1)
|
||||
#define SKS2 SKS(S2, 4, 5, 6, 7, 2, 3, 1, 4)
|
||||
#define SKS3 SKS(S3, 0, 1, 2, 3, 1, 2, 3, 4)
|
||||
#define SKS4 SKS(S4, 4, 5, 6, 7, 1, 4, 0, 3)
|
||||
#define SKS5 SKS(S5, 0, 1, 2, 3, 1, 3, 0, 2)
|
||||
#define SKS6 SKS(S6, 4, 5, 6, 7, 0, 1, 4, 2)
|
||||
#define SKS7 SKS(S7, 0, 1, 2, 3, 4, 3, 1, 0)
|
||||
|
||||
#define WUP(wi, wi5, wi3, wi1, cc) do { \
|
||||
ulong32 tt = (wi) ^ (wi5) ^ (wi3) \
|
||||
^ (wi1) ^ (0x9E3779B9 ^ (ulong32)(cc)); \
|
||||
(wi) = ROLc(tt, 11); \
|
||||
} while (0)
|
||||
|
||||
#define WUP0(cc) do { \
|
||||
WUP(w0, w3, w5, w7, cc); \
|
||||
WUP(w1, w4, w6, w0, cc + 1); \
|
||||
WUP(w2, w5, w7, w1, cc + 2); \
|
||||
WUP(w3, w6, w0, w2, cc + 3); \
|
||||
} while (0)
|
||||
|
||||
#define WUP1(cc) do { \
|
||||
WUP(w4, w7, w1, w3, cc); \
|
||||
WUP(w5, w0, w2, w4, cc + 1); \
|
||||
WUP(w6, w1, w3, w5, cc + 2); \
|
||||
WUP(w7, w2, w4, w6, cc + 3); \
|
||||
} while (0)
|
||||
|
||||
unsigned char wbuf[32];
|
||||
ulong32 w0, w1, w2, w3, w4, w5, w6, w7;
|
||||
int i = 0;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(keylen > 0 && keylen <= 32);
|
||||
|
||||
/*
|
||||
* The key is copied into the wbuf[] buffer and padded to 256 bits
|
||||
* as described in the Serpent specification.
|
||||
*/
|
||||
XMEMCPY(wbuf, key, keylen);
|
||||
if (keylen < 32) {
|
||||
wbuf[keylen] = 0x01;
|
||||
if (keylen < 31) {
|
||||
XMEMSET(wbuf + keylen + 1, 0, 31 - keylen);
|
||||
}
|
||||
}
|
||||
|
||||
LOAD32L(w0, wbuf);
|
||||
LOAD32L(w1, wbuf + 4);
|
||||
LOAD32L(w2, wbuf + 8);
|
||||
LOAD32L(w3, wbuf + 12);
|
||||
LOAD32L(w4, wbuf + 16);
|
||||
LOAD32L(w5, wbuf + 20);
|
||||
LOAD32L(w6, wbuf + 24);
|
||||
LOAD32L(w7, wbuf + 28);
|
||||
|
||||
WUP0(0); SKS3;
|
||||
WUP1(4); SKS2;
|
||||
WUP0(8); SKS1;
|
||||
WUP1(12); SKS0;
|
||||
WUP0(16); SKS7;
|
||||
WUP1(20); SKS6;
|
||||
WUP0(24); SKS5;
|
||||
WUP1(28); SKS4;
|
||||
WUP0(32); SKS3;
|
||||
WUP1(36); SKS2;
|
||||
WUP0(40); SKS1;
|
||||
WUP1(44); SKS0;
|
||||
WUP0(48); SKS7;
|
||||
WUP1(52); SKS6;
|
||||
WUP0(56); SKS5;
|
||||
WUP1(60); SKS4;
|
||||
WUP0(64); SKS3;
|
||||
WUP1(68); SKS2;
|
||||
WUP0(72); SKS1;
|
||||
WUP1(76); SKS0;
|
||||
WUP0(80); SKS7;
|
||||
WUP1(84); SKS6;
|
||||
WUP0(88); SKS5;
|
||||
WUP1(92); SKS4;
|
||||
WUP0(96); SKS3;
|
||||
|
||||
#undef SKS
|
||||
#undef SKS0
|
||||
#undef SKS1
|
||||
#undef SKS2
|
||||
#undef SKS3
|
||||
#undef SKS4
|
||||
#undef SKS5
|
||||
#undef SKS6
|
||||
#undef SKS7
|
||||
#undef WUP
|
||||
#undef WUP0
|
||||
#undef WUP1
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialization continues by setting the IV. The IV length is up to 16 bytes.
|
||||
* If "ivlen" is 0 (no IV), then the "iv" parameter can be NULL. If multiple
|
||||
* encryptions/decryptions are to be performed with the same key and
|
||||
* sosemanuk_done() has not been called, only sosemanuk_setiv() need be called
|
||||
* to set the state.
|
||||
* @param st The Sosemanuk state
|
||||
* @param iv Initialization vector
|
||||
* @param ivlen Length of iv in bytes
|
||||
* @return CRYPT_OK on success
|
||||
*/
|
||||
int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen)
|
||||
{
|
||||
|
||||
/*
|
||||
* The Serpent key addition step.
|
||||
*/
|
||||
#define KA(zc, x0, x1, x2, x3) do { \
|
||||
x0 ^= st->kc[(zc)]; \
|
||||
x1 ^= st->kc[(zc) + 1]; \
|
||||
x2 ^= st->kc[(zc) + 2]; \
|
||||
x3 ^= st->kc[(zc) + 3]; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* One Serpent round.
|
||||
* zc = current subkey counter
|
||||
* S = S-box macro for this round
|
||||
* i0 to i4 = input register numbers (the fifth is a scratch register)
|
||||
* o0 to o3 = output register numbers
|
||||
*/
|
||||
#define FSS(zc, S, i0, i1, i2, i3, i4, o0, o1, o2, o3) do { \
|
||||
KA(zc, r ## i0, r ## i1, r ## i2, r ## i3); \
|
||||
S(r ## i0, r ## i1, r ## i2, r ## i3, r ## i4); \
|
||||
SERPENT_LT(r ## o0, r ## o1, r ## o2, r ## o3); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Last Serpent round. Contrary to the "true" Serpent, we keep
|
||||
* the linear transformation for that last round.
|
||||
*/
|
||||
#define FSF(zc, S, i0, i1, i2, i3, i4, o0, o1, o2, o3) do { \
|
||||
KA(zc, r ## i0, r ## i1, r ## i2, r ## i3); \
|
||||
S(r ## i0, r ## i1, r ## i2, r ## i3, r ## i4); \
|
||||
SERPENT_LT(r ## o0, r ## o1, r ## o2, r ## o3); \
|
||||
KA(zc + 4, r ## o0, r ## o1, r ## o2, r ## o3); \
|
||||
} while (0)
|
||||
|
||||
ulong32 r0, r1, r2, r3, r4;
|
||||
unsigned char ivtmp[16] = {0};
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(ivlen <= 16);
|
||||
LTC_ARGCHK(iv != NULL || ivlen == 0);
|
||||
|
||||
if (ivlen > 0) XMEMCPY(ivtmp, iv, ivlen);
|
||||
|
||||
/*
|
||||
* Decode IV into four 32-bit words (little-endian).
|
||||
*/
|
||||
LOAD32L(r0, ivtmp);
|
||||
LOAD32L(r1, ivtmp + 4);
|
||||
LOAD32L(r2, ivtmp + 8);
|
||||
LOAD32L(r3, ivtmp + 12);
|
||||
|
||||
/*
|
||||
* Encrypt IV with Serpent24. Some values are extracted from the
|
||||
* output of the twelfth, eighteenth and twenty-fourth rounds.
|
||||
*/
|
||||
FSS(0, S0, 0, 1, 2, 3, 4, 1, 4, 2, 0);
|
||||
FSS(4, S1, 1, 4, 2, 0, 3, 2, 1, 0, 4);
|
||||
FSS(8, S2, 2, 1, 0, 4, 3, 0, 4, 1, 3);
|
||||
FSS(12, S3, 0, 4, 1, 3, 2, 4, 1, 3, 2);
|
||||
FSS(16, S4, 4, 1, 3, 2, 0, 1, 0, 4, 2);
|
||||
FSS(20, S5, 1, 0, 4, 2, 3, 0, 2, 1, 4);
|
||||
FSS(24, S6, 0, 2, 1, 4, 3, 0, 2, 3, 1);
|
||||
FSS(28, S7, 0, 2, 3, 1, 4, 4, 1, 2, 0);
|
||||
FSS(32, S0, 4, 1, 2, 0, 3, 1, 3, 2, 4);
|
||||
FSS(36, S1, 1, 3, 2, 4, 0, 2, 1, 4, 3);
|
||||
FSS(40, S2, 2, 1, 4, 3, 0, 4, 3, 1, 0);
|
||||
FSS(44, S3, 4, 3, 1, 0, 2, 3, 1, 0, 2);
|
||||
st->s09 = r3;
|
||||
st->s08 = r1;
|
||||
st->s07 = r0;
|
||||
st->s06 = r2;
|
||||
|
||||
FSS(48, S4, 3, 1, 0, 2, 4, 1, 4, 3, 2);
|
||||
FSS(52, S5, 1, 4, 3, 2, 0, 4, 2, 1, 3);
|
||||
FSS(56, S6, 4, 2, 1, 3, 0, 4, 2, 0, 1);
|
||||
FSS(60, S7, 4, 2, 0, 1, 3, 3, 1, 2, 4);
|
||||
FSS(64, S0, 3, 1, 2, 4, 0, 1, 0, 2, 3);
|
||||
FSS(68, S1, 1, 0, 2, 3, 4, 2, 1, 3, 0);
|
||||
st->r1 = r2;
|
||||
st->s04 = r1;
|
||||
st->r2 = r3;
|
||||
st->s05 = r0;
|
||||
|
||||
FSS(72, S2, 2, 1, 3, 0, 4, 3, 0, 1, 4);
|
||||
FSS(76, S3, 3, 0, 1, 4, 2, 0, 1, 4, 2);
|
||||
FSS(80, S4, 0, 1, 4, 2, 3, 1, 3, 0, 2);
|
||||
FSS(84, S5, 1, 3, 0, 2, 4, 3, 2, 1, 0);
|
||||
FSS(88, S6, 3, 2, 1, 0, 4, 3, 2, 4, 1);
|
||||
FSF(92, S7, 3, 2, 4, 1, 0, 0, 1, 2, 3);
|
||||
st->s03 = r0;
|
||||
st->s02 = r1;
|
||||
st->s01 = r2;
|
||||
st->s00 = r3;
|
||||
|
||||
st->ptr = sizeof(st->buf);
|
||||
|
||||
#undef KA
|
||||
#undef FSS
|
||||
#undef FSF
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication by alpha: alpha * x = T32(x << 8) ^ mul_a[x >> 24]
|
||||
*/
|
||||
static const ulong32 mul_a[] = {
|
||||
0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835,
|
||||
0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679,
|
||||
0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD,
|
||||
0xD320B2D4, 0x32BF7DC7, 0xB8B785F2, 0x59284AE1,
|
||||
0x0AE71199, 0xEB78DE8A, 0x617026BF, 0x80EFE9AC,
|
||||
0xDC607FD5, 0x3DFFB0C6, 0xB7F748F3, 0x566887E0,
|
||||
0x0F40CD01, 0xEEDF0212, 0x64D7FA27, 0x85483534,
|
||||
0xD9C7A34D, 0x38586C5E, 0xB250946B, 0x53CF5B78,
|
||||
0x1467229B, 0xF5F8ED88, 0x7FF015BD, 0x9E6FDAAE,
|
||||
0xC2E04CD7, 0x237F83C4, 0xA9777BF1, 0x48E8B4E2,
|
||||
0x11C0FE03, 0xF05F3110, 0x7A57C925, 0x9BC80636,
|
||||
0xC747904F, 0x26D85F5C, 0xACD0A769, 0x4D4F687A,
|
||||
0x1E803302, 0xFF1FFC11, 0x75170424, 0x9488CB37,
|
||||
0xC8075D4E, 0x2998925D, 0xA3906A68, 0x420FA57B,
|
||||
0x1B27EF9A, 0xFAB82089, 0x70B0D8BC, 0x912F17AF,
|
||||
0xCDA081D6, 0x2C3F4EC5, 0xA637B6F0, 0x47A879E3,
|
||||
0x28CE449F, 0xC9518B8C, 0x435973B9, 0xA2C6BCAA,
|
||||
0xFE492AD3, 0x1FD6E5C0, 0x95DE1DF5, 0x7441D2E6,
|
||||
0x2D699807, 0xCCF65714, 0x46FEAF21, 0xA7616032,
|
||||
0xFBEEF64B, 0x1A713958, 0x9079C16D, 0x71E60E7E,
|
||||
0x22295506, 0xC3B69A15, 0x49BE6220, 0xA821AD33,
|
||||
0xF4AE3B4A, 0x1531F459, 0x9F390C6C, 0x7EA6C37F,
|
||||
0x278E899E, 0xC611468D, 0x4C19BEB8, 0xAD8671AB,
|
||||
0xF109E7D2, 0x109628C1, 0x9A9ED0F4, 0x7B011FE7,
|
||||
0x3CA96604, 0xDD36A917, 0x573E5122, 0xB6A19E31,
|
||||
0xEA2E0848, 0x0BB1C75B, 0x81B93F6E, 0x6026F07D,
|
||||
0x390EBA9C, 0xD891758F, 0x52998DBA, 0xB30642A9,
|
||||
0xEF89D4D0, 0x0E161BC3, 0x841EE3F6, 0x65812CE5,
|
||||
0x364E779D, 0xD7D1B88E, 0x5DD940BB, 0xBC468FA8,
|
||||
0xE0C919D1, 0x0156D6C2, 0x8B5E2EF7, 0x6AC1E1E4,
|
||||
0x33E9AB05, 0xD2766416, 0x587E9C23, 0xB9E15330,
|
||||
0xE56EC549, 0x04F10A5A, 0x8EF9F26F, 0x6F663D7C,
|
||||
0x50358897, 0xB1AA4784, 0x3BA2BFB1, 0xDA3D70A2,
|
||||
0x86B2E6DB, 0x672D29C8, 0xED25D1FD, 0x0CBA1EEE,
|
||||
0x5592540F, 0xB40D9B1C, 0x3E056329, 0xDF9AAC3A,
|
||||
0x83153A43, 0x628AF550, 0xE8820D65, 0x091DC276,
|
||||
0x5AD2990E, 0xBB4D561D, 0x3145AE28, 0xD0DA613B,
|
||||
0x8C55F742, 0x6DCA3851, 0xE7C2C064, 0x065D0F77,
|
||||
0x5F754596, 0xBEEA8A85, 0x34E272B0, 0xD57DBDA3,
|
||||
0x89F22BDA, 0x686DE4C9, 0xE2651CFC, 0x03FAD3EF,
|
||||
0x4452AA0C, 0xA5CD651F, 0x2FC59D2A, 0xCE5A5239,
|
||||
0x92D5C440, 0x734A0B53, 0xF942F366, 0x18DD3C75,
|
||||
0x41F57694, 0xA06AB987, 0x2A6241B2, 0xCBFD8EA1,
|
||||
0x977218D8, 0x76EDD7CB, 0xFCE52FFE, 0x1D7AE0ED,
|
||||
0x4EB5BB95, 0xAF2A7486, 0x25228CB3, 0xC4BD43A0,
|
||||
0x9832D5D9, 0x79AD1ACA, 0xF3A5E2FF, 0x123A2DEC,
|
||||
0x4B12670D, 0xAA8DA81E, 0x2085502B, 0xC11A9F38,
|
||||
0x9D950941, 0x7C0AC652, 0xF6023E67, 0x179DF174,
|
||||
0x78FBCC08, 0x9964031B, 0x136CFB2E, 0xF2F3343D,
|
||||
0xAE7CA244, 0x4FE36D57, 0xC5EB9562, 0x24745A71,
|
||||
0x7D5C1090, 0x9CC3DF83, 0x16CB27B6, 0xF754E8A5,
|
||||
0xABDB7EDC, 0x4A44B1CF, 0xC04C49FA, 0x21D386E9,
|
||||
0x721CDD91, 0x93831282, 0x198BEAB7, 0xF81425A4,
|
||||
0xA49BB3DD, 0x45047CCE, 0xCF0C84FB, 0x2E934BE8,
|
||||
0x77BB0109, 0x9624CE1A, 0x1C2C362F, 0xFDB3F93C,
|
||||
0xA13C6F45, 0x40A3A056, 0xCAAB5863, 0x2B349770,
|
||||
0x6C9CEE93, 0x8D032180, 0x070BD9B5, 0xE69416A6,
|
||||
0xBA1B80DF, 0x5B844FCC, 0xD18CB7F9, 0x301378EA,
|
||||
0x693B320B, 0x88A4FD18, 0x02AC052D, 0xE333CA3E,
|
||||
0xBFBC5C47, 0x5E239354, 0xD42B6B61, 0x35B4A472,
|
||||
0x667BFF0A, 0x87E43019, 0x0DECC82C, 0xEC73073F,
|
||||
0xB0FC9146, 0x51635E55, 0xDB6BA660, 0x3AF46973,
|
||||
0x63DC2392, 0x8243EC81, 0x084B14B4, 0xE9D4DBA7,
|
||||
0xB55B4DDE, 0x54C482CD, 0xDECC7AF8, 0x3F53B5EB
|
||||
};
|
||||
|
||||
/*
|
||||
* Multiplication by 1/alpha: 1/alpha * x = (x >> 8) ^ mul_ia[x & 0xFF]
|
||||
*/
|
||||
static const ulong32 mul_ia[] = {
|
||||
0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE,
|
||||
0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998,
|
||||
0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32,
|
||||
0xA04452AA, 0xB84B1267, 0x905AD299, 0x88559254,
|
||||
0x29F05F31, 0x31FF1FFC, 0x19EEDF02, 0x01E19FCF,
|
||||
0x49CCF657, 0x51C3B69A, 0x79D27664, 0x61DD36A9,
|
||||
0xE988A4FD, 0xF187E430, 0xD99624CE, 0xC1996403,
|
||||
0x89B40D9B, 0x91BB4D56, 0xB9AA8DA8, 0xA1A5CD65,
|
||||
0x5249BE62, 0x4A46FEAF, 0x62573E51, 0x7A587E9C,
|
||||
0x32751704, 0x2A7A57C9, 0x026B9737, 0x1A64D7FA,
|
||||
0x923145AE, 0x8A3E0563, 0xA22FC59D, 0xBA208550,
|
||||
0xF20DECC8, 0xEA02AC05, 0xC2136CFB, 0xDA1C2C36,
|
||||
0x7BB9E153, 0x63B6A19E, 0x4BA76160, 0x53A821AD,
|
||||
0x1B854835, 0x038A08F8, 0x2B9BC806, 0x339488CB,
|
||||
0xBBC11A9F, 0xA3CE5A52, 0x8BDF9AAC, 0x93D0DA61,
|
||||
0xDBFDB3F9, 0xC3F2F334, 0xEBE333CA, 0xF3EC7307,
|
||||
0xA492D5C4, 0xBC9D9509, 0x948C55F7, 0x8C83153A,
|
||||
0xC4AE7CA2, 0xDCA13C6F, 0xF4B0FC91, 0xECBFBC5C,
|
||||
0x64EA2E08, 0x7CE56EC5, 0x54F4AE3B, 0x4CFBEEF6,
|
||||
0x04D6876E, 0x1CD9C7A3, 0x34C8075D, 0x2CC74790,
|
||||
0x8D628AF5, 0x956DCA38, 0xBD7C0AC6, 0xA5734A0B,
|
||||
0xED5E2393, 0xF551635E, 0xDD40A3A0, 0xC54FE36D,
|
||||
0x4D1A7139, 0x551531F4, 0x7D04F10A, 0x650BB1C7,
|
||||
0x2D26D85F, 0x35299892, 0x1D38586C, 0x053718A1,
|
||||
0xF6DB6BA6, 0xEED42B6B, 0xC6C5EB95, 0xDECAAB58,
|
||||
0x96E7C2C0, 0x8EE8820D, 0xA6F942F3, 0xBEF6023E,
|
||||
0x36A3906A, 0x2EACD0A7, 0x06BD1059, 0x1EB25094,
|
||||
0x569F390C, 0x4E9079C1, 0x6681B93F, 0x7E8EF9F2,
|
||||
0xDF2B3497, 0xC724745A, 0xEF35B4A4, 0xF73AF469,
|
||||
0xBF179DF1, 0xA718DD3C, 0x8F091DC2, 0x97065D0F,
|
||||
0x1F53CF5B, 0x075C8F96, 0x2F4D4F68, 0x37420FA5,
|
||||
0x7F6F663D, 0x676026F0, 0x4F71E60E, 0x577EA6C3,
|
||||
0xE18D0321, 0xF98243EC, 0xD1938312, 0xC99CC3DF,
|
||||
0x81B1AA47, 0x99BEEA8A, 0xB1AF2A74, 0xA9A06AB9,
|
||||
0x21F5F8ED, 0x39FAB820, 0x11EB78DE, 0x09E43813,
|
||||
0x41C9518B, 0x59C61146, 0x71D7D1B8, 0x69D89175,
|
||||
0xC87D5C10, 0xD0721CDD, 0xF863DC23, 0xE06C9CEE,
|
||||
0xA841F576, 0xB04EB5BB, 0x985F7545, 0x80503588,
|
||||
0x0805A7DC, 0x100AE711, 0x381B27EF, 0x20146722,
|
||||
0x68390EBA, 0x70364E77, 0x58278E89, 0x4028CE44,
|
||||
0xB3C4BD43, 0xABCBFD8E, 0x83DA3D70, 0x9BD57DBD,
|
||||
0xD3F81425, 0xCBF754E8, 0xE3E69416, 0xFBE9D4DB,
|
||||
0x73BC468F, 0x6BB30642, 0x43A2C6BC, 0x5BAD8671,
|
||||
0x1380EFE9, 0x0B8FAF24, 0x239E6FDA, 0x3B912F17,
|
||||
0x9A34E272, 0x823BA2BF, 0xAA2A6241, 0xB225228C,
|
||||
0xFA084B14, 0xE2070BD9, 0xCA16CB27, 0xD2198BEA,
|
||||
0x5A4C19BE, 0x42435973, 0x6A52998D, 0x725DD940,
|
||||
0x3A70B0D8, 0x227FF015, 0x0A6E30EB, 0x12617026,
|
||||
0x451FD6E5, 0x5D109628, 0x750156D6, 0x6D0E161B,
|
||||
0x25237F83, 0x3D2C3F4E, 0x153DFFB0, 0x0D32BF7D,
|
||||
0x85672D29, 0x9D686DE4, 0xB579AD1A, 0xAD76EDD7,
|
||||
0xE55B844F, 0xFD54C482, 0xD545047C, 0xCD4A44B1,
|
||||
0x6CEF89D4, 0x74E0C919, 0x5CF109E7, 0x44FE492A,
|
||||
0x0CD320B2, 0x14DC607F, 0x3CCDA081, 0x24C2E04C,
|
||||
0xAC977218, 0xB49832D5, 0x9C89F22B, 0x8486B2E6,
|
||||
0xCCABDB7E, 0xD4A49BB3, 0xFCB55B4D, 0xE4BA1B80,
|
||||
0x17566887, 0x0F59284A, 0x2748E8B4, 0x3F47A879,
|
||||
0x776AC1E1, 0x6F65812C, 0x477441D2, 0x5F7B011F,
|
||||
0xD72E934B, 0xCF21D386, 0xE7301378, 0xFF3F53B5,
|
||||
0xB7123A2D, 0xAF1D7AE0, 0x870CBA1E, 0x9F03FAD3,
|
||||
0x3EA637B6, 0x26A9777B, 0x0EB8B785, 0x16B7F748,
|
||||
0x5E9A9ED0, 0x4695DE1D, 0x6E841EE3, 0x768B5E2E,
|
||||
0xFEDECC7A, 0xE6D18CB7, 0xCEC04C49, 0xD6CF0C84,
|
||||
0x9EE2651C, 0x86ED25D1, 0xAEFCE52F, 0xB6F3A5E2
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Compute the next block of bits of output stream. This is equivalent
|
||||
* to one full rotation of the shift register.
|
||||
*/
|
||||
static LTC_INLINE void s_sosemanuk_internal(sosemanuk_state *st)
|
||||
{
|
||||
/*
|
||||
* MUL_A(x) computes alpha * x (in F_{2^32}).
|
||||
* MUL_G(x) computes 1/alpha * x (in F_{2^32}).
|
||||
*/
|
||||
#define MUL_A(x) (T32((x) << 8) ^ mul_a[(x) >> 24])
|
||||
#define MUL_G(x) (((x) >> 8) ^ mul_ia[(x) & 0xFF])
|
||||
|
||||
/*
|
||||
* This macro computes the special multiplexer, which chooses
|
||||
* between "x" and "x xor y", depending on the least significant
|
||||
* bit of the control word. We use the C "?:" selection operator
|
||||
* (which most compilers know how to optimise) except for Alpha,
|
||||
* where the manual sign extension seems to perform equally well
|
||||
* with DEC/Compaq/HP compiler, and much better with gcc.
|
||||
*/
|
||||
#ifdef __alpha
|
||||
#define XMUX(c, x, y) ((((signed int)((c) << 31) >> 31) & (y)) ^ (x))
|
||||
#else
|
||||
#define XMUX(c, x, y) (((c) & 0x1) ? ((x) ^ (y)) : (x))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FSM() updates the finite state machine.
|
||||
*/
|
||||
#define FSM(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) do { \
|
||||
ulong32 tt, or1; \
|
||||
tt = XMUX(r1, s ## x1, s ## x8); \
|
||||
or1 = r1; \
|
||||
r1 = T32(r2 + tt); \
|
||||
tt = T32(or1 * 0x54655307); \
|
||||
r2 = ROLc(tt, 7); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* LRU updates the shift register; the dropped value is stored
|
||||
* in variable "dd".
|
||||
*/
|
||||
#define LRU(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, dd) do { \
|
||||
dd = s ## x0; \
|
||||
s ## x0 = MUL_A(s ## x0) ^ MUL_G(s ## x3) ^ s ## x9; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* CC1 stores into variable "ee" the next intermediate word
|
||||
* (combination of the new states of the LFSR and the FSM).
|
||||
*/
|
||||
#define CC1(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, ee) do { \
|
||||
ee = T32(s ## x9 + r1) ^ r2; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* STEP computes one internal round. "dd" receives the "s_t"
|
||||
* value (dropped from the LFSR) and "ee" gets the value computed
|
||||
* from the LFSR and FSM.
|
||||
*/
|
||||
#define STEP(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, dd, ee) do { \
|
||||
FSM(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9); \
|
||||
LRU(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, dd); \
|
||||
CC1(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, ee); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Apply one Serpent round (with the provided S-box macro), XOR
|
||||
* the result with the "v" values, and encode the result into
|
||||
* the destination buffer, at the provided offset. The "x*"
|
||||
* arguments encode the output permutation of the "S" macro.
|
||||
*/
|
||||
#define SRD(S, x0, x1, x2, x3, ooff) do { \
|
||||
S(u0, u1, u2, u3, u4); \
|
||||
STORE32L(u ## x0 ^ v0, st->buf + ooff); \
|
||||
STORE32L(u ## x1 ^ v1, st->buf + ooff + 4); \
|
||||
STORE32L(u ## x2 ^ v2, st->buf + ooff + 8); \
|
||||
STORE32L(u ## x3 ^ v3, st->buf + ooff + 12); \
|
||||
} while (0)
|
||||
|
||||
ulong32 s00 = st->s00;
|
||||
ulong32 s01 = st->s01;
|
||||
ulong32 s02 = st->s02;
|
||||
ulong32 s03 = st->s03;
|
||||
ulong32 s04 = st->s04;
|
||||
ulong32 s05 = st->s05;
|
||||
ulong32 s06 = st->s06;
|
||||
ulong32 s07 = st->s07;
|
||||
ulong32 s08 = st->s08;
|
||||
ulong32 s09 = st->s09;
|
||||
ulong32 r1 = st->r1;
|
||||
ulong32 r2 = st->r2;
|
||||
ulong32 u0, u1, u2, u3, u4;
|
||||
ulong32 v0, v1, v2, v3;
|
||||
|
||||
STEP(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, v0, u0);
|
||||
STEP(01, 02, 03, 04, 05, 06, 07, 08, 09, 00, v1, u1);
|
||||
STEP(02, 03, 04, 05, 06, 07, 08, 09, 00, 01, v2, u2);
|
||||
STEP(03, 04, 05, 06, 07, 08, 09, 00, 01, 02, v3, u3);
|
||||
SRD(S2, 2, 3, 1, 4, 0);
|
||||
STEP(04, 05, 06, 07, 08, 09, 00, 01, 02, 03, v0, u0);
|
||||
STEP(05, 06, 07, 08, 09, 00, 01, 02, 03, 04, v1, u1);
|
||||
STEP(06, 07, 08, 09, 00, 01, 02, 03, 04, 05, v2, u2);
|
||||
STEP(07, 08, 09, 00, 01, 02, 03, 04, 05, 06, v3, u3);
|
||||
SRD(S2, 2, 3, 1, 4, 16);
|
||||
STEP(08, 09, 00, 01, 02, 03, 04, 05, 06, 07, v0, u0);
|
||||
STEP(09, 00, 01, 02, 03, 04, 05, 06, 07, 08, v1, u1);
|
||||
STEP(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, v2, u2);
|
||||
STEP(01, 02, 03, 04, 05, 06, 07, 08, 09, 00, v3, u3);
|
||||
SRD(S2, 2, 3, 1, 4, 32);
|
||||
STEP(02, 03, 04, 05, 06, 07, 08, 09, 00, 01, v0, u0);
|
||||
STEP(03, 04, 05, 06, 07, 08, 09, 00, 01, 02, v1, u1);
|
||||
STEP(04, 05, 06, 07, 08, 09, 00, 01, 02, 03, v2, u2);
|
||||
STEP(05, 06, 07, 08, 09, 00, 01, 02, 03, 04, v3, u3);
|
||||
SRD(S2, 2, 3, 1, 4, 48);
|
||||
STEP(06, 07, 08, 09, 00, 01, 02, 03, 04, 05, v0, u0);
|
||||
STEP(07, 08, 09, 00, 01, 02, 03, 04, 05, 06, v1, u1);
|
||||
STEP(08, 09, 00, 01, 02, 03, 04, 05, 06, 07, v2, u2);
|
||||
STEP(09, 00, 01, 02, 03, 04, 05, 06, 07, 08, v3, u3);
|
||||
SRD(S2, 2, 3, 1, 4, 64);
|
||||
|
||||
st->s00 = s00;
|
||||
st->s01 = s01;
|
||||
st->s02 = s02;
|
||||
st->s03 = s03;
|
||||
st->s04 = s04;
|
||||
st->s05 = s05;
|
||||
st->s06 = s06;
|
||||
st->s07 = s07;
|
||||
st->s08 = s08;
|
||||
st->s09 = s09;
|
||||
st->r1 = r1;
|
||||
st->r2 = r2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Combine buffers in1[] and in2[] by XOR, result in out[]. The length
|
||||
* is "datalen" (in bytes). Partial overlap of out[] with either in1[]
|
||||
* or in2[] is not allowed. Total overlap (out == in1 and/or out == in2)
|
||||
* is allowed.
|
||||
*/
|
||||
static LTC_INLINE void s_xorbuf(const unsigned char *in1, const unsigned char *in2,
|
||||
unsigned char *out, unsigned long datalen)
|
||||
{
|
||||
while (datalen -- > 0) {
|
||||
*out ++ = *in1 ++ ^ *in2 ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Cipher operation, as a stream cipher: data is read from the "in"
|
||||
* buffer, combined by XOR with the stream, and the result is written
|
||||
* in the "out" buffer. "in" and "out" must be either equal, or
|
||||
* reference distinct buffers (no partial overlap is allowed).
|
||||
* @param st The Sosemanuk state
|
||||
* @param in Data in
|
||||
* @param inlen Length of data in bytes
|
||||
* @param out Data out
|
||||
* @return CRYPT_OK on success
|
||||
*/
|
||||
int sosemanuk_crypt(sosemanuk_state *st,
|
||||
const unsigned char *in, unsigned long inlen, unsigned char *out)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
if (st->ptr < (sizeof(st->buf))) {
|
||||
unsigned long rlen = (sizeof(st->buf)) - st->ptr;
|
||||
|
||||
if (rlen > inlen) {
|
||||
rlen = inlen;
|
||||
}
|
||||
s_xorbuf(st->buf + st->ptr, in, out, rlen);
|
||||
in += rlen;
|
||||
out += rlen;
|
||||
inlen -= rlen;
|
||||
st->ptr += rlen;
|
||||
}
|
||||
while (inlen > 0) {
|
||||
s_sosemanuk_internal(st);
|
||||
if (inlen >= sizeof(st->buf)) {
|
||||
s_xorbuf(st->buf, in, out, sizeof(st->buf));
|
||||
in += sizeof(st->buf);
|
||||
out += sizeof(st->buf);
|
||||
inlen -= sizeof(st->buf);
|
||||
} else {
|
||||
s_xorbuf(st->buf, in, out, inlen);
|
||||
st->ptr = inlen;
|
||||
inlen = 0;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Cipher operation, as a PRNG: the provided output buffer is filled with
|
||||
* pseudo-random bytes as output from the stream cipher.
|
||||
* @param st The Sosemanuk state
|
||||
* @param out Data out
|
||||
* @param outlen Length of output in bytes
|
||||
* @return CRYPT_OK on success
|
||||
*/
|
||||
int sosemanuk_keystream(sosemanuk_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 sosemanuk_crypt(st, out, outlen, out);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Terminate and clear Sosemanuk key context
|
||||
* @param st The Sosemanuk state
|
||||
* @return CRYPT_OK on success
|
||||
*/
|
||||
int sosemanuk_done(sosemanuk_state *st)
|
||||
{
|
||||
LTC_ARGCHK(st != NULL);
|
||||
zeromem(st, sizeof(sosemanuk_state));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,35 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SOSEMANUK
|
||||
|
||||
/**
|
||||
Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sosemanuk
|
||||
@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 dataout [out] The ciphertext (or plaintext)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sosemanuk_memory(const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *iv, unsigned long ivlen,
|
||||
const unsigned char *datain, unsigned long datalen,
|
||||
unsigned char *dataout)
|
||||
{
|
||||
sosemanuk_state st;
|
||||
int err;
|
||||
|
||||
if ((err = sosemanuk_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY;
|
||||
if ((err = sosemanuk_setiv(&st, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY;
|
||||
err = sosemanuk_crypt(&st, datain, datalen, dataout);
|
||||
WIPE_KEY:
|
||||
sosemanuk_done(&st);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_SOSEMANUK */
|
||||
@@ -0,0 +1,79 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SOSEMANUK
|
||||
int sosemanuk_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
sosemanuk_state st;
|
||||
int err;
|
||||
unsigned char out[1000];
|
||||
|
||||
{
|
||||
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
unsigned char ct[] = { 0x7e, 0xfe, 0x2e, 0x6f, 0x8f, 0x77, 0x15, 0x72, 0x6a, 0x88, 0x14, 0xa6, 0x56, 0x88, 0x29, 0x9a,
|
||||
0x86, 0x32, 0x7f, 0x14, 0xd6, 0xb1, 0x94, 0x90, 0x25, 0xbc, 0x73, 0xfd, 0x02, 0x6c, 0x6a, 0xb8,
|
||||
0xda, 0x8e, 0x7f, 0x61, 0x70, 0x81, 0xe3, 0xbb, 0x99, 0xaf, 0x19, 0x9f, 0x20, 0x45 };
|
||||
char pt[] = "Kilroy was here, and there. ...and everywhere!"; /* len = 46 bytes */
|
||||
unsigned long len;
|
||||
len = XSTRLEN(pt);
|
||||
/* crypt piece by piece */
|
||||
if ((err = sosemanuk_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_setiv(&st, n, sizeof(n))) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_crypt(&st, (unsigned char*)pt + 5, 25, out + 5)) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_crypt(&st, (unsigned char*)pt + 30, 10, out + 30)) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_crypt(&st, (unsigned char*)pt + 40, len - 40, out + 40)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "SOSEMANUK-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in one go - using sosemanuk_ivctr64() */
|
||||
if ((err = sosemanuk_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_setiv(&st, n, sizeof(n))) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_crypt(&st, (unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "SOSEMANUK-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* crypt in a single call */
|
||||
if ((err = sosemanuk_memory(k, sizeof(k), n, sizeof(n),
|
||||
(unsigned char*)pt, len, out)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, len, ct, sizeof(ct), "SOSEMANUK-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
}
|
||||
{
|
||||
/* keystream
|
||||
* http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/sosemanuk/unverified.test-vectors?rev=210&view=auto
|
||||
* Set 6, vector 0
|
||||
* key = 0053A6F94C9FF24598EB3E91E4378ADD
|
||||
* 3083D6297CCF2275C81B6EC11467BA0D
|
||||
* IV = 0D74DB42A91077DE45AC137AE148AF16
|
||||
* stream[0..63] = 55EB8D174C2E0351E5A53C90E84740EB
|
||||
* 0F5A24AAFEC8E0C9F9D2CE48B2ADB0A3
|
||||
* 4D2E8C4E016102607368FFA43A0F9155
|
||||
* 0706E3548AD9E5EA15A53EB6F0EDE9DC
|
||||
*
|
||||
*/
|
||||
|
||||
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, 0x45, 0xAC, 0x13, 0x7A, 0xE1, 0x48, 0xAF, 0x16 };
|
||||
unsigned char ct3[] = { 0x55, 0xEB, 0x8D, 0x17, 0x4C, 0x2E, 0x03, 0x51, 0xE5, 0xA5, 0x3C, 0x90, 0xE8, 0x47, 0x40, 0xEB,
|
||||
0x0F, 0x5A, 0x24, 0xAA, 0xFE, 0xC8, 0xE0, 0xC9, 0xF9, 0xD2, 0xCE, 0x48, 0xB2, 0xAD, 0xB0, 0xA3,
|
||||
0x4D, 0x2E, 0x8C, 0x4E, 0x01, 0x61, 0x02, 0x60, 0x73, 0x68, 0xFF, 0xA4, 0x3A, 0x0F, 0x91, 0x55,
|
||||
0x07, 0x06, 0xE3, 0x54, 0x8A, 0xD9, 0xE5, 0xEA, 0x15, 0xA5, 0x3E, 0xB6, 0xF0, 0xED, 0xE9, 0xDC };
|
||||
if ((err = sosemanuk_setup(&st, k3, sizeof(k3))) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_setiv(&st, n3, sizeof(n3))) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_keystream(&st, out, 64)) != CRYPT_OK) return err;
|
||||
if ((err = sosemanuk_done(&st)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(out, 64, ct3, sizeof(ct3), "SOSEMANUK-TV4", 1)) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user