Coverage Report

Created: 2022-08-24 06:31

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