~ubuntu-branches/debian/lenny/dropbear/lenny

« back to all changes in this revision

Viewing changes to libtomcrypt/rc4.c

  • Committer: Bazaar Package Importer
  • Author(s): Gerrit Pape
  • Date: 2005-05-25 22:38:17 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050525223817-fdl653extybmz1zb
Tags: 0.45-3
* debian/dropbear.init: init script prints human readable message in case
  it's disabled (closes: #309099).
* debian/dropbear.postinst: configure: restart service through init script
  instead of start.
* debian/dropbear.prerm: set -u -> set -e.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 
15
15
const struct _prng_descriptor rc4_desc = 
16
16
{
17
 
   "rc4",
 
17
   "rc4", 32,
18
18
    &rc4_start,
19
19
    &rc4_add_entropy,
20
20
    &rc4_ready,
21
 
    &rc4_read
 
21
    &rc4_read,
 
22
    &rc4_done,
 
23
    &rc4_export,
 
24
    &rc4_import,
 
25
    &rc4_test
22
26
};
23
27
 
24
28
int rc4_start(prng_state *prng)
33
37
 
34
38
int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
35
39
{
36
 
    _ARGCHK(buf != NULL);
 
40
    _ARGCHK(buf  != NULL);
37
41
    _ARGCHK(prng != NULL);
38
 
 
 
42
 
 
43
    /* trim as required */
39
44
    if (prng->rc4.x + len > 256) {
40
 
       return CRYPT_INVALID_KEYSIZE;
 
45
       if (prng->rc4.x == 256) {
 
46
          /* I can't possibly accept another byte, ok maybe a mint wafer... */
 
47
          return CRYPT_OK;
 
48
       } else {
 
49
          /* only accept part of it */
 
50
          len = 256 - prng->rc4.x;
 
51
       }       
41
52
    }
42
53
 
43
54
    while (len--) {
50
61
 
51
62
int rc4_ready(prng_state *prng)
52
63
{
53
 
    unsigned char key[256], tmp;
54
 
    int keylen, x, y;
 
64
    unsigned char key[256], tmp, *s;
 
65
    int keylen, x, y, j;
55
66
 
56
67
    _ARGCHK(prng != NULL);
57
68
 
58
69
    /* extract the key */
59
 
    memcpy(key, prng->rc4.buf, 256);
 
70
    s = prng->rc4.buf;
 
71
    XMEMCPY(key, s, 256);
60
72
    keylen = prng->rc4.x;
61
73
 
62
74
    /* make RC4 perm and shuffle */
63
75
    for (x = 0; x < 256; x++) {
64
 
        prng->rc4.buf[x] = x;
 
76
        s[x] = x;
65
77
    }
66
78
 
67
 
    for (x = y = 0; x < 256; x++) {
68
 
        y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255;
69
 
        tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp;
 
79
    for (j = x = y = 0; x < 256; x++) {
 
80
        y = (y + prng->rc4.buf[x] + key[j++]) & 255;
 
81
        if (j == keylen) {
 
82
           j = 0; 
 
83
        }
 
84
        tmp = s[x]; s[x] = s[y]; s[y] = tmp;
70
85
    }
71
 
    prng->rc4.x = x;
72
 
    prng->rc4.y = y;
 
86
    prng->rc4.x = 0;
 
87
    prng->rc4.y = 0;
73
88
 
74
89
#ifdef CLEAN_STACK
75
90
    zeromem(key, sizeof(key));
80
95
 
81
96
unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
82
97
{
83
 
   int x, y; 
84
 
   unsigned char *s, tmp;
 
98
   unsigned char x, y, *s, tmp;
85
99
   unsigned long n;
86
100
 
87
101
   _ARGCHK(buf != NULL);
103
117
   return n;
104
118
}
105
119
 
 
120
int rc4_done(prng_state *prng)
 
121
{
 
122
   _ARGCHK(prng != NULL);
 
123
   return CRYPT_OK;
 
124
}
 
125
 
 
126
int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
 
127
{
 
128
   _ARGCHK(outlen != NULL);
 
129
   _ARGCHK(out    != NULL);
 
130
   _ARGCHK(prng   != NULL);
 
131
 
 
132
   if (*outlen < 32) {
 
133
      return CRYPT_BUFFER_OVERFLOW;
 
134
   }
 
135
 
 
136
   if (rc4_read(out, 32, prng) != 32) {
 
137
      return CRYPT_ERROR_READPRNG;
 
138
   }
 
139
   *outlen = 32;
 
140
 
 
141
   return CRYPT_OK;
 
142
}
 
143
 
 
144
int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 
145
{
 
146
   int err;
 
147
   _ARGCHK(in   != NULL);
 
148
   _ARGCHK(prng != NULL);
 
149
 
 
150
   if (inlen != 32) {
 
151
      return CRYPT_INVALID_ARG;
 
152
   }
 
153
   
 
154
   if ((err = rc4_start(prng)) != CRYPT_OK) {
 
155
      return err;
 
156
   }
 
157
   return rc4_add_entropy(in, 32, prng);
 
158
}
 
159
 
 
160
int rc4_test(void)
 
161
{
 
162
#ifndef LTC_TEST
 
163
   return CRYPT_NOP;
 
164
#else
 
165
   static const struct {
 
166
      unsigned char key[8], pt[8], ct[8];
 
167
   } tests[] = {
 
168
{
 
169
   { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 
170
   { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 
171
   { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 }
 
172
}
 
173
};
 
174
   prng_state prng;
 
175
   unsigned char dst[8];
 
176
   int err, x;
 
177
 
 
178
   for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
 
179
       if ((err = rc4_start(&prng)) != CRYPT_OK) {
 
180
          return err;
 
181
       }
 
182
       if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) {
 
183
          return err;
 
184
       }
 
185
       if ((err = rc4_ready(&prng)) != CRYPT_OK) {
 
186
          return err;
 
187
       }
 
188
       XMEMCPY(dst, tests[x].pt, 8);
 
189
       if (rc4_read(dst, 8, &prng) != 8) {
 
190
          return CRYPT_ERROR_READPRNG;
 
191
       }
 
192
       rc4_done(&prng);
 
193
       if (memcmp(dst, tests[x].ct, 8)) {
 
194
#if 0
 
195
          int y;
 
196
          printf("\n\nRC4 failed, I got:\n"); 
 
197
          for (y = 0; y < 8; y++) printf("%02x ", dst[y]);
 
198
          printf("\n");
 
199
#endif
 
200
          return CRYPT_FAIL_TESTVECTOR;
 
201
       }
 
202
   }
 
203
   return CRYPT_OK;
 
204
#endif
 
205
}
 
206
 
106
207
#endif
107
208