diff options
Diffstat (limited to 'libs/libsodium/src/crypto_stream/salsa20/ref')
-rw-r--r-- | libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c | 120 | ||||
-rw-r--r-- | libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h | 8 |
2 files changed, 128 insertions, 0 deletions
diff --git a/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c new file mode 100644 index 0000000000..f0854ebf7e --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c @@ -0,0 +1,120 @@ +/* +version 20140420 +D. J. Bernstein +Public domain. +*/ + +#include <stdint.h> + +#include "crypto_core_salsa20.h" +#include "crypto_stream_salsa20.h" +#include "utils.h" + +#include "../stream_salsa20.h" +#include "salsa20_ref.h" + +#ifndef HAVE_AMD64_ASM + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!clen) { + return 0; + } + for (i = 0; i < 32; i++) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; i++) { + in[i] = n[i]; + } + for (i = 8; i < 16; i++) { + in[i] = 0; + } + while (clen >= 64) { + crypto_core_salsa20(c, in, kcopy, NULL); + u = 1; + for (i = 8; i < 16; i++) { + u += (unsigned int) in[i]; + in[i] = u; + u >>= 8; + } + clen -= 64; + c += 64; + } + if (clen) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int) clen; i++) { + c[i] = block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!mlen) { + return 0; + } + for (i = 0; i < 32; i++) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; i++) { + in[i] = n[i]; + } + for (i = 8; i < 16; i++) { + in[i] = (unsigned char) (ic & 0xff); + ic >>= 8; + } + while (mlen >= 64) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < 64; i++) { + c[i] = m[i] ^ block[i]; + } + u = 1; + for (i = 8; i < 16; i++) { + u += (unsigned int) in[i]; + in[i] = u; + u >>= 8; + } + mlen -= 64; + c += 64; + m += 64; + } + if (mlen) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int) mlen; i++) { + c[i] = m[i] ^ block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_ref_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + }; + +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h new file mode 100644 index 0000000000..8716cb4048 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_ref_implementation; |