Coverage Report

Created: 2025-03-09 06:52

/src/libressl/crypto/compat/chacha_private.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
chacha-merged.c version 20080118
3
D. J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker 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
11.5M
#define U8C(v) (v##U)
18
118M
#define U32C(v) (v##U)
19
20
11.5M
#define U8V(v) ((u8)(v) & U8C(0xFF))
21
118M
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define ROTL32(v, n) \
24
57.6M
  (U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define U8TO32_LITTLE(p) \
27
157k
  (((u32)((p)[0])      ) | \
28
157k
   ((u32)((p)[1]) <<  8) | \
29
157k
   ((u32)((p)[2]) << 16) | \
30
157k
   ((u32)((p)[3]) << 24))
31
32
#define U32TO8_LITTLE(p, v) \
33
2.88M
  do { \
34
2.88M
    (p)[0] = U8V((v)      ); \
35
2.88M
    (p)[1] = U8V((v) >>  8); \
36
2.88M
    (p)[2] = U8V((v) >> 16); \
37
2.88M
    (p)[3] = U8V((v) >> 24); \
38
2.88M
  } while (0)
39
40
57.6M
#define ROTATE(v,c) (ROTL32(v,c))
41
#define XOR(v,w) ((v) ^ (w))
42
60.6M
#define PLUS(v,w) (U32V((v) + (w)))
43
180k
#define PLUSONE(v) (PLUS((v),1))
44
45
#define QUARTERROUND(a,b,c,d) \
46
14.4M
  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
47
14.4M
  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
48
14.4M
  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
49
14.4M
  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)
56
11.2k
{
57
11.2k
  const char *constants;
58
59
11.2k
  x->input[4] = U8TO32_LITTLE(k + 0);
60
11.2k
  x->input[5] = U8TO32_LITTLE(k + 4);
61
11.2k
  x->input[6] = U8TO32_LITTLE(k + 8);
62
11.2k
  x->input[7] = U8TO32_LITTLE(k + 12);
63
11.2k
  if (kbits == 256) { /* recommended */
64
11.2k
    k += 16;
65
11.2k
    constants = sigma;
66
11.2k
  } else { /* kbits == 128 */
67
0
    constants = tau;
68
0
  }
69
11.2k
  x->input[8] = U8TO32_LITTLE(k + 0);
70
11.2k
  x->input[9] = U8TO32_LITTLE(k + 4);
71
11.2k
  x->input[10] = U8TO32_LITTLE(k + 8);
72
11.2k
  x->input[11] = U8TO32_LITTLE(k + 12);
73
11.2k
  x->input[0] = U8TO32_LITTLE(constants + 0);
74
11.2k
  x->input[1] = U8TO32_LITTLE(constants + 4);
75
11.2k
  x->input[2] = U8TO32_LITTLE(constants + 8);
76
11.2k
  x->input[3] = U8TO32_LITTLE(constants + 12);
77
11.2k
}
78
79
static void
80
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
81
11.2k
{
82
11.2k
  x->input[12] = 0;
83
11.2k
  x->input[13] = 0;
84
11.2k
  x->input[14] = U8TO32_LITTLE(iv + 0);
85
11.2k
  x->input[15] = U8TO32_LITTLE(iv + 4);
86
11.2k
}
87
88
static void
89
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
90
11.2k
{
91
11.2k
  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
92
11.2k
  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
93
11.2k
  u8 *ctarget = NULL;
94
11.2k
  u8 tmp[64];
95
11.2k
  u_int i;
96
97
11.2k
  if (!bytes) return;
98
99
11.2k
  j0 = x->input[0];
100
11.2k
  j1 = x->input[1];
101
11.2k
  j2 = x->input[2];
102
11.2k
  j3 = x->input[3];
103
11.2k
  j4 = x->input[4];
104
11.2k
  j5 = x->input[5];
105
11.2k
  j6 = x->input[6];
106
11.2k
  j7 = x->input[7];
107
11.2k
  j8 = x->input[8];
108
11.2k
  j9 = x->input[9];
109
11.2k
  j10 = x->input[10];
110
11.2k
  j11 = x->input[11];
111
11.2k
  j12 = x->input[12];
112
11.2k
  j13 = x->input[13];
113
11.2k
  j14 = x->input[14];
114
11.2k
  j15 = x->input[15];
115
116
180k
  for (;;) {
117
180k
    if (bytes < 64) {
118
50
      for (i = 0;i < bytes;++i) tmp[i] = m[i];
119
10
      m = tmp;
120
10
      ctarget = c;
121
10
      c = tmp;
122
10
    }
123
180k
    x0 = j0;
124
180k
    x1 = j1;
125
180k
    x2 = j2;
126
180k
    x3 = j3;
127
180k
    x4 = j4;
128
180k
    x5 = j5;
129
180k
    x6 = j6;
130
180k
    x7 = j7;
131
180k
    x8 = j8;
132
180k
    x9 = j9;
133
180k
    x10 = j10;
134
180k
    x11 = j11;
135
180k
    x12 = j12;
136
180k
    x13 = j13;
137
180k
    x14 = j14;
138
180k
    x15 = j15;
139
1.98M
    for (i = 20;i > 0;i -= 2) {
140
1.80M
      QUARTERROUND( x0, x4, x8,x12)
141
1.80M
      QUARTERROUND( x1, x5, x9,x13)
142
1.80M
      QUARTERROUND( x2, x6,x10,x14)
143
1.80M
      QUARTERROUND( x3, x7,x11,x15)
144
1.80M
      QUARTERROUND( x0, x5,x10,x15)
145
1.80M
      QUARTERROUND( x1, x6,x11,x12)
146
1.80M
      QUARTERROUND( x2, x7, x8,x13)
147
1.80M
      QUARTERROUND( x3, x4, x9,x14)
148
1.80M
    }
149
180k
    x0 = PLUS(x0,j0);
150
180k
    x1 = PLUS(x1,j1);
151
180k
    x2 = PLUS(x2,j2);
152
180k
    x3 = PLUS(x3,j3);
153
180k
    x4 = PLUS(x4,j4);
154
180k
    x5 = PLUS(x5,j5);
155
180k
    x6 = PLUS(x6,j6);
156
180k
    x7 = PLUS(x7,j7);
157
180k
    x8 = PLUS(x8,j8);
158
180k
    x9 = PLUS(x9,j9);
159
180k
    x10 = PLUS(x10,j10);
160
180k
    x11 = PLUS(x11,j11);
161
180k
    x12 = PLUS(x12,j12);
162
180k
    x13 = PLUS(x13,j13);
163
180k
    x14 = PLUS(x14,j14);
164
180k
    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
180k
    j12 = PLUSONE(j12);
186
180k
    if (!j12) {
187
0
      j13 = PLUSONE(j13);
188
      /* stopping at 2^70 bytes per nonce is user's responsibility */
189
0
    }
190
191
180k
    U32TO8_LITTLE(c + 0,x0);
192
180k
    U32TO8_LITTLE(c + 4,x1);
193
180k
    U32TO8_LITTLE(c + 8,x2);
194
180k
    U32TO8_LITTLE(c + 12,x3);
195
180k
    U32TO8_LITTLE(c + 16,x4);
196
180k
    U32TO8_LITTLE(c + 20,x5);
197
180k
    U32TO8_LITTLE(c + 24,x6);
198
180k
    U32TO8_LITTLE(c + 28,x7);
199
180k
    U32TO8_LITTLE(c + 32,x8);
200
180k
    U32TO8_LITTLE(c + 36,x9);
201
180k
    U32TO8_LITTLE(c + 40,x10);
202
180k
    U32TO8_LITTLE(c + 44,x11);
203
180k
    U32TO8_LITTLE(c + 48,x12);
204
180k
    U32TO8_LITTLE(c + 52,x13);
205
180k
    U32TO8_LITTLE(c + 56,x14);
206
180k
    U32TO8_LITTLE(c + 60,x15);
207
208
180k
    if (bytes <= 64) {
209
11.2k
      if (bytes < 64) {
210
50
        for (i = 0;i < bytes;++i) ctarget[i] = c[i];
211
10
      }
212
11.2k
      x->input[12] = j12;
213
11.2k
      x->input[13] = j13;
214
11.2k
      return;
215
11.2k
    }
216
168k
    bytes -= 64;
217
168k
    c += 64;
218
#ifndef KEYSTREAM_ONLY
219
    m += 64;
220
#endif
221
168k
  }
222
11.2k
}