1 /*
2 version 20140420
3 D. J. Bernstein
4 Public domain.
5 */
6 
7 #include <stdint.h>
8 
9 #include "crypto_core_salsa2012.h"
10 #include "crypto_stream_salsa2012.h"
11 #include "utils.h"
12 
13 int
crypto_stream_salsa2012(unsigned char * c,unsigned long long clen,const unsigned char * n,const unsigned char * k)14 crypto_stream_salsa2012(unsigned char *c, unsigned long long clen,
15                         const unsigned char *n, const unsigned char *k)
16 {
17     unsigned char in[16];
18     unsigned char block[64];
19     unsigned char kcopy[32];
20     unsigned int  i;
21     unsigned int  u;
22 
23     if (!clen) {
24         return 0;
25     }
26     for (i = 0; i < 32; ++i) {
27         kcopy[i] = k[i];
28     }
29     for (i = 0; i < 8; ++i) {
30         in[i] = n[i];
31     }
32     for (i = 8; i < 16; ++i) {
33         in[i] = 0;
34     }
35     while (clen >= 64) {
36         crypto_core_salsa2012(c, in, kcopy, NULL);
37         u = 1;
38         for (i = 8; i < 16; ++i) {
39             u += (unsigned int)in[i];
40             in[i] = u;
41             u >>= 8;
42         }
43         clen -= 64;
44         c += 64;
45     }
46     if (clen) {
47         crypto_core_salsa2012(block, in, kcopy, NULL);
48         for (i = 0; i < (unsigned int)clen; ++i) {
49             c[i] = block[i];
50         }
51     }
52     sodium_memzero(block, sizeof block);
53     sodium_memzero(kcopy, sizeof kcopy);
54 
55     return 0;
56 }
57 
58 int
crypto_stream_salsa2012_xor(unsigned char * c,const unsigned char * m,unsigned long long mlen,const unsigned char * n,const unsigned char * k)59 crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m,
60                             unsigned long long mlen, const unsigned char *n,
61                             const unsigned char *k)
62 {
63     unsigned char in[16];
64     unsigned char block[64];
65     unsigned char kcopy[32];
66     unsigned int  i;
67     unsigned int  u;
68 
69     if (!mlen) {
70         return 0;
71     }
72     for (i = 0; i < 32; ++i) {
73         kcopy[i] = k[i];
74     }
75     for (i = 0; i < 8; ++i) {
76         in[i] = n[i];
77     }
78     for (i = 8; i < 16; ++i) {
79         in[i] = 0;
80     }
81     while (mlen >= 64) {
82         crypto_core_salsa2012(block, in, kcopy, NULL);
83         for (i = 0; i < 64; ++i) {
84             c[i] = m[i] ^ block[i];
85         }
86         u = 1;
87         for (i = 8; i < 16; ++i) {
88             u += (unsigned int)in[i];
89             in[i] = u;
90             u >>= 8;
91         }
92         mlen -= 64;
93         c += 64;
94         m += 64;
95     }
96     if (mlen) {
97         crypto_core_salsa2012(block, in, kcopy, NULL);
98         for (i = 0; i < (unsigned int)mlen; ++i) {
99             c[i] = m[i] ^ block[i];
100         }
101     }
102     sodium_memzero(block, sizeof block);
103     sodium_memzero(kcopy, sizeof kcopy);
104 
105     return 0;
106 }
107