Coverage Report

Created: 2025-08-28 06:59

/src/boringssl/crypto/cipher/e_rc2.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/cipher.h>
16
#include <openssl/nid.h>
17
18
#include "../fipsmodule/cipher/internal.h"
19
#include "../internal.h"
20
21
22
#define c2l(c, l)                         \
23
1.21k
  do {                                    \
24
1.21k
    (l) = ((uint32_t)(*((c)++)));         \
25
1.21k
    (l) |= ((uint32_t)(*((c)++))) << 8L;  \
26
1.21k
    (l) |= ((uint32_t)(*((c)++))) << 16L; \
27
1.21k
    (l) |= ((uint32_t)(*((c)++))) << 24L; \
28
1.21k
  } while (0)
29
30
#define c2ln(c, l1, l2, n)                     \
31
0
  do {                                         \
32
0
    (c) += (n);                                \
33
0
    (l1) = (l2) = 0;                           \
34
0
    switch (n) {                               \
35
0
      case 8:                                  \
36
0
        (l2) = ((uint32_t)(*(--(c)))) << 24L;  \
37
0
        [[fallthrough]];                       \
38
0
      case 7:                                  \
39
0
        (l2) |= ((uint32_t)(*(--(c)))) << 16L; \
40
0
        [[fallthrough]];                       \
41
0
      case 6:                                  \
42
0
        (l2) |= ((uint32_t)(*(--(c)))) << 8L;  \
43
0
        [[fallthrough]];                       \
44
0
      case 5:                                  \
45
0
        (l2) |= ((uint32_t)(*(--(c))));        \
46
0
        [[fallthrough]];                       \
47
0
      case 4:                                  \
48
0
        (l1) = ((uint32_t)(*(--(c)))) << 24L;  \
49
0
        [[fallthrough]];                       \
50
0
      case 3:                                  \
51
0
        (l1) |= ((uint32_t)(*(--(c)))) << 16L; \
52
0
        [[fallthrough]];                       \
53
0
      case 2:                                  \
54
0
        (l1) |= ((uint32_t)(*(--(c)))) << 8L;  \
55
0
        [[fallthrough]];                       \
56
0
      case 1:                                  \
57
0
        (l1) |= ((uint32_t)(*(--(c))));        \
58
0
    }                                          \
59
0
  } while (0)
60
61
#define l2c(l, c)                              \
62
1.21k
  do {                                         \
63
1.21k
    *((c)++) = (uint8_t)(((l)) & 0xff);        \
64
1.21k
    *((c)++) = (uint8_t)(((l) >> 8L) & 0xff);  \
65
1.21k
    *((c)++) = (uint8_t)(((l) >> 16L) & 0xff); \
66
1.21k
    *((c)++) = (uint8_t)(((l) >> 24L) & 0xff); \
67
1.21k
  } while (0)
68
69
#define l2cn(l1, l2, c, n)                          \
70
0
  do {                                              \
71
0
    (c) += (n);                                     \
72
0
    switch (n) {                                    \
73
0
      case 8:                                       \
74
0
        *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
75
0
        [[fallthrough]];                            \
76
0
      case 7:                                       \
77
0
        *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
78
0
        [[fallthrough]];                            \
79
0
      case 6:                                       \
80
0
        *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff);  \
81
0
        [[fallthrough]];                            \
82
0
      case 5:                                       \
83
0
        *(--(c)) = (uint8_t)(((l2)) & 0xff);        \
84
0
        [[fallthrough]];                            \
85
0
      case 4:                                       \
86
0
        *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
87
0
        [[fallthrough]];                            \
88
0
      case 3:                                       \
89
0
        *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
90
0
        [[fallthrough]];                            \
91
0
      case 2:                                       \
92
0
        *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff);  \
93
0
        [[fallthrough]];                            \
94
0
      case 1:                                       \
95
0
        *(--(c)) = (uint8_t)(((l1)) & 0xff);        \
96
0
    }                                               \
97
0
  } while (0)
98
99
typedef struct rc2_key_st {
100
  uint16_t data[64];
101
} RC2_KEY;
102
103
0
static void RC2_encrypt(uint32_t *d, RC2_KEY *key) {
104
0
  int i, n;
105
0
  uint16_t *p0, *p1;
106
0
  uint16_t x0, x1, x2, x3, t;
107
0
  uint32_t l;
108
109
0
  l = d[0];
110
0
  x0 = (uint16_t)l & 0xffff;
111
0
  x1 = (uint16_t)(l >> 16L);
112
0
  l = d[1];
113
0
  x2 = (uint16_t)l & 0xffff;
114
0
  x3 = (uint16_t)(l >> 16L);
115
116
0
  n = 3;
117
0
  i = 5;
118
119
0
  p0 = p1 = &key->data[0];
120
0
  for (;;) {
121
0
    t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff;
122
0
    x0 = (t << 1) | (t >> 15);
123
0
    t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff;
124
0
    x1 = (t << 2) | (t >> 14);
125
0
    t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff;
126
0
    x2 = (t << 3) | (t >> 13);
127
0
    t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff;
128
0
    x3 = (t << 5) | (t >> 11);
129
130
0
    if (--i == 0) {
131
0
      if (--n == 0) {
132
0
        break;
133
0
      }
134
0
      i = (n == 2) ? 6 : 5;
135
136
0
      x0 += p1[x3 & 0x3f];
137
0
      x1 += p1[x0 & 0x3f];
138
0
      x2 += p1[x1 & 0x3f];
139
0
      x3 += p1[x2 & 0x3f];
140
0
    }
141
0
  }
142
143
0
  d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L);
144
0
  d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L);
145
0
}
146
147
602
static void RC2_decrypt(uint32_t *d, RC2_KEY *key) {
148
602
  int i, n;
149
602
  uint16_t *p0, *p1;
150
602
  uint16_t x0, x1, x2, x3, t;
151
602
  uint32_t l;
152
153
602
  l = d[0];
154
602
  x0 = (uint16_t)l & 0xffff;
155
602
  x1 = (uint16_t)(l >> 16L);
156
602
  l = d[1];
157
602
  x2 = (uint16_t)l & 0xffff;
158
602
  x3 = (uint16_t)(l >> 16L);
159
160
602
  n = 3;
161
602
  i = 5;
162
163
602
  p0 = &key->data[63];
164
602
  p1 = &key->data[0];
165
9.63k
  for (;;) {
166
9.63k
    t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
167
9.63k
    x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff;
168
9.63k
    t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
169
9.63k
    x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff;
170
9.63k
    t = ((x1 << 14) | (x1 >> 2)) & 0xffff;
171
9.63k
    x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff;
172
9.63k
    t = ((x0 << 15) | (x0 >> 1)) & 0xffff;
173
9.63k
    x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff;
174
175
9.63k
    if (--i == 0) {
176
1.80k
      if (--n == 0) {
177
602
        break;
178
602
      }
179
1.20k
      i = (n == 2) ? 6 : 5;
180
181
1.20k
      x3 = (x3 - p1[x2 & 0x3f]) & 0xffff;
182
1.20k
      x2 = (x2 - p1[x1 & 0x3f]) & 0xffff;
183
1.20k
      x1 = (x1 - p1[x0 & 0x3f]) & 0xffff;
184
1.20k
      x0 = (x0 - p1[x3 & 0x3f]) & 0xffff;
185
1.20k
    }
186
9.63k
  }
187
188
602
  d[0] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L);
189
602
  d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L);
190
602
}
191
192
static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
193
5
                            RC2_KEY *ks, uint8_t *iv, int encrypt) {
194
5
  uint32_t tin0, tin1;
195
5
  uint32_t tout0, tout1, xor0, xor1;
196
5
  long l = length;
197
5
  uint32_t tin[2];
198
199
5
  if (encrypt) {
200
0
    c2l(iv, tout0);
201
0
    c2l(iv, tout1);
202
0
    iv -= 8;
203
0
    for (l -= 8; l >= 0; l -= 8) {
204
0
      c2l(in, tin0);
205
0
      c2l(in, tin1);
206
0
      tin0 ^= tout0;
207
0
      tin1 ^= tout1;
208
0
      tin[0] = tin0;
209
0
      tin[1] = tin1;
210
0
      RC2_encrypt(tin, ks);
211
0
      tout0 = tin[0];
212
0
      l2c(tout0, out);
213
0
      tout1 = tin[1];
214
0
      l2c(tout1, out);
215
0
    }
216
0
    if (l != -8) {
217
0
      c2ln(in, tin0, tin1, l + 8);
218
0
      tin0 ^= tout0;
219
0
      tin1 ^= tout1;
220
0
      tin[0] = tin0;
221
0
      tin[1] = tin1;
222
0
      RC2_encrypt(tin, ks);
223
0
      tout0 = tin[0];
224
0
      l2c(tout0, out);
225
0
      tout1 = tin[1];
226
0
      l2c(tout1, out);
227
0
    }
228
0
    l2c(tout0, iv);
229
0
    l2c(tout1, iv);
230
5
  } else {
231
5
    c2l(iv, xor0);
232
5
    c2l(iv, xor1);
233
5
    iv -= 8;
234
607
    for (l -= 8; l >= 0; l -= 8) {
235
602
      c2l(in, tin0);
236
602
      tin[0] = tin0;
237
602
      c2l(in, tin1);
238
602
      tin[1] = tin1;
239
602
      RC2_decrypt(tin, ks);
240
602
      tout0 = tin[0] ^ xor0;
241
602
      tout1 = tin[1] ^ xor1;
242
602
      l2c(tout0, out);
243
602
      l2c(tout1, out);
244
602
      xor0 = tin0;
245
602
      xor1 = tin1;
246
602
    }
247
5
    if (l != -8) {
248
0
      c2l(in, tin0);
249
0
      tin[0] = tin0;
250
0
      c2l(in, tin1);
251
0
      tin[1] = tin1;
252
0
      RC2_decrypt(tin, ks);
253
0
      tout0 = tin[0] ^ xor0;
254
0
      tout1 = tin[1] ^ xor1;
255
0
      l2cn(tout0, tout1, out, l + 8);
256
0
      xor0 = tin0;
257
0
      xor1 = tin1;
258
0
    }
259
5
    l2c(xor0, iv);
260
5
    l2c(xor1, iv);
261
5
  }
262
5
  tin[0] = tin[1] = 0;
263
5
}
264
265
static const uint8_t key_table[256] = {
266
    0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79,
267
    0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
268
    0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5,
269
    0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
270
    0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22,
271
    0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
272
    0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f,
273
    0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
274
    0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b,
275
    0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
276
    0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde,
277
    0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
278
    0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e,
279
    0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
280
    0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85,
281
    0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
282
    0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10,
283
    0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
284
    0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b,
285
    0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
286
    0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68,
287
    0xfe, 0x7f, 0xc1, 0xad,
288
};
289
290
5
static void RC2_set_key(RC2_KEY *key, int len, const uint8_t *data, int bits) {
291
5
  int i, j;
292
5
  uint8_t *k;
293
5
  uint16_t *ki;
294
5
  unsigned int c, d;
295
296
5
  k = (uint8_t *)&key->data[0];
297
5
  *k = 0;  // for if there is a zero length key
298
299
5
  if (len > 128) {
300
0
    len = 128;
301
0
  }
302
5
  if (bits <= 0) {
303
0
    bits = 1024;
304
0
  }
305
5
  if (bits > 1024) {
306
0
    bits = 1024;
307
0
  }
308
309
30
  for (i = 0; i < len; i++) {
310
25
    k[i] = data[i];
311
25
  }
312
313
  // expand table
314
5
  d = k[len - 1];
315
5
  j = 0;
316
620
  for (i = len; i < 128; i++, j++) {
317
615
    d = key_table[(k[j] + d) & 0xff];
318
615
    k[i] = d;
319
615
  }
320
321
  // hmm.... key reduction to 'bits' bits
322
323
5
  j = (bits + 7) >> 3;
324
5
  i = 128 - j;
325
5
  c = (0xff >> (-bits & 0x07));
326
327
5
  d = key_table[k[i] & c];
328
5
  k[i] = d;
329
620
  while (i--) {
330
615
    d = key_table[k[i + j] ^ d];
331
615
    k[i] = d;
332
615
  }
333
334
  // copy from bytes into uint16_t's
335
5
  ki = &(key->data[63]);
336
325
  for (i = 127; i >= 0; i -= 2) {
337
320
    *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff;
338
320
  }
339
5
}
340
341
typedef struct {
342
  int key_bits;  // effective key bits
343
  RC2_KEY ks;    // key schedule
344
} EVP_RC2_KEY;
345
346
static int rc2_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
347
5
                        const uint8_t *iv, int enc) {
348
5
  EVP_RC2_KEY *rc2_key = (EVP_RC2_KEY *)ctx->cipher_data;
349
5
  RC2_set_key(&rc2_key->ks, EVP_CIPHER_CTX_key_length(ctx), key,
350
5
              rc2_key->key_bits);
351
5
  return 1;
352
5
}
353
354
static int rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
355
5
                          size_t inl) {
356
5
  EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
357
5
  static const size_t kChunkSize = 0x10000;
358
359
5
  while (inl >= kChunkSize) {
360
0
    RC2_cbc_encrypt(in, out, kChunkSize, &key->ks, ctx->iv, ctx->encrypt);
361
0
    inl -= kChunkSize;
362
0
    in += kChunkSize;
363
0
    out += kChunkSize;
364
0
  }
365
5
  if (inl) {
366
5
    RC2_cbc_encrypt(in, out, inl, &key->ks, ctx->iv, ctx->encrypt);
367
5
  }
368
5
  return 1;
369
5
}
370
371
5
static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) {
372
5
  EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data;
373
374
5
  switch (type) {
375
5
    case EVP_CTRL_INIT:
376
5
      key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
377
5
      return 1;
378
0
    case EVP_CTRL_SET_RC2_KEY_BITS:
379
      // Should be overridden by later call to |EVP_CTRL_INIT|, but
380
      // people call it, so it may as well work.
381
0
      key->key_bits = arg;
382
0
      return 1;
383
384
0
    default:
385
0
      return -1;
386
5
  }
387
5
}
388
389
static const EVP_CIPHER rc2_40_cbc = {
390
    /*nid=*/NID_rc2_40_cbc,
391
    /*block_size=*/8,
392
    /*key_len=*/5 /* 40 bit */,
393
    /*iv_len=*/8,
394
    /*ctx_size=*/sizeof(EVP_RC2_KEY),
395
    /*flags=*/EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
396
    /*init=*/rc2_init_key,
397
    /*cipher=*/rc2_cbc_cipher,
398
    /*cleanup=*/nullptr,
399
    /*ctrl=*/rc2_ctrl,
400
};
401
402
5
const EVP_CIPHER *EVP_rc2_40_cbc(void) { return &rc2_40_cbc; }
403
404
static const EVP_CIPHER rc2_cbc = {
405
    /*nid=*/NID_rc2_cbc,
406
    /*block_size=*/8,
407
    /*key_len=*/16 /* 128 bit */,
408
    /*iv_len=*/8,
409
    /*ctx_size=*/sizeof(EVP_RC2_KEY),
410
    /*flags=*/EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
411
    /*init=*/rc2_init_key,
412
    /*cipher=*/rc2_cbc_cipher,
413
    /*cleanup=*/nullptr,
414
    /*ctrl=*/rc2_ctrl,
415
};
416
417
0
const EVP_CIPHER *EVP_rc2_cbc(void) { return &rc2_cbc; }