Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/lib/util/chacha_private.h
1532 views
1
/*
2
chacha-merged.c version 20080118
3
D. J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
8
9
typedef unsigned char u8;
10
typedef unsigned int u32;
11
12
typedef struct
13
{
14
u32 input[16]; /* could be compressed */
15
} chacha_ctx;
16
17
#define U8C(v) (v##U)
18
#define U32C(v) (v##U)
19
20
#define U8V(v) ((u8)(v) & U8C(0xFF))
21
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define ROTL32(v, n) \
24
(U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define U8TO32_LITTLE(p) \
27
(((u32)((p)[0]) ) | \
28
((u32)((p)[1]) << 8) | \
29
((u32)((p)[2]) << 16) | \
30
((u32)((p)[3]) << 24))
31
32
#define U32TO8_LITTLE(p, v) \
33
do { \
34
(p)[0] = U8V((v) ); \
35
(p)[1] = U8V((v) >> 8); \
36
(p)[2] = U8V((v) >> 16); \
37
(p)[3] = U8V((v) >> 24); \
38
} while (0)
39
40
#define ROTATE(v,c) (ROTL32(v,c))
41
#define XOR(v,w) ((v) ^ (w))
42
#define PLUS(v,w) (U32V((v) + (w)))
43
#define PLUSONE(v) (PLUS((v),1))
44
45
#define QUARTERROUND(a,b,c,d) \
46
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
47
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
48
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
49
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
50
51
static const char sigma[16] = "expand 32-byte k";
52
static const char tau[16] = "expand 16-byte k";
53
54
static void
55
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
56
{
57
const char *constants;
58
59
x->input[4] = U8TO32_LITTLE(k + 0);
60
x->input[5] = U8TO32_LITTLE(k + 4);
61
x->input[6] = U8TO32_LITTLE(k + 8);
62
x->input[7] = U8TO32_LITTLE(k + 12);
63
if (kbits == 256) { /* recommended */
64
k += 16;
65
constants = sigma;
66
} else { /* kbits == 128 */
67
constants = tau;
68
}
69
x->input[8] = U8TO32_LITTLE(k + 0);
70
x->input[9] = U8TO32_LITTLE(k + 4);
71
x->input[10] = U8TO32_LITTLE(k + 8);
72
x->input[11] = U8TO32_LITTLE(k + 12);
73
x->input[0] = U8TO32_LITTLE(constants + 0);
74
x->input[1] = U8TO32_LITTLE(constants + 4);
75
x->input[2] = U8TO32_LITTLE(constants + 8);
76
x->input[3] = U8TO32_LITTLE(constants + 12);
77
}
78
79
static void
80
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
81
{
82
x->input[12] = 0;
83
x->input[13] = 0;
84
x->input[14] = U8TO32_LITTLE(iv + 0);
85
x->input[15] = U8TO32_LITTLE(iv + 4);
86
}
87
88
static void
89
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
90
{
91
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
92
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
93
u8 *ctarget = NULL;
94
u8 tmp[64];
95
u32 i;
96
97
if (!bytes) return;
98
99
j0 = x->input[0];
100
j1 = x->input[1];
101
j2 = x->input[2];
102
j3 = x->input[3];
103
j4 = x->input[4];
104
j5 = x->input[5];
105
j6 = x->input[6];
106
j7 = x->input[7];
107
j8 = x->input[8];
108
j9 = x->input[9];
109
j10 = x->input[10];
110
j11 = x->input[11];
111
j12 = x->input[12];
112
j13 = x->input[13];
113
j14 = x->input[14];
114
j15 = x->input[15];
115
116
for (;;) {
117
if (bytes < 64) {
118
for (i = 0;i < bytes;++i) tmp[i] = m[i];
119
m = tmp;
120
ctarget = c;
121
c = tmp;
122
}
123
x0 = j0;
124
x1 = j1;
125
x2 = j2;
126
x3 = j3;
127
x4 = j4;
128
x5 = j5;
129
x6 = j6;
130
x7 = j7;
131
x8 = j8;
132
x9 = j9;
133
x10 = j10;
134
x11 = j11;
135
x12 = j12;
136
x13 = j13;
137
x14 = j14;
138
x15 = j15;
139
for (i = 20;i > 0;i -= 2) {
140
QUARTERROUND( x0, x4, x8,x12)
141
QUARTERROUND( x1, x5, x9,x13)
142
QUARTERROUND( x2, x6,x10,x14)
143
QUARTERROUND( x3, x7,x11,x15)
144
QUARTERROUND( x0, x5,x10,x15)
145
QUARTERROUND( x1, x6,x11,x12)
146
QUARTERROUND( x2, x7, x8,x13)
147
QUARTERROUND( x3, x4, x9,x14)
148
}
149
x0 = PLUS(x0,j0);
150
x1 = PLUS(x1,j1);
151
x2 = PLUS(x2,j2);
152
x3 = PLUS(x3,j3);
153
x4 = PLUS(x4,j4);
154
x5 = PLUS(x5,j5);
155
x6 = PLUS(x6,j6);
156
x7 = PLUS(x7,j7);
157
x8 = PLUS(x8,j8);
158
x9 = PLUS(x9,j9);
159
x10 = PLUS(x10,j10);
160
x11 = PLUS(x11,j11);
161
x12 = PLUS(x12,j12);
162
x13 = PLUS(x13,j13);
163
x14 = PLUS(x14,j14);
164
x15 = PLUS(x15,j15);
165
166
#ifndef KEYSTREAM_ONLY
167
x0 = XOR(x0,U8TO32_LITTLE(m + 0));
168
x1 = XOR(x1,U8TO32_LITTLE(m + 4));
169
x2 = XOR(x2,U8TO32_LITTLE(m + 8));
170
x3 = XOR(x3,U8TO32_LITTLE(m + 12));
171
x4 = XOR(x4,U8TO32_LITTLE(m + 16));
172
x5 = XOR(x5,U8TO32_LITTLE(m + 20));
173
x6 = XOR(x6,U8TO32_LITTLE(m + 24));
174
x7 = XOR(x7,U8TO32_LITTLE(m + 28));
175
x8 = XOR(x8,U8TO32_LITTLE(m + 32));
176
x9 = XOR(x9,U8TO32_LITTLE(m + 36));
177
x10 = XOR(x10,U8TO32_LITTLE(m + 40));
178
x11 = XOR(x11,U8TO32_LITTLE(m + 44));
179
x12 = XOR(x12,U8TO32_LITTLE(m + 48));
180
x13 = XOR(x13,U8TO32_LITTLE(m + 52));
181
x14 = XOR(x14,U8TO32_LITTLE(m + 56));
182
x15 = XOR(x15,U8TO32_LITTLE(m + 60));
183
#endif
184
185
j12 = PLUSONE(j12);
186
if (!j12) {
187
j13 = PLUSONE(j13);
188
/* stopping at 2^70 bytes per nonce is user's responsibility */
189
}
190
191
U32TO8_LITTLE(c + 0,x0);
192
U32TO8_LITTLE(c + 4,x1);
193
U32TO8_LITTLE(c + 8,x2);
194
U32TO8_LITTLE(c + 12,x3);
195
U32TO8_LITTLE(c + 16,x4);
196
U32TO8_LITTLE(c + 20,x5);
197
U32TO8_LITTLE(c + 24,x6);
198
U32TO8_LITTLE(c + 28,x7);
199
U32TO8_LITTLE(c + 32,x8);
200
U32TO8_LITTLE(c + 36,x9);
201
U32TO8_LITTLE(c + 40,x10);
202
U32TO8_LITTLE(c + 44,x11);
203
U32TO8_LITTLE(c + 48,x12);
204
U32TO8_LITTLE(c + 52,x13);
205
U32TO8_LITTLE(c + 56,x14);
206
U32TO8_LITTLE(c + 60,x15);
207
208
if (bytes <= 64) {
209
if (bytes < 64) {
210
for (i = 0;i < bytes;++i) ctarget[i] = c[i];
211
}
212
x->input[12] = j12;
213
x->input[13] = j13;
214
return;
215
}
216
bytes -= 64;
217
c += 64;
218
#ifndef KEYSTREAM_ONLY
219
m += 64;
220
#endif
221
}
222
}
223
224