1 /*
2 version 20140420
3 D. J. Bernstein
4 Public domain.
5 */
6
7 #include <stdint.h>
8
9 #include "crypto_core_salsa208.h"
10 #include "crypto_stream_salsa208.h"
11 #include "utils.h"
12
13 int
crypto_stream_salsa208(unsigned char * c,unsigned long long clen,const unsigned char * n,const unsigned char * k)14 crypto_stream_salsa208(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_salsa208(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_salsa208(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_salsa208_xor(unsigned char * c,const unsigned char * m,unsigned long long mlen,const unsigned char * n,const unsigned char * k)59 crypto_stream_salsa208_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_salsa208(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_salsa208(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