~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

« back to all changes in this revision

Viewing changes to libtomcrypt/md2.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Johnston
  • Date: 2005-12-08 19:20:21 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208192021-nyp9rwnt77nsg6ty
Tags: 0.47-1
* New upstream release.
* SECURITY: Fix incorrect buffer sizing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
 
 *
3
 
 * LibTomCrypt is a library that provides various cryptographic
4
 
 * algorithms in a highly modular and flexible manner.
5
 
 *
6
 
 * The library is free for all purposes without any express
7
 
 * guarantee it works.
8
 
 *
9
 
 * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
10
 
 */
11
 
/* MD2 (RFC 1319) hash function implementation by Tom St Denis */
12
 
#include "mycrypt.h"
13
 
 
14
 
#ifdef MD2
15
 
 
16
 
const struct _hash_descriptor md2_desc =
17
 
{
18
 
    "md2",
19
 
    7,
20
 
    16,
21
 
    16,
22
 
 
23
 
    /* DER encoding */
24
 
    { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 
25
 
      0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 
26
 
      0x04, 0x10 },
27
 
    18,
28
 
 
29
 
    &md2_init,
30
 
    &md2_process,
31
 
    &md2_done,
32
 
    &md2_test
33
 
};
34
 
 
35
 
static const unsigned char PI_SUBST[256] = {
36
 
  41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
37
 
  19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
38
 
  76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
39
 
  138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
40
 
  245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
41
 
  148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
42
 
  39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
43
 
  181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
44
 
  150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
45
 
  112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
46
 
  96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
47
 
  85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
48
 
  234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
49
 
  129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
50
 
  8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
51
 
  203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
52
 
  166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
53
 
  31, 26, 219, 153, 141, 51, 159, 17, 131, 20
54
 
};
55
 
 
56
 
/* adds 16 bytes to the checksum */
57
 
static void md2_update_chksum(hash_state *md)
58
 
{
59
 
   int j;
60
 
   unsigned char L;
61
 
   L = md->md2.chksum[15];
62
 
   for (j = 0; j < 16; j++) {
63
 
 
64
 
/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say 
65
 
   otherwise.
66
 
*/
67
 
       L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255);
68
 
   }
69
 
}
70
 
 
71
 
static void md2_compress(hash_state *md)
72
 
{
73
 
   int j, k;
74
 
   unsigned char t;
75
 
   
76
 
   /* copy block */
77
 
   for (j = 0; j < 16; j++) {
78
 
       md->md2.X[16+j] = md->md2.buf[j];
79
 
       md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j];
80
 
   }
81
 
 
82
 
   t = (unsigned char)0;
83
 
 
84
 
   /* do 18 rounds */
85
 
   for (j = 0; j < 18; j++) {
86
 
       for (k = 0; k < 48; k++) {
87
 
           t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]);
88
 
       }
89
 
       t = (t + (unsigned char)j) & 255;
90
 
   }
91
 
}
92
 
 
93
 
int md2_init(hash_state *md)
94
 
{
95
 
   _ARGCHK(md != NULL);
96
 
 
97
 
   /* MD2 uses a zero'ed state... */
98
 
   zeromem(md->md2.X, sizeof(md->md2.X));
99
 
   zeromem(md->md2.chksum, sizeof(md->md2.chksum));
100
 
   zeromem(md->md2.buf, sizeof(md->md2.buf));
101
 
   md->md2.curlen = 0;
102
 
   return CRYPT_OK;
103
 
}
104
 
 
105
 
int md2_process(hash_state *md, const unsigned char *buf, unsigned long len)
106
 
{
107
 
    unsigned long n;
108
 
    _ARGCHK(md != NULL);
109
 
    _ARGCHK(buf != NULL);
110
 
    if (md-> md2 .curlen > sizeof(md-> md2 .buf)) {                            
111
 
       return CRYPT_INVALID_ARG;                                                           
112
 
    }                                                                                       
113
 
    while (len > 0) {
114
 
        n = MIN(len, (16 - md->md2.curlen));
115
 
        XMEMCPY(md->md2.buf + md->md2.curlen, buf, (size_t)n);
116
 
        md->md2.curlen += n;
117
 
        buf            += n;
118
 
        len            -= n;
119
 
 
120
 
        /* is 16 bytes full? */
121
 
        if (md->md2.curlen == 16) {
122
 
            md2_compress(md);
123
 
            md2_update_chksum(md);
124
 
            md->md2.curlen = 0;
125
 
        }
126
 
    }
127
 
    return CRYPT_OK;
128
 
}
129
 
 
130
 
int md2_done(hash_state * md, unsigned char *hash)
131
 
{
132
 
    unsigned long i, k;
133
 
 
134
 
    _ARGCHK(md != NULL);
135
 
    _ARGCHK(hash != NULL);
136
 
 
137
 
    if (md->md2.curlen >= sizeof(md->md2.buf)) {
138
 
       return CRYPT_INVALID_ARG;
139
 
    }
140
 
 
141
 
 
142
 
    /* pad the message */
143
 
    k = 16 - md->md2.curlen;
144
 
    for (i = md->md2.curlen; i < 16; i++) {
145
 
        md->md2.buf[i] = (unsigned char)k;
146
 
    }
147
 
 
148
 
    /* hash and update */
149
 
    md2_compress(md);
150
 
    md2_update_chksum(md);
151
 
 
152
 
    /* hash checksum */
153
 
    XMEMCPY(md->md2.buf, md->md2.chksum, 16);
154
 
    md2_compress(md);
155
 
 
156
 
    /* output is lower 16 bytes of X */
157
 
    XMEMCPY(hash, md->md2.X, 16);
158
 
 
159
 
#ifdef CLEAN_STACK
160
 
    zeromem(md, sizeof(hash_state));
161
 
#endif
162
 
    return CRYPT_OK;
163
 
}
164
 
 
165
 
int md2_test(void)
166
 
{
167
 
 #ifndef LTC_TEST
168
 
    return CRYPT_NOP;
169
 
 #else    
170
 
   static const struct {
171
 
        char *msg;
172
 
        unsigned char md[16];
173
 
   } tests[] = {
174
 
      { "",
175
 
        {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
176
 
         0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
177
 
        }
178
 
      },
179
 
      { "a",
180
 
        {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
181
 
         0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
182
 
        }
183
 
      },
184
 
      { "message digest",
185
 
        {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
186
 
         0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
187
 
        }
188
 
      },
189
 
      { "abcdefghijklmnopqrstuvwxyz",
190
 
        {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
191
 
         0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
192
 
        }
193
 
      },
194
 
      { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
195
 
        {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
196
 
         0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
197
 
        }
198
 
      },
199
 
      { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
200
 
        {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
201
 
         0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
202
 
        }
203
 
      }
204
 
   };
205
 
   int i;
206
 
   hash_state md;
207
 
   unsigned char buf[16];
208
 
 
209
 
   for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
210
 
       md2_init(&md);
211
 
       md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
212
 
       md2_done(&md, buf);
213
 
       if (memcmp(buf, tests[i].md, 16) != 0) {
214
 
          return CRYPT_FAIL_TESTVECTOR;
215
 
       }
216
 
   }
217
 
   return CRYPT_OK;        
218
 
  #endif
219
 
}
220
 
 
221
 
#endif
222