~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/lib/libgcrypt/cipher/rfc2268.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* rfc2268.c  - The cipher described in rfc2268; aka Ron's Cipher 2.
 
2
 * Copyright (C) 2003 Nikos Mavroyanopoulos
 
3
 * Copyright (C) 2004 Free Software Foundation, Inc.
 
4
 *
 
5
 * This file is part of Libgcrypt
 
6
 *
 
7
 * Libgcrypt is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU Lesser general Public License as
 
9
 * published by the Free Software Foundation; either version 2.1 of
 
10
 * the License, or (at your option) any later version.
 
11
 *
 
12
 * Libgcrypt is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
20
 */
 
21
 
 
22
/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
 
23
 * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
 
24
 * direct use by Libgcrypt by Werner Koch.  This implementation is
 
25
 * only useful for pkcs#12 descryption.
 
26
 *
 
27
 * The implementation here is based on Peter Gutmann's RRC.2 paper.
 
28
 */
 
29
 
 
30
 
 
31
#include <config.h>
 
32
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
#include "g10lib.h"
 
36
#include "types.h"
 
37
#include "cipher.h"
 
38
 
 
39
#define RFC2268_BLOCKSIZE 8
 
40
 
 
41
typedef struct 
 
42
{
 
43
  u16 S[64];
 
44
} RFC2268_context;
 
45
 
 
46
static const unsigned char rfc2268_sbox[] = { 
 
47
  217, 120, 249, 196,  25, 221, 181, 237, 
 
48
   40, 233, 253, 121,  74, 160, 216, 157,
 
49
  198, 126,  55, 131,  43, 118,  83, 142, 
 
50
   98,  76, 100, 136,  68, 139, 251, 162,
 
51
   23, 154,  89, 245, 135, 179,  79,  19,
 
52
   97,  69, 109, 141,   9, 129, 125,  50,
 
53
  189, 143,  64, 235, 134, 183, 123,  11,
 
54
  240, 149,  33,  34,  92, 107,  78, 130,
 
55
   84, 214, 101, 147, 206,  96, 178,  28,
 
56
  115,  86, 192,  20, 167, 140, 241, 220,
 
57
   18, 117, 202,  31,  59, 190, 228, 209,
 
58
   66,  61, 212,  48, 163,  60, 182,  38,
 
59
  111, 191,  14, 218,  70, 105,   7,  87,
 
60
   39, 242,  29, 155, 188, 148,  67,   3,
 
61
  248,  17, 199, 246, 144, 239,  62, 231,
 
62
    6, 195, 213,  47, 200, 102,  30, 215,
 
63
    8, 232, 234, 222, 128,  82, 238, 247,
 
64
  132, 170, 114, 172,  53,  77, 106,  42,
 
65
  150,  26, 210, 113,  90,  21,  73, 116,
 
66
   75, 159, 208,  94,   4,  24, 164, 236,
 
67
  194, 224,  65, 110,  15,  81, 203, 204,
 
68
   36, 145, 175,  80, 161, 244, 112,  57,
 
69
  153, 124,  58, 133,  35, 184, 180, 122,
 
70
  252,   2,  54,  91,  37,  85, 151,  49,
 
71
   45,  93, 250, 152, 227, 138, 146, 174,
 
72
    5, 223,  41,  16, 103, 108, 186, 201,
 
73
  211,   0, 230, 207, 225, 158, 168,  44,
 
74
   99,  22,   1,  63,  88, 226, 137, 169,
 
75
   13,  56,  52,  27, 171,  51, 255, 176,
 
76
  187,  72,  12,  95, 185, 177, 205,  46,
 
77
  197, 243, 219,  71, 229, 165, 156, 119,
 
78
   10, 166,  32, 104, 254, 127, 193, 173
 
79
};
 
80
 
 
81
#define rotl16(x,n)   (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
 
82
#define rotr16(x,n)   (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
 
83
 
 
84
static const char *selftest (void);
 
85
 
 
86
 
 
87
static void
 
88
do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
 
89
{
 
90
  RFC2268_context *ctx = context;
 
91
  register int i, j;
 
92
  u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
 
93
 
 
94
  word0 = (word0 << 8) | inbuf[1];
 
95
  word0 = (word0 << 8) | inbuf[0];
 
96
  word1 = (word1 << 8) | inbuf[3];
 
97
  word1 = (word1 << 8) | inbuf[2];
 
98
  word2 = (word2 << 8) | inbuf[5];
 
99
  word2 = (word2 << 8) | inbuf[4];
 
100
  word3 = (word3 << 8) | inbuf[7];
 
101
  word3 = (word3 << 8) | inbuf[6];
 
102
 
 
103
  for (i = 0; i < 16; i++)
 
104
    {
 
105
      j = i * 4;
 
106
      /* For some reason I cannot combine those steps. */
 
107
      word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
 
108
      word0 = rotl16(word0, 1);
 
109
                
 
110
      word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
 
111
      word1 = rotl16(word1, 2);
 
112
                
 
113
      word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
 
114
      word2 = rotl16(word2, 3);
 
115
 
 
116
      word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
 
117
      word3 = rotl16(word3, 5);
 
118
 
 
119
      if (i == 4 || i == 10)
 
120
        {
 
121
          word0 += ctx->S[word3 & 63];
 
122
          word1 += ctx->S[word0 & 63];
 
123
          word2 += ctx->S[word1 & 63];
 
124
          word3 += ctx->S[word2 & 63];
 
125
        }
 
126
 
 
127
    }
 
128
 
 
129
  outbuf[0] = word0 & 255;
 
130
  outbuf[1] = word0 >> 8;
 
131
  outbuf[2] = word1 & 255;
 
132
  outbuf[3] = word1 >> 8;
 
133
  outbuf[4] = word2 & 255;
 
134
  outbuf[5] = word2 >> 8;
 
135
  outbuf[6] = word3 & 255;
 
136
  outbuf[7] = word3 >> 8;
 
137
}
 
138
 
 
139
static void
 
140
do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
 
141
{
 
142
  RFC2268_context *ctx = context;
 
143
  register int i, j;
 
144
  u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
 
145
 
 
146
  word0 = (word0 << 8) | inbuf[1];
 
147
  word0 = (word0 << 8) | inbuf[0];
 
148
  word1 = (word1 << 8) | inbuf[3];
 
149
  word1 = (word1 << 8) | inbuf[2];
 
150
  word2 = (word2 << 8) | inbuf[5];
 
151
  word2 = (word2 << 8) | inbuf[4];
 
152
  word3 = (word3 << 8) | inbuf[7];
 
153
  word3 = (word3 << 8) | inbuf[6];
 
154
 
 
155
  for (i = 15; i >= 0; i--) 
 
156
    {
 
157
      j = i * 4;
 
158
 
 
159
      word3 = rotr16(word3, 5);
 
160
      word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
 
161
 
 
162
      word2 = rotr16(word2, 3);
 
163
      word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
 
164
 
 
165
      word1 = rotr16(word1, 2);
 
166
      word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
 
167
 
 
168
      word0 = rotr16(word0, 1);
 
169
      word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
 
170
 
 
171
      if (i == 5 || i == 11) 
 
172
        {
 
173
          word3 = word3 - ctx->S[word2 & 63];
 
174
          word2 = word2 - ctx->S[word1 & 63];
 
175
          word1 = word1 - ctx->S[word0 & 63];
 
176
          word0 = word0 - ctx->S[word3 & 63];
 
177
        }
 
178
 
 
179
    }
 
180
 
 
181
  outbuf[0] = word0 & 255;
 
182
  outbuf[1] = word0 >> 8;
 
183
  outbuf[2] = word1 & 255;
 
184
  outbuf[3] = word1 >> 8;
 
185
  outbuf[4] = word2 & 255;
 
186
  outbuf[5] = word2 >> 8;
 
187
  outbuf[6] = word3 & 255;
 
188
  outbuf[7] = word3 >> 8;
 
189
}
 
190
 
 
191
 
 
192
static gpg_err_code_t
 
193
setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
 
194
{
 
195
  static int initialized;
 
196
  static const char *selftest_failed;
 
197
  RFC2268_context *ctx = context;
 
198
  unsigned int i;
 
199
  unsigned char *S, x;
 
200
  int len;
 
201
  int bits = keylen * 8;
 
202
 
 
203
  if (!initialized)
 
204
    {
 
205
      initialized = 1;
 
206
      selftest_failed = selftest ();
 
207
      if (selftest_failed)
 
208
        log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
 
209
    }
 
210
  if (selftest_failed)
 
211
    return GPG_ERR_SELFTEST_FAILED;
 
212
 
 
213
  if (keylen < 40 / 8)  /* We want at least 40 bits. */
 
214
    return GPG_ERR_INV_KEYLEN;
 
215
 
 
216
  S = (unsigned char *) ctx->S;
 
217
  
 
218
  for (i = 0; i < keylen; i++)
 
219
    S[i] = key[i];
 
220
 
 
221
  for (i = keylen; i < 128; i++)
 
222
    S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
 
223
 
 
224
  S[0] = rfc2268_sbox[S[0]];
 
225
 
 
226
  /* Phase 2 - reduce effective key size to "bits". This was not
 
227
   * discussed in Gutmann's paper. I've copied that from the public
 
228
   * domain code posted in sci.crypt. */
 
229
  if (with_phase2)
 
230
    {
 
231
      len = (bits + 7) >> 3;
 
232
      i = 128 - len;
 
233
      x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
 
234
      S[i] = x;
 
235
      
 
236
      while (i--) 
 
237
        {
 
238
          x = rfc2268_sbox[x ^ S[i + len]];
 
239
          S[i] = x;
 
240
        }
 
241
    }
 
242
 
 
243
  /* Make the expanded key, endian independent. */
 
244
  for (i = 0; i < 64; i++) 
 
245
    ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
 
246
 
 
247
  return 0;
 
248
}
 
249
 
 
250
static gpg_err_code_t
 
251
do_setkey (void *context, const unsigned char *key, unsigned int keylen)
 
252
{
 
253
  return setkey_core (context, key, keylen, 1);
 
254
}
 
255
 
 
256
static const char *
 
257
selftest (void)
 
258
{
 
259
  RFC2268_context ctx;
 
260
  unsigned char scratch[16];
 
261
 
 
262
  /* Test vectors from Peter Gutmann's paper. */
 
263
  static unsigned char key_1[] =
 
264
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
265
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 
266
    };
 
267
  static unsigned char plaintext_1[] =
 
268
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
269
  static const unsigned char ciphertext_1[] =
 
270
    { 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
 
271
 
 
272
  static unsigned char key_2[] =
 
273
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 
274
      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
 
275
    };
 
276
  static unsigned char plaintext_2[] =
 
277
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
278
  static unsigned char ciphertext_2[] =
 
279
    { 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
 
280
 
 
281
  /* This one was checked against libmcrypt's RFC2268. */
 
282
  static unsigned char key_3[] =
 
283
    { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
284
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 
285
    };
 
286
  static unsigned char plaintext_3[] =
 
287
    { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
288
  static unsigned char ciphertext_3[] =
 
289
    { 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
 
290
 
 
291
 
 
292
  /* First test. */
 
293
  setkey_core (&ctx, key_1, sizeof(key_1), 0);
 
294
  do_encrypt (&ctx, scratch, plaintext_1);
 
295
 
 
296
  if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
 
297
    return "RFC2268 encryption test 1 failed.";
 
298
 
 
299
  setkey_core (&ctx, key_1, sizeof(key_1), 0);
 
300
  do_decrypt (&ctx, scratch, scratch); 
 
301
  if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
 
302
    return "RFC2268 decryption test 1 failed.";
 
303
 
 
304
  /* Second test. */
 
305
  setkey_core (&ctx, key_2, sizeof(key_2), 0);
 
306
  do_encrypt (&ctx, scratch, plaintext_2);
 
307
  if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
 
308
    return "RFC2268 encryption test 2 failed.";
 
309
 
 
310
  setkey_core (&ctx, key_2, sizeof(key_2), 0);
 
311
  do_decrypt (&ctx, scratch, scratch); 
 
312
  if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
 
313
    return "RFC2268 decryption test 2 failed.";
 
314
 
 
315
  /* Third test. */
 
316
  setkey_core(&ctx, key_3, sizeof(key_3), 0);
 
317
  do_encrypt(&ctx, scratch, plaintext_3);
 
318
 
 
319
  if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
 
320
    return "RFC2268 encryption test 3 failed.";
 
321
 
 
322
  setkey_core (&ctx, key_3, sizeof(key_3), 0);
 
323
  do_decrypt (&ctx, scratch, scratch); 
 
324
  if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
 
325
    return "RFC2268 decryption test 3 failed.";
 
326
 
 
327
  return NULL;
 
328
}
 
329
 
 
330
 
 
331
 
 
332
static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
 
333
  {
 
334
    /*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
 
335
    /* pbeWithSHAAnd40BitRC2_CBC */
 
336
    { "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
 
337
    { NULL }
 
338
  };
 
339
 
 
340
gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
 
341
  "RFC2268_40", NULL, oids_rfc2268_40,
 
342
  RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
 
343
  do_setkey, do_encrypt, do_decrypt
 
344
};
 
345