10ac341f1SConrad Meyer /*
20ac341f1SConrad Meyer version 20140420
30ac341f1SConrad Meyer D. J. Bernstein
40ac341f1SConrad Meyer Public domain.
50ac341f1SConrad Meyer */
60ac341f1SConrad Meyer
70ac341f1SConrad Meyer #include <stdint.h>
80ac341f1SConrad Meyer
90ac341f1SConrad Meyer #include "crypto_core_salsa2012.h"
100ac341f1SConrad Meyer #include "crypto_stream_salsa2012.h"
110ac341f1SConrad Meyer #include "utils.h"
120ac341f1SConrad Meyer
130ac341f1SConrad Meyer int
crypto_stream_salsa2012(unsigned char * c,unsigned long long clen,const unsigned char * n,const unsigned char * k)140ac341f1SConrad Meyer crypto_stream_salsa2012(unsigned char *c, unsigned long long clen,
150ac341f1SConrad Meyer const unsigned char *n, const unsigned char *k)
160ac341f1SConrad Meyer {
170ac341f1SConrad Meyer unsigned char in[16];
180ac341f1SConrad Meyer unsigned char block[64];
190ac341f1SConrad Meyer unsigned char kcopy[32];
200ac341f1SConrad Meyer unsigned int i;
210ac341f1SConrad Meyer unsigned int u;
220ac341f1SConrad Meyer
230ac341f1SConrad Meyer if (!clen) {
240ac341f1SConrad Meyer return 0;
250ac341f1SConrad Meyer }
260ac341f1SConrad Meyer for (i = 0; i < 32; ++i) {
270ac341f1SConrad Meyer kcopy[i] = k[i];
280ac341f1SConrad Meyer }
290ac341f1SConrad Meyer for (i = 0; i < 8; ++i) {
300ac341f1SConrad Meyer in[i] = n[i];
310ac341f1SConrad Meyer }
320ac341f1SConrad Meyer for (i = 8; i < 16; ++i) {
330ac341f1SConrad Meyer in[i] = 0;
340ac341f1SConrad Meyer }
350ac341f1SConrad Meyer while (clen >= 64) {
360ac341f1SConrad Meyer crypto_core_salsa2012(c, in, kcopy, NULL);
370ac341f1SConrad Meyer u = 1;
380ac341f1SConrad Meyer for (i = 8; i < 16; ++i) {
390ac341f1SConrad Meyer u += (unsigned int)in[i];
400ac341f1SConrad Meyer in[i] = u;
410ac341f1SConrad Meyer u >>= 8;
420ac341f1SConrad Meyer }
430ac341f1SConrad Meyer clen -= 64;
440ac341f1SConrad Meyer c += 64;
450ac341f1SConrad Meyer }
460ac341f1SConrad Meyer if (clen) {
470ac341f1SConrad Meyer crypto_core_salsa2012(block, in, kcopy, NULL);
480ac341f1SConrad Meyer for (i = 0; i < (unsigned int)clen; ++i) {
490ac341f1SConrad Meyer c[i] = block[i];
500ac341f1SConrad Meyer }
510ac341f1SConrad Meyer }
520ac341f1SConrad Meyer sodium_memzero(block, sizeof block);
530ac341f1SConrad Meyer sodium_memzero(kcopy, sizeof kcopy);
540ac341f1SConrad Meyer
550ac341f1SConrad Meyer return 0;
560ac341f1SConrad Meyer }
570ac341f1SConrad Meyer
580ac341f1SConrad Meyer int
crypto_stream_salsa2012_xor(unsigned char * c,const unsigned char * m,unsigned long long mlen,const unsigned char * n,const unsigned char * k)590ac341f1SConrad Meyer crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m,
600ac341f1SConrad Meyer unsigned long long mlen, const unsigned char *n,
610ac341f1SConrad Meyer const unsigned char *k)
620ac341f1SConrad Meyer {
630ac341f1SConrad Meyer unsigned char in[16];
640ac341f1SConrad Meyer unsigned char block[64];
650ac341f1SConrad Meyer unsigned char kcopy[32];
660ac341f1SConrad Meyer unsigned int i;
670ac341f1SConrad Meyer unsigned int u;
680ac341f1SConrad Meyer
690ac341f1SConrad Meyer if (!mlen) {
700ac341f1SConrad Meyer return 0;
710ac341f1SConrad Meyer }
720ac341f1SConrad Meyer for (i = 0; i < 32; ++i) {
730ac341f1SConrad Meyer kcopy[i] = k[i];
740ac341f1SConrad Meyer }
750ac341f1SConrad Meyer for (i = 0; i < 8; ++i) {
760ac341f1SConrad Meyer in[i] = n[i];
770ac341f1SConrad Meyer }
780ac341f1SConrad Meyer for (i = 8; i < 16; ++i) {
790ac341f1SConrad Meyer in[i] = 0;
800ac341f1SConrad Meyer }
810ac341f1SConrad Meyer while (mlen >= 64) {
820ac341f1SConrad Meyer crypto_core_salsa2012(block, in, kcopy, NULL);
830ac341f1SConrad Meyer for (i = 0; i < 64; ++i) {
840ac341f1SConrad Meyer c[i] = m[i] ^ block[i];
850ac341f1SConrad Meyer }
860ac341f1SConrad Meyer u = 1;
870ac341f1SConrad Meyer for (i = 8; i < 16; ++i) {
880ac341f1SConrad Meyer u += (unsigned int)in[i];
890ac341f1SConrad Meyer in[i] = u;
900ac341f1SConrad Meyer u >>= 8;
910ac341f1SConrad Meyer }
920ac341f1SConrad Meyer mlen -= 64;
930ac341f1SConrad Meyer c += 64;
940ac341f1SConrad Meyer m += 64;
950ac341f1SConrad Meyer }
960ac341f1SConrad Meyer if (mlen) {
970ac341f1SConrad Meyer crypto_core_salsa2012(block, in, kcopy, NULL);
980ac341f1SConrad Meyer for (i = 0; i < (unsigned int)mlen; ++i) {
990ac341f1SConrad Meyer c[i] = m[i] ^ block[i];
1000ac341f1SConrad Meyer }
1010ac341f1SConrad Meyer }
1020ac341f1SConrad Meyer sodium_memzero(block, sizeof block);
1030ac341f1SConrad Meyer sodium_memzero(kcopy, sizeof kcopy);
1040ac341f1SConrad Meyer
1050ac341f1SConrad Meyer return 0;
1060ac341f1SConrad Meyer }
107