Coverage Report

Created: 2025-12-31 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nettle/arctwo.c
Line
Count
Source
1
/* arctwo.c
2
3
   The cipher described in rfc2268; aka Ron's Cipher 2.
4
   
5
   Copyright (C) 2004 Simon Josefsson
6
   Copyright (C) 2003 Nikos Mavroyanopoulos
7
   Copyright (C) 2004 Free Software Foundation, Inc.
8
   Copyright (C) 2004, 2014 Niels Möller
9
10
   This file is part of GNU Nettle.
11
12
   GNU Nettle is free software: you can redistribute it and/or
13
   modify it under the terms of either:
14
15
     * the GNU Lesser General Public License as published by the Free
16
       Software Foundation; either version 3 of the License, or (at your
17
       option) any later version.
18
19
   or
20
21
     * the GNU General Public License as published by the Free
22
       Software Foundation; either version 2 of the License, or (at your
23
       option) any later version.
24
25
   or both in parallel, as here.
26
27
   GNU Nettle is distributed in the hope that it will be useful,
28
   but WITHOUT ANY WARRANTY; without even the implied warranty of
29
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30
   General Public License for more details.
31
32
   You should have received copies of the GNU General Public License and
33
   the GNU Lesser General Public License along with this program.  If
34
   not, see http://www.gnu.org/licenses/.
35
*/
36
37
/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
38
 * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
39
 * direct use by Libgcrypt by Werner Koch and later adapted for direct
40
 * use by Nettle by Simon Josefsson and Niels Möller.
41
 *
42
 * The implementation here is based on Peter Gutmann's RRC.2 paper and
43
 * RFC 2268.
44
 */
45
46
#if HAVE_CONFIG_H
47
# include "config.h"
48
#endif
49
50
#include <assert.h>
51
52
#include "arctwo.h"
53
54
#include "macros.h"
55
56
static const uint8_t arctwo_sbox[] = {
57
  0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
58
  0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
59
  0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
60
  0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
61
  0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
62
  0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
63
  0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
64
  0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
65
  0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
66
  0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
67
  0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
68
  0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
69
  0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
70
  0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
71
  0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
72
  0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
73
  0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
74
  0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
75
  0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
76
  0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
77
  0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
78
  0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
79
  0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
80
  0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
81
  0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
82
  0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
83
  0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
84
  0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
85
  0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
86
  0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
87
  0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
88
  0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad
89
};
90
91
0
#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n))))
92
68.6k
#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n))))
93
94
void
95
arctwo_encrypt (struct arctwo_ctx *ctx,
96
    size_t length, uint8_t *dst, const uint8_t *src)
97
0
{
98
0
  FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE)
99
0
  {
100
0
    register unsigned i;
101
0
    uint16_t w0, w1, w2, w3;
102
103
0
    w0 = LE_READ_UINT16 (&src[0]);
104
0
    w1 = LE_READ_UINT16 (&src[2]);
105
0
    w2 = LE_READ_UINT16 (&src[4]);
106
0
    w3 = LE_READ_UINT16 (&src[6]);
107
108
0
    for (i = 0; i < 16; i++)
109
0
      {
110
0
  register unsigned j = i * 4;
111
  /* For some reason I cannot combine those steps. */
112
0
  w0 += (w1 & ~w3) + (w2 & w3) + ctx->S[j];
113
0
  w0 = rotl16 (w0, 1);
114
115
0
  w1 += (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1];
116
0
  w1 = rotl16 (w1, 2);
117
118
0
  w2 += (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2];
119
0
  w2 = rotl16 (w2, 3);
120
121
0
  w3 += (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3];
122
0
  w3 = rotl16 (w3, 5);
123
124
0
  if (i == 4 || i == 10)
125
0
    {
126
0
      w0 += ctx->S[w3 & 63];
127
0
      w1 += ctx->S[w0 & 63];
128
0
      w2 += ctx->S[w1 & 63];
129
0
      w3 += ctx->S[w2 & 63];
130
0
    }
131
0
      }
132
0
    LE_WRITE_UINT16 (&dst[0], w0);
133
0
    LE_WRITE_UINT16 (&dst[2], w1);
134
0
    LE_WRITE_UINT16 (&dst[4], w2);
135
0
    LE_WRITE_UINT16 (&dst[6], w3);
136
0
  }
137
0
}
138
139
void
140
arctwo_decrypt (struct arctwo_ctx *ctx,
141
    size_t length, uint8_t *dst, const uint8_t *src)
142
27
{
143
27
  FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE)
144
1.07k
  {
145
1.07k
    register unsigned i;
146
1.07k
    uint16_t w0, w1, w2, w3;
147
148
1.07k
    w0 = LE_READ_UINT16 (&src[0]);
149
1.07k
    w1 = LE_READ_UINT16 (&src[2]);
150
1.07k
    w2 = LE_READ_UINT16 (&src[4]);
151
1.07k
    w3 = LE_READ_UINT16 (&src[6]);
152
153
18.2k
    for (i = 16; i-- > 0; )
154
17.1k
      {
155
17.1k
  register unsigned j = i * 4;
156
157
17.1k
  w3 = rotr16 (w3, 5);
158
17.1k
  w3 -= (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3];
159
160
17.1k
  w2 = rotr16 (w2, 3);
161
17.1k
  w2 -= (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2];
162
163
17.1k
  w1 = rotr16 (w1, 2);
164
17.1k
  w1 -= (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1];
165
166
17.1k
  w0 = rotr16 (w0, 1);
167
17.1k
  w0 -= (w1 & ~w3) + (w2 & w3) + ctx->S[j];
168
169
17.1k
  if (i == 5 || i == 11)
170
2.14k
    {
171
2.14k
      w3 = w3 - ctx->S[w2 & 63];
172
2.14k
      w2 = w2 - ctx->S[w1 & 63];
173
2.14k
      w1 = w1 - ctx->S[w0 & 63];
174
2.14k
      w0 = w0 - ctx->S[w3 & 63];
175
2.14k
    }
176
177
17.1k
      }
178
1.07k
    LE_WRITE_UINT16 (&dst[0], w0);
179
1.07k
    LE_WRITE_UINT16 (&dst[2], w1);
180
1.07k
    LE_WRITE_UINT16 (&dst[4], w2);
181
1.07k
    LE_WRITE_UINT16 (&dst[6], w3);
182
1.07k
  }
183
27
}
184
185
void
186
arctwo_set_key_ekb (struct arctwo_ctx *ctx,
187
        size_t length, const uint8_t *key, unsigned ekb)
188
30
{
189
30
  size_t i;
190
  /* Expanded key, treated as octets */
191
30
  uint8_t S[128];
192
30
  uint8_t x;
193
194
30
  assert (length >= ARCTWO_MIN_KEY_SIZE);
195
30
  assert (length <= ARCTWO_MAX_KEY_SIZE);
196
30
  assert (ekb <= 1024);
197
198
180
  for (i = 0; i < length; i++)
199
150
    S[i] = key[i];
200
201
  /* Phase 1: Expand input key to 128 bytes */
202
3.72k
  for (i = length; i < ARCTWO_MAX_KEY_SIZE; i++)
203
3.69k
    S[i] = arctwo_sbox[(S[i - length] + S[i - 1]) & 255];
204
205
30
  S[0] = arctwo_sbox[S[0]];
206
207
  /* Reduce effective key size to ekb bits, if requested by caller. */
208
30
  if (ekb > 0 && ekb < 1024)
209
30
    {
210
30
      int len = (ekb + 7) >> 3;
211
30
      i = 128 - len;
212
30
      x = arctwo_sbox[S[i] & (255 >> (7 & -ekb))];
213
30
      S[i] = x;
214
215
3.72k
      while (i--)
216
3.69k
  {
217
3.69k
    x = arctwo_sbox[x ^ S[i + len]];
218
3.69k
    S[i] = x;
219
3.69k
  }
220
30
    }
221
222
  /* Make the expanded key endian independent. */
223
1.95k
  for (i = 0; i < 64; i++)
224
1.92k
    ctx->S[i] = LE_READ_UINT16(S + i * 2);
225
30
}
226
227
void
228
arctwo_set_key (struct arctwo_ctx *ctx, size_t length, const uint8_t *key)
229
0
{
230
0
  arctwo_set_key_ekb (ctx, length, key, 8 * length);
231
0
}
232
233
void
234
arctwo_set_key_gutmann (struct arctwo_ctx *ctx,
235
      size_t length, const uint8_t *key)
236
0
{
237
0
  arctwo_set_key_ekb (ctx, length, key, 0);
238
0
}
239
240
void
241
arctwo40_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
242
30
{
243
30
  arctwo_set_key_ekb (ctx, 5, key, 40);
244
30
}
245
void
246
arctwo64_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
247
0
{
248
0
  arctwo_set_key_ekb (ctx, 8, key, 64);
249
0
}
250
251
void
252
arctwo128_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
253
0
{
254
0
  arctwo_set_key_ekb (ctx, 16, key, 128);
255
0
}
256
void
257
arctwo128_set_key_gutmann (struct arctwo_ctx *ctx,
258
         const uint8_t *key)
259
0
{
260
0
  arctwo_set_key_ekb (ctx, 16, key, 1024);
261
0
}