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