1 /*
2 version 20140420
3 D. J. Bernstein
4 Public domain.
5 */
6
7 #include <stdint.h>
8
9 #include "crypto_core_salsa20.h"
10 #include "crypto_stream_salsa20.h"
11 #include "utils.h"
12
13 #include "../stream_salsa20.h"
14 #include "salsa20_ref.h"
15
16 #ifndef HAVE_AMD64_ASM
17
18 static int
stream_ref(unsigned char * c,unsigned long long clen,const unsigned char * n,const unsigned char * k)19 stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n,
20 const unsigned char *k)
21 {
22 unsigned char in[16];
23 unsigned char block[64];
24 unsigned char kcopy[32];
25 unsigned int i;
26 unsigned int u;
27
28 if (!clen) {
29 return 0;
30 }
31 for (i = 0; i < 32; i++) {
32 kcopy[i] = k[i];
33 }
34 for (i = 0; i < 8; i++) {
35 in[i] = n[i];
36 }
37 for (i = 8; i < 16; i++) {
38 in[i] = 0;
39 }
40 while (clen >= 64) {
41 crypto_core_salsa20(c, in, kcopy, NULL);
42 u = 1;
43 for (i = 8; i < 16; i++) {
44 u += (unsigned int) in[i];
45 in[i] = u;
46 u >>= 8;
47 }
48 clen -= 64;
49 c += 64;
50 }
51 if (clen) {
52 crypto_core_salsa20(block, in, kcopy, NULL);
53 for (i = 0; i < (unsigned int) clen; i++) {
54 c[i] = block[i];
55 }
56 }
57 sodium_memzero(block, sizeof block);
58 sodium_memzero(kcopy, sizeof kcopy);
59
60 return 0;
61 }
62
63 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)64 stream_ref_xor_ic(unsigned char *c, const unsigned char *m,
65 unsigned long long mlen, const unsigned char *n, uint64_t ic,
66 const unsigned char *k)
67 {
68 unsigned char in[16];
69 unsigned char block[64];
70 unsigned char kcopy[32];
71 unsigned int i;
72 unsigned int u;
73
74 if (!mlen) {
75 return 0;
76 }
77 for (i = 0; i < 32; i++) {
78 kcopy[i] = k[i];
79 }
80 for (i = 0; i < 8; i++) {
81 in[i] = n[i];
82 }
83 for (i = 8; i < 16; i++) {
84 in[i] = (unsigned char) (ic & 0xff);
85 ic >>= 8;
86 }
87 while (mlen >= 64) {
88 crypto_core_salsa20(block, in, kcopy, NULL);
89 for (i = 0; i < 64; i++) {
90 c[i] = m[i] ^ block[i];
91 }
92 u = 1;
93 for (i = 8; i < 16; i++) {
94 u += (unsigned int) in[i];
95 in[i] = u;
96 u >>= 8;
97 }
98 mlen -= 64;
99 c += 64;
100 m += 64;
101 }
102 if (mlen) {
103 crypto_core_salsa20(block, in, kcopy, NULL);
104 for (i = 0; i < (unsigned int) mlen; i++) {
105 c[i] = m[i] ^ block[i];
106 }
107 }
108 sodium_memzero(block, sizeof block);
109 sodium_memzero(kcopy, sizeof kcopy);
110
111 return 0;
112 }
113
114 struct crypto_stream_salsa20_implementation
115 crypto_stream_salsa20_ref_implementation = {
116 SODIUM_C99(.stream =) stream_ref,
117 SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic,
118 };
119
120 #endif
121