OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [snmp/] [lib/] [v2_0/] [src/] [md5.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ./lib/current/src/md5.c
4
//
5
//
6
//==========================================================================
7
//####ECOSGPLCOPYRIGHTBEGIN####
8
// -------------------------------------------
9
// This file is part of eCos, the Embedded Configurable Operating System.
10
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11
//
12
// eCos is free software; you can redistribute it and/or modify it under
13
// the terms of the GNU General Public License as published by the Free
14
// Software Foundation; either version 2 or (at your option) any later version.
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
// for more details.
20
//
21
// You should have received a copy of the GNU General Public License along
22
// with eCos; if not, write to the Free Software Foundation, Inc.,
23
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24
//
25
// As a special exception, if other files instantiate templates or use macros
26
// or inline functions from this file, or you compile this file and link it
27
// with other works to produce a work based on this file, this file does not
28
// by itself cause the resulting work to be covered by the GNU General Public
29
// License. However the source code for this file must still be made available
30
// in accordance with section (3) of the GNU General Public License.
31
//
32
// This exception does not invalidate any other reasons why a work based on
33
// this file might be covered by the GNU General Public License.
34
//
35
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36
// at http://sources.redhat.com/ecos/ecos-license/
37
// -------------------------------------------
38
//####ECOSGPLCOPYRIGHTEND####
39
//####UCDSNMPCOPYRIGHTBEGIN####
40
//
41
// -------------------------------------------
42
//
43
// Portions of this software may have been derived from the UCD-SNMP
44
// project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
45
// California at Davis, which was originally based on the Carnegie Mellon
46
// University SNMP implementation.  Portions of this software are therefore
47
// covered by the appropriate copyright disclaimers included herein.
48
//
49
// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50
// -------------------------------------------
51
//
52
//####UCDSNMPCOPYRIGHTEND####
53
//==========================================================================
54
//#####DESCRIPTIONBEGIN####
55
//
56
// Author(s):    hmt
57
// Contributors: hmt
58
// Date:         2000-05-30
59
// Purpose:      Port of UCD-SNMP distribution to eCos.
60
// Description:  
61
//              
62
//
63
//####DESCRIPTIONEND####
64
//
65
//==========================================================================
66
/********************************************************************
67
       Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
 
69
                          Derivative Work -
70
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
 
72
                         All Rights Reserved
73
 
74
Permission to use, copy, modify and distribute this software and its
75
documentation for any purpose and without fee is hereby granted,
76
provided that the above copyright notice appears in all copies and
77
that both that copyright notice and this permission notice appear in
78
supporting documentation, and that the name of CMU and The Regents of
79
the University of California not be used in advertising or publicity
80
pertaining to distribution of the software without specific written
81
permission.
82
 
83
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85
WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
86
THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88
FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91
*********************************************************************/
92
/*
93
** **************************************************************************
94
** md5.c -- Implementation of MD5 Message Digest Algorithm                 **
95
** Updated: 2/16/90 by Ronald L. Rivest                                    **
96
** (C) 1990 RSA Data Security, Inc.                                        **
97
** **************************************************************************
98
*/
99
 
100
/*
101
** To use MD5:
102
**   -- Include md5.h in your program
103
**   -- Declare an MDstruct MD to hold the state of the digest computation.
104
**   -- Initialize MD using MDbegin(&MD)
105
**   -- For each full block (64 bytes) X you wish to process, call
106
**          MDupdate(&MD,X,512)
107
**      (512 is the number of bits in a full block.)
108
**   -- For the last block (less than 64 bytes) you wish to process,
109
**          MDupdate(&MD,X,n)
110
**      where n is the number of bits in the partial block. A partial
111
**      block terminates the computation, so every MD computation should
112
**      terminate by processing a partial block, even if it has n = 0.
113
**   -- The message digest is available in MD.buffer[0] ... MD.buffer[3].
114
**      (Least-significant byte of each word should be output first.)
115
**   -- You can print out the digest using MDprint(&MD)
116
*/
117
 
118
/* Implementation notes:
119
** This implementation assumes that ints are 32-bit quantities.
120
** If the machine stores the least-significant byte of an int in the
121
** least-addressed byte (eg., VAX and 8086), then LOWBYTEFIRST should be
122
** set to TRUE.  Otherwise (eg., SUNS), LOWBYTEFIRST should be set to
123
** FALSE.  Note that on machines with LOWBYTEFIRST FALSE the routine
124
** MDupdate modifies has a side-effect on its input array (the order of bytes
125
** in each word are reversed).  If this is undesired a call to MDreverse(X) can
126
** reverse the bytes of X back into order after each call to MDupdate.
127
*/
128
 
129
/* code uses WORDS_BIGENDIAN defined by configure now  -- WH 9/27/95 */
130
 
131
/* Compile-time includes
132
*/
133
 
134
#include <config.h>
135
 
136
#include <stdio.h>
137
#include <sys/types.h>
138
#if HAVE_STRING_H
139
#include <string.h>
140
#else
141
#include <strings.h>
142
#endif
143
#if HAVE_WINSOCK_H
144
#include <winsock.h>
145
#endif
146
 
147
#include "md5.h"
148
 
149
/* Compile-time declarations of MD5 ``magic constants''.
150
*/
151
#define I0  0x67452301       /* Initial values for MD buffer */
152
#define I1  0xefcdab89
153
#define I2  0x98badcfe
154
#define I3  0x10325476
155
#define fs1  7               /* round 1 shift amounts */
156
#define fs2 12   
157
#define fs3 17  
158
#define fs4 22  
159
#define gs1  5               /* round 2 shift amounts */
160
#define gs2  9   
161
#define gs3 14   
162
#define gs4 20  
163
#define hs1  4               /* round 3 shift amounts */
164
#define hs2 11 
165
#define hs3 16 
166
#define hs4 23
167
#define is1  6               /* round 4 shift amounts */
168
#define is2 10
169
#define is3 15
170
#define is4 21
171
 
172
 
173
/* Compile-time macro declarations for MD5.
174
** Note: The ``rot'' operator uses the variable ``tmp''.
175
** It assumes tmp is declared as unsigned int, so that the >>
176
** operator will shift in zeros rather than extending the sign bit.
177
*/
178
#define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
179
#define g(X,Y,Z)             ((X&Z) | (Y&(~Z)))
180
#define h(X,Y,Z)             (X^Y^Z)
181
#define i_(X,Y,Z)            (Y ^ ((X) | (~Z)))
182
#define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
183
#define ff(A,B,C,D,i,s,lp)   A = rot((A + f(B,C,D) + X[i] + lp),s) + B
184
#define gg(A,B,C,D,i,s,lp)   A = rot((A + g(B,C,D) + X[i] + lp),s) + B
185
#define hh(A,B,C,D,i,s,lp)   A = rot((A + h(B,C,D) + X[i] + lp),s) + B
186
#define ii(A,B,C,D,i,s,lp)   A = rot((A + i_(B,C,D) + X[i] + lp),s) + B
187
 
188
#ifdef STDC_HEADERS
189
#define Uns(num) num##U
190
#else
191
#define Uns(num) num
192
#endif /* STDC_HEADERS */
193
 
194
void MDreverse (unsigned int *);
195
static void MDblock (MDptr, unsigned int *);
196
 
197
#ifdef SNMP_TESTING_CODE
198
/* MDprint(MDp)
199
** Print message digest buffer MDp as 32 hexadecimal digits.
200
** Order is from low-order byte of buffer[0] to high-order byte of buffer[3].
201
** Each byte is printed with high-order hexadecimal digit first.
202
** This is a user-callable routine.
203
*/
204
void
205
MDprint(MDptr MDp)
206
{
207
    int i,j;
208
    for (i=0;i<4;i++)
209
        for (j=0;j<32;j=j+8)
210
            printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
211
    printf("\n");
212
    fflush(stdout);
213
}
214
#endif /* SNMP_TESTING_CODE */
215
 
216
/* MDbegin(MDp)
217
** Initialize message digest buffer MDp.
218
** This is a user-callable routine.
219
*/
220
void
221
MDbegin(MDptr MDp)
222
{
223
    int i;
224
    MDp->buffer[0] = I0;
225
    MDp->buffer[1] = I1;
226
    MDp->buffer[2] = I2;
227
    MDp->buffer[3] = I3;
228
    for (i=0;i<8;i++) MDp->count[i] = 0;
229
    MDp->done = 0;
230
}
231
 
232
/* MDreverse(X)
233
** Reverse the byte-ordering of every int in X.
234
** Assumes X is an array of 16 ints.
235
** The macro revx reverses the byte-ordering of the next word of X.
236
*/
237
#define revx { t = (*X << 16) | (*X >> 16); \
238
               *X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
239
 
240
void MDreverse(unsigned int *X)
241
{
242
    register unsigned int t;
243
    revx; revx; revx; revx; revx; revx; revx; revx;
244
    revx; revx; revx; revx; revx; revx; revx; revx;
245
}
246
 
247
/* MDblock(MDp,X)
248
** Update message digest buffer MDp->buffer using 16-word data block X.
249
** Assumes all 16 words of X are full of data.
250
** Does not update MDp->count.
251
** This routine is not user-callable.
252
*/
253
static void
254
MDblock(MDptr MDp,
255
        unsigned int *X)
256
{
257
    register unsigned int tmp, A, B, C, D;  /* hpux sysv sun */
258
#ifdef WORDS_BIGENDIAN
259
    MDreverse(X);
260
#endif
261
    A = MDp->buffer[0];
262
    B = MDp->buffer[1];
263
    C = MDp->buffer[2];
264
    D = MDp->buffer[3];
265
 
266
    /* Update the message digest buffer */
267
    ff(A , B , C , D ,  0 , fs1 , Uns(3614090360)); /* Round 1 */
268
    ff(D , A , B , C ,  1 , fs2 , Uns(3905402710));
269
    ff(C , D , A , B ,  2 , fs3 ,  Uns(606105819));
270
    ff(B , C , D , A ,  3 , fs4 , Uns(3250441966));
271
    ff(A , B , C , D ,  4 , fs1 , Uns(4118548399));
272
    ff(D , A , B , C ,  5 , fs2 , Uns(1200080426));
273
    ff(C , D , A , B ,  6 , fs3 , Uns(2821735955));
274
    ff(B , C , D , A ,  7 , fs4 , Uns(4249261313));
275
    ff(A , B , C , D ,  8 , fs1 , Uns(1770035416));
276
    ff(D , A , B , C ,  9 , fs2 , Uns(2336552879));
277
    ff(C , D , A , B , 10 , fs3 , Uns(4294925233));
278
    ff(B , C , D , A , 11 , fs4 , Uns(2304563134));
279
    ff(A , B , C , D , 12 , fs1 , Uns(1804603682));
280
    ff(D , A , B , C , 13 , fs2 , Uns(4254626195));
281
    ff(C , D , A , B , 14 , fs3 , Uns(2792965006));
282
    ff(B , C , D , A , 15 , fs4 , Uns(1236535329));
283
    gg(A , B , C , D ,  1 , gs1 , Uns(4129170786)); /* Round 2 */
284
    gg(D , A , B , C ,  6 , gs2 , Uns(3225465664));
285
    gg(C , D , A , B , 11 , gs3 ,  Uns(643717713));
286
    gg(B , C , D , A ,  0 , gs4 , Uns(3921069994));
287
    gg(A , B , C , D ,  5 , gs1 , Uns(3593408605));
288
    gg(D , A , B , C , 10 , gs2 ,   Uns(38016083));
289
    gg(C , D , A , B , 15 , gs3 , Uns(3634488961));
290
    gg(B , C , D , A ,  4 , gs4 , Uns(3889429448));
291
    gg(A , B , C , D ,  9 , gs1 ,  Uns(568446438));
292
    gg(D , A , B , C , 14 , gs2 , Uns(3275163606));
293
    gg(C , D , A , B ,  3 , gs3 , Uns(4107603335));
294
    gg(B , C , D , A ,  8 , gs4 , Uns(1163531501));
295
    gg(A , B , C , D , 13 , gs1 , Uns(2850285829));
296
    gg(D , A , B , C ,  2 , gs2 , Uns(4243563512));
297
    gg(C , D , A , B ,  7 , gs3 , Uns(1735328473));
298
    gg(B , C , D , A , 12 , gs4 , Uns(2368359562));
299
    hh(A , B , C , D ,  5 , hs1 , Uns(4294588738)); /* Round 3 */
300
    hh(D , A , B , C ,  8 , hs2 , Uns(2272392833));
301
    hh(C , D , A , B , 11 , hs3 , Uns(1839030562));
302
    hh(B , C , D , A , 14 , hs4 , Uns(4259657740));
303
    hh(A , B , C , D ,  1 , hs1 , Uns(2763975236));
304
    hh(D , A , B , C ,  4 , hs2 , Uns(1272893353));
305
    hh(C , D , A , B ,  7 , hs3 , Uns(4139469664));
306
    hh(B , C , D , A , 10 , hs4 , Uns(3200236656));
307
    hh(A , B , C , D , 13 , hs1 ,  Uns(681279174));
308
    hh(D , A , B , C ,  0 , hs2 , Uns(3936430074));
309
    hh(C , D , A , B ,  3 , hs3 , Uns(3572445317));
310
    hh(B , C , D , A ,  6 , hs4 ,   Uns(76029189));
311
    hh(A , B , C , D ,  9 , hs1 , Uns(3654602809));
312
    hh(D , A , B , C , 12 , hs2 , Uns(3873151461));
313
    hh(C , D , A , B , 15 , hs3 ,  Uns(530742520));
314
    hh(B , C , D , A ,  2 , hs4 , Uns(3299628645));
315
    ii(A , B , C , D ,  0 , is1 , Uns(4096336452)); /* Round 4 */
316
    ii(D , A , B , C ,  7 , is2 , Uns(1126891415));
317
    ii(C , D , A , B , 14 , is3 , Uns(2878612391));
318
    ii(B , C , D , A ,  5 , is4 , Uns(4237533241));
319
    ii(A , B , C , D , 12 , is1 , Uns(1700485571));
320
    ii(D , A , B , C ,  3 , is2 , Uns(2399980690));
321
    ii(C , D , A , B , 10 , is3 , Uns(4293915773));
322
    ii(B , C , D , A ,  1 , is4 , Uns(2240044497));
323
    ii(A , B , C , D ,  8 , is1 , Uns(1873313359));
324
    ii(D , A , B , C , 15 , is2 , Uns(4264355552));
325
    ii(C , D , A , B ,  6 , is3 , Uns(2734768916));
326
    ii(B , C , D , A , 13 , is4 , Uns(1309151649));
327
    ii(A , B , C , D ,  4 , is1 , Uns(4149444226));
328
    ii(D , A , B , C , 11 , is2 , Uns(3174756917));
329
    ii(C , D , A , B ,  2 , is3 ,  Uns(718787259));
330
    ii(B , C , D , A ,  9 , is4 , Uns(3951481745));
331
 
332
    MDp->buffer[0] += A;
333
    MDp->buffer[1] += B;
334
    MDp->buffer[2] += C;
335
    MDp->buffer[3] += D;
336
#ifdef WORDS_BIGENDIAN
337
    MDreverse(X);
338
#endif
339
}
340
 
341
/* MDupdate(MDp,X,count)
342
** Input: MDp -- an MDptr
343
**        X -- a pointer to an array of unsigned characters.
344
**        count -- the number of bits of X to use.
345
**                 (if not a multiple of 8, uses high bits of last byte.)
346
** Update MDp using the number of bits of X given by count.
347
** This is the basic input routine for an MD5 user.
348
** The routine completes the MD computation when count < 512, so
349
** every MD computation should end with one call to MDupdate with a
350
** count less than 512.  A call with count 0 will be ignored if the
351
** MD has already been terminated (done != 0), so an extra call with count
352
** 0 can be given as a ``courtesy close'' to force termination if desired.
353
** Returns : 0 if processing succeeds or was already done;
354
**          -1 if processing was already done
355
**          -2 if count was too large
356
*/
357
int
358
MDupdate(MDptr MDp,
359
         unsigned char *X,
360
         unsigned int count)
361
{
362
    unsigned int i, tmp, bit, byte, mask;
363
    unsigned char XX[64];
364
    unsigned char *p;
365
    /* return with no error if this is a courtesy close with count
366
  ** zero and MDp->done is true.
367
  */
368
    if (count == 0 && MDp->done) return 0;
369
    /* check to see if MD is already done and report error */
370
    if (MDp->done) { return -1; }
371
/*
372
    if (MDp->done) { fprintf(stderr,"\nError: MDupdate MD already done."); return; }
373
*/
374
    /* Add count to MDp->count */
375
    tmp = count;
376
    p = MDp->count;
377
    while (tmp)
378
    { tmp += *p;
379
    *p++ = tmp;
380
    tmp = tmp >> 8;
381
    }
382
    /* Process data */
383
    if (count == 512)
384
    { /* Full block of data to handle */
385
        MDblock(MDp,(unsigned int *)X);
386
    }
387
    else if (count > 512) /* Check for count too large */
388
    return -2;
389
/*
390
    { fprintf(stderr,"\nError: MDupdate called with illegal count value %d.",count);
391
    return;
392
    }
393
*/
394
    else /* partial block -- must be last block so finish up */
395
    { /* Find out how many bytes and residual bits there are */
396
        int copycount;
397
        byte = count >> 3;
398
        bit =  count & 7;
399
        copycount = byte; if (bit) copycount++;
400
        /* Copy X into XX since we need to modify it */
401
        memset(XX,0,sizeof(XX));
402
        memcpy(XX,X,copycount);
403
 
404
        /* Add padding '1' bit and low-order zeros in last byte */
405
        mask = ((unsigned long)1) << (7 - bit);
406
        XX[byte] = (XX[byte] | mask) & ~( mask - 1);
407
        /* If room for bit count, finish up with this block */
408
        if (byte <= 55)
409
        { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
410
        MDblock(MDp,(unsigned int *)XX);
411
        }
412
        else /* need to do two blocks to finish up */
413
        { MDblock(MDp,(unsigned int *)XX);
414
        for (i=0;i<56;i++) XX[i] = 0;
415
        for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
416
        MDblock(MDp,(unsigned int *)XX);
417
        }
418
        /* Set flag saying we're done with MD computation */
419
        MDp->done = 1;
420
    }
421
    return 0;
422
}
423
 
424
/* MDchecksum(data, len, MD5): do a checksum on an arbirtrary amount of data */
425
int
426
MDchecksum(u_char *data, size_t len, u_char *mac, size_t maclen)
427
{
428
  MDstruct md;
429
  MDstruct *MD = &md;
430
  int rc = 0;
431
 
432
  MDbegin(MD);
433
  while (len >= 64) {
434
    rc = MDupdate(MD, data, 64*8);
435
    if (rc) goto check_end;
436
    data += 64;
437
    len -= 64;
438
  }
439
  rc = MDupdate(MD, data, len*8);
440
  if (rc) goto check_end;
441
 
442
  /* copy the checksum to the outgoing data (all of it that is requested). */
443
  MDget(MD, mac, maclen);
444
 
445
check_end:
446
  memset(&md,0,sizeof(md));
447
  return rc;
448
}
449
 
450
 
451
/* MDsign(data, len, MD5): do a checksum on an arbirtrary amount
452
   of data, and prepended with a secret in the standard fashion */
453
int
454
MDsign(u_char *data, size_t len, u_char *mac, size_t maclen,
455
       u_char *secret, size_t secretlen)
456
{
457
#define HASHKEYLEN 64
458
 
459
  MDstruct MD;
460
  u_char   K1[HASHKEYLEN];
461
  u_char   K2[HASHKEYLEN];
462
  u_char   extendedAuthKey[HASHKEYLEN];
463
  u_char   buf[HASHKEYLEN];
464
  size_t   i;
465
  u_char  *cp;
466
  int      rc = 0;
467
 
468
/*
469
  memset(K1,0,HASHKEYLEN);
470
  memset(K2,0,HASHKEYLEN);
471
  memset(buf,0,HASHKEYLEN);
472
  memset(extendedAuthKey,0,HASHKEYLEN);
473
*/
474
 
475
  if (secretlen != 16 || secret == NULL || mac == NULL || data == NULL ||
476
    len <= 0 || maclen <= 0) {
477
/*    DEBUGMSGTL(("md5","MD5 signing not properly initialized")); */
478
    return -1;
479
  }
480
 
481
  memset(extendedAuthKey, 0, HASHKEYLEN);
482
  memcpy(extendedAuthKey, secret, secretlen);
483
  for(i = 0; i < HASHKEYLEN; i++) {
484
    K1[i] = extendedAuthKey[i] ^ 0x36;
485
    K2[i] = extendedAuthKey[i] ^ 0x5c;
486
  }
487
 
488
  MDbegin(&MD);
489
  rc = MDupdate(&MD, K1, HASHKEYLEN*8);
490
  if (rc) goto update_end;
491
 
492
  i = len;
493
  cp = data;
494
  while (i >= 64) {
495
    rc = MDupdate(&MD, cp, 64*8);
496
        if (rc) goto update_end;
497
    cp += 64;
498
    i -= 64;
499
  }
500
 
501
  rc = MDupdate(&MD, cp, i*8);
502
  if (rc) goto update_end;
503
 
504
  memset(buf,0,HASHKEYLEN);
505
  MDget(&MD, buf, HASHKEYLEN);
506
 
507
  MDbegin(&MD);
508
  rc = MDupdate(&MD, K2, HASHKEYLEN*8);
509
  if (rc) goto update_end;
510
  rc = MDupdate(&MD, buf, 16*8);
511
  if (rc) goto update_end;
512
 
513
  /* copy the sign checksum to the outgoing pointer */
514
  MDget(&MD, mac, maclen);
515
 
516
update_end:
517
  memset(buf, 0, HASHKEYLEN);
518
  memset(K1, 0, HASHKEYLEN);
519
  memset(K2, 0, HASHKEYLEN);
520
  memset(extendedAuthKey, 0, HASHKEYLEN);
521
  memset(&MD, 0, sizeof(MD));
522
 
523
  return rc;
524
}
525
 
526
void
527
MDget(MDstruct *MD, u_char *buf, size_t buflen)
528
{
529
  int i, j;
530
 
531
  /* copy the checksum to the outgoing data (all of it that is requested). */
532
  for(i=0; i < 4 && i*4 < (int)buflen; i++)
533
    for(j=0; j < 4 && i*4+j < (int)buflen; j++)
534
      buf[i*4+j] = (MD->buffer[i] >> j*8) & 0xff;
535
}
536
 
537
/*
538
** End of md5.c
539
****************************(cut)*****************************************/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.