Browse Source
Change 3D cache manager to use boost SHA-1 digest rather than in-tree MD5
pull/12/head
Change 3D cache manager to use boost SHA-1 digest rather than in-tree MD5
pull/12/head
6 changed files with 71 additions and 903 deletions
-
1113d-viewer/3d_cache/3d_cache.cpp
-
103d-viewer/3d_cache/3d_cache.h
-
2973d-viewer/3d_cache/ansidecl.h
-
4093d-viewer/3d_cache/md5.cpp
-
1463d-viewer/3d_cache/md5.h
-
13d-viewer/CMakeLists.txt
@ -1,297 +0,0 @@ |
|||
/* ANSI and traditional C compatability macros |
|||
Copyright 1991, 1992, 1*993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 |
|||
Free Software Foundation, Inc. |
|||
This file is part of the GNU C Library. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 2 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software |
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
|
|||
/* ANSI and traditional C compatibility macros |
|||
|
|||
ANSI C is assumed if __STDC__ is #defined. |
|||
|
|||
Macro ANSI C definition Traditional C definition |
|||
----- ---- - ---------- ----------- - ---------- |
|||
ANSI_PROTOTYPES 1 not defined |
|||
PTR `void *' `char *' |
|||
PTRCONST `void *const' `char *' |
|||
LONG_DOUBLE `long double' `double' |
|||
const not defined `' |
|||
volatile not defined `' |
|||
signed not defined `' |
|||
VA_START(ap, var) va_start(ap, var) va_start(ap) |
|||
|
|||
Note that it is safe to write "void foo();" indicating a function |
|||
with no return value, in all K+R compilers we have been able to test. |
|||
|
|||
For declaring functions with prototypes, we also provide these: |
|||
|
|||
PARAMS ((prototype)) |
|||
-- for functions which take a fixed number of arguments. Use this |
|||
when declaring the function. When defining the function, write a |
|||
K+R style argument list. For example: |
|||
|
|||
char *strcpy PARAMS ((char *dest, char *source)); |
|||
... |
|||
char * |
|||
strcpy (dest, source) |
|||
char *dest; |
|||
char *source; |
|||
{ ... } |
|||
|
|||
VPARAMS ((prototype, ...)) |
|||
-- for functions which take a variable number of arguments. Use |
|||
PARAMS to declare the function, VPARAMS to define it. For example: |
|||
|
|||
int printf PARAMS ((const char *format, ...)); |
|||
... |
|||
int |
|||
printf VPARAMS ((const char *format, ...)) |
|||
{ |
|||
... |
|||
} |
|||
|
|||
For writing functions which take variable numbers of arguments, we |
|||
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These |
|||
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more |
|||
thoroughly than the simple VA_START() macro mentioned above. |
|||
|
|||
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. |
|||
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls |
|||
corresponding to the list of fixed arguments. Then use va_arg |
|||
normally to get the variable arguments, or pass your va_list object |
|||
around. You do not declare the va_list yourself; VA_OPEN does it |
|||
for you. |
|||
|
|||
Here is a complete example: |
|||
|
|||
int |
|||
printf VPARAMS ((const char *format, ...)) |
|||
{ |
|||
int result; |
|||
|
|||
VA_OPEN (ap, format); |
|||
VA_FIXEDARG (ap, const char *, format); |
|||
|
|||
result = vfprintf (stdout, format, ap); |
|||
VA_CLOSE (ap); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
|
|||
You can declare variables either before or after the VA_OPEN, |
|||
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning |
|||
and end of a block. They must appear at the same nesting level, |
|||
and any variables declared after VA_OPEN go out of scope at |
|||
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the |
|||
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE |
|||
pairs in a single function in case you need to traverse the |
|||
argument list more than once. |
|||
|
|||
For ease of writing code which uses GCC extensions but needs to be |
|||
portable to other compilers, we provide the GCC_VERSION macro that |
|||
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various |
|||
wrappers around __attribute__. Also, __extension__ will be #defined |
|||
to nothing if it doesn't work. See below. |
|||
|
|||
This header also defines a lot of obsolete macros: |
|||
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, |
|||
AND, DOTS, NOARGS. Don't use them. */ |
|||
|
|||
#ifndef _ANSIDECL_H |
|||
#define _ANSIDECL_H 1 |
|||
|
|||
/* Every source file includes this file, |
|||
so they will all get the switch for lint. */ |
|||
/* LINTLIBRARY */ |
|||
|
|||
/* Using MACRO(x,y) in cpp #if conditionals does not work with some |
|||
older preprocessors. Thus we can't define something like this: |
|||
|
|||
#define HAVE_GCC_VERSION(MAJOR, MINOR) \ |
|||
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) |
|||
|
|||
and then test "#if HAVE_GCC_VERSION(2,7)". |
|||
|
|||
So instead we use the macro below and test it against specific values. */ |
|||
|
|||
/* This macro simplifies testing whether we are using gcc, and if it |
|||
is of a particular mini*mum version. (Both major & minor numbers are |
|||
significant.) This macro will evaluate to 0 if we are not using |
|||
gcc at all. */ |
|||
#ifndef GCC_VERSION |
|||
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) |
|||
#endif /* GCC_VERSION */ |
|||
|
|||
#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus)) |
|||
/* All known AIX compilers implement these things (but don't always |
|||
define __STDC__). The RISC/OS MIPS compiler defines these things |
|||
in SVR4 mode, but does not define __STDC__. */ |
|||
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other |
|||
C ++ compilers, does not define __STDC__, though it acts as if this |
|||
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ |
|||
|
|||
#define ANSI_PROTOTYPES 1 |
|||
#define PTR void * |
|||
#define PTRCONST void *const |
|||
#define LONG_DOUBLE long double |
|||
|
|||
#define PARAMS(ARGS) ARGS |
|||
#define VPARAMS(ARGS) ARGS |
|||
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) |
|||
|
|||
/* variadic function helper macros */ |
|||
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's |
|||
use without inhibiting further decls and without declaring an |
|||
actual variable. */ |
|||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy |
|||
#define VA_CLOSE(AP) } va_end(AP); } |
|||
#define VA_FIXEDARG(AP, T, N) struct Qdmy |
|||
|
|||
#undef const |
|||
#undef volatile |
|||
#undef signed |
|||
|
|||
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports |
|||
it too, but it's not in C89. */ |
|||
#undef inline |
|||
#if __STDC_VERSION__ > 199901L |
|||
/* it's a keyword */ |
|||
#else |
|||
# if GCC_VERSION >= 2007 |
|||
# define inline __inline__ /* __inline__ prevents -pedantic warnings */ |
|||
# else |
|||
# define inline /* nothing */ |
|||
# endif |
|||
#endif |
|||
|
|||
/* These are obsolete. Do not use. */ |
|||
#ifndef IN_GCC |
|||
#define CONST const |
|||
#define VOLATILE volatile |
|||
#define SIGNED signed |
|||
|
|||
#define PROTO(type, name, arglist) type name arglist |
|||
#define EXFUN(name, proto) name proto |
|||
#define DEFUN(name, arglist, args) name(args) |
|||
#define DEFUN_VOID(name) name(void) |
|||
#define AND , |
|||
#define DOTS , ... |
|||
#define NOARGS void |
|||
#endif /* ! IN_GCC */ |
|||
|
|||
#else /* Not ANSI C. */ |
|||
|
|||
#undef ANSI_PROTOTYPES |
|||
#define PTR char * |
|||
#define PTRCONST PTR |
|||
#define LONG_DOUBLE double |
|||
|
|||
#define PARAMS(args) () |
|||
#define VPARAMS(args) (va_alist) va_dcl |
|||
#define VA_START(va_list, var) va_start(va_list) |
|||
|
|||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy |
|||
#define VA_CLOSE(AP) } va_end(AP); } |
|||
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) |
|||
|
|||
/* some systems define these in header files for non-ansi mode */ |
|||
#undef const |
|||
#undef volatile |
|||
#undef signed |
|||
#undef inline |
|||
#define const |
|||
#define volatile |
|||
#define signed |
|||
#define inline |
|||
|
|||
#ifndef IN_GCC |
|||
#define CONST |
|||
#define VOLATILE |
|||
#define SIGNED |
|||
|
|||
#define PROTO(type, name, arglist) type name () |
|||
#define EXFUN(name, proto) name() |
|||
#define DEFUN(name, arglist, args) name arglist args; |
|||
#define DEFUN_VOID(name) name() |
|||
#define AND ; |
|||
#define DOTS |
|||
#define NOARGS |
|||
#endif /* ! IN_GCC */ |
|||
|
|||
#endif /* ANSI C. */ |
|||
|
|||
/* Define macros for some gcc attributes. This permits us to use the |
|||
macros freely, and know that they will come into play for the |
|||
version of gcc in which they are supported. */ |
|||
|
|||
#if (GCC_VERSION < 2007) |
|||
# define __attribute__(x) |
|||
#endif |
|||
|
|||
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */ |
|||
#ifndef ATTRIBUTE_MALLOC |
|||
# if (GCC_VERSION >= 2096) |
|||
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) |
|||
# else |
|||
# define ATTRIBUTE_MALLOC |
|||
# endif /* GNUC >= 2.96 */ |
|||
#endif /* ATTRIBUTE_MALLOC */ |
|||
|
|||
/* Attributes on labels were valid as of gcc 2.93. */ |
|||
#ifndef ATTRIBUTE_UNUSED_LABEL |
|||
# if (GCC_VERSION >= 2093) |
|||
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED |
|||
# else |
|||
# define ATTRIBUTE_UNUSED_LABEL |
|||
# endif /* GNUC >= 2.93 */ |
|||
#endif /* ATTRIBUTE_UNUSED_LABEL */ |
|||
|
|||
#ifndef ATTRIBUTE_UNUSED |
|||
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) |
|||
#endif /* ATTRIBUTE_UNUSED */ |
|||
|
|||
#ifndef ATTRIBUTE_NORETURN |
|||
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) |
|||
#endif /* ATTRIBUTE_NORETURN */ |
|||
|
|||
#ifndef ATTRIBUTE_PRINTF |
|||
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) |
|||
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) |
|||
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) |
|||
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) |
|||
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) |
|||
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) |
|||
#endif /* ATTRIBUTE_PRINTF */ |
|||
|
|||
/* We use __extension__ in some places to suppress -pedantic warnings |
|||
about GCC extensions. This feature didn't work properly before |
|||
gcc 2.8. */ |
|||
#if GCC_VERSION < 2008 |
|||
#define __extension__ |
|||
#endif |
|||
|
|||
/* Bootstrap support: Adjust certain macros defined by Autoconf, |
|||
which are only valid for the stage1 compiler. If we detect |
|||
a modern version of GCC, we are probably in stage2 or beyond, |
|||
so unconditionally reset the values. Note that const, inline, |
|||
etc. have been dealt with above. */ |
|||
#if (GCC_VERSION >= 2007) |
|||
# ifndef HAVE_LONG_DOUBLE |
|||
# define HAVE_LONG_DOUBLE 1 |
|||
# endif |
|||
#endif /* GCC >= 2.7 */ |
|||
|
|||
#endif /* ansidecl.h */ |
@ -1,409 +0,0 @@ |
|||
/* md5.c - Functions to compute MD5 message digest of files or memory blocks
|
|||
* according to the definition of MD5 in RFC 1321 from April 1992. |
|||
* Copyright (C) 1995, 1996 Free Software Foundation, Inc. |
|||
* |
|||
* NOTE: This source is derived from an old version taken from the GNU C |
|||
* Library (glibc). |
|||
* |
|||
* This program is free software; you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation; either version 2, or (at your option) any |
|||
* later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, write to the Free Software Foundation, |
|||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
|
|||
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ |
|||
|
|||
#ifdef HAVE_CONFIG_H
|
|||
# include <config.h>
|
|||
#endif
|
|||
|
|||
#include <sys/types.h>
|
|||
|
|||
# include <stdlib.h>
|
|||
# include <string.h>
|
|||
|
|||
#include "ansidecl.h"
|
|||
#include "md5.h"
|
|||
|
|||
#ifdef __APPLE__
|
|||
# include <machine/endian.h>
|
|||
#elif !defined( _WIN32 )
|
|||
# include <endian.h>
|
|||
#endif
|
|||
# if __BYTE_ORDER == __BIG_ENDIAN
|
|||
# define WORDS_BIGENDIAN 1
|
|||
# endif
|
|||
|
|||
#ifdef WORDS_BIGENDIAN
|
|||
# define SWAP(n) \
|
|||
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) |
|||
#else
|
|||
# define SWAP(n) (n)
|
|||
#endif
|
|||
|
|||
|
|||
/* This array contains the bytes used to pad the buffer to the next
|
|||
* 64-byte boundary. (RFC 1321, 3.1: Step 1) */ |
|||
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; |
|||
|
|||
|
|||
/* Initialize structure containing state of computation.
|
|||
* (RFC 1321, 3.3: Step 3) */ |
|||
void |
|||
md5_init_ctx ( struct md5_ctx *ctx ) |
|||
{ |
|||
ctx->A = (md5_uint32) 0x67452301; |
|||
ctx->B = (md5_uint32) 0xefcdab89; |
|||
ctx->C = (md5_uint32) 0x98badcfe; |
|||
ctx->D = (md5_uint32) 0x10325476; |
|||
|
|||
ctx->total[0] = ctx->total[1] = 0; |
|||
ctx->buflen = 0; |
|||
} |
|||
|
|||
/* Put result from CTX in first 16 bytes following RESBUF. The result
|
|||
* must be in little endian byte order. |
|||
* |
|||
* IMPORTANT: On some systems it is required that RESBUF is correctly |
|||
* aligned for a 32 bits value. */ |
|||
void * |
|||
md5_read_ctx ( const struct md5_ctx *ctx, void *resbuf ) |
|||
{ |
|||
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); |
|||
((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); |
|||
((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); |
|||
((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); |
|||
|
|||
return resbuf; |
|||
} |
|||
|
|||
/* Process the remaining bytes in the internal buffer and the usual
|
|||
* prolog according to the standard and write the result to RESBUF. |
|||
* |
|||
* IMPORTANT: On some systems it is required that RESBUF is correctly |
|||
* aligned for a 32 bits value. */ |
|||
void * |
|||
md5_finish_ctx ( struct md5_ctx *ctx, void *resbuf ) |
|||
{ |
|||
/* Take yet unprocessed bytes into account. */ |
|||
md5_uint32 bytes = ctx->buflen; |
|||
size_t pad; |
|||
|
|||
/* Now count remaining bytes. */ |
|||
ctx->total[0] += bytes; |
|||
if (ctx->total[0] < bytes) |
|||
++ctx->total[1]; |
|||
|
|||
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; |
|||
memcpy (&ctx->buffer[bytes], fillbuf, pad); |
|||
|
|||
/* Put the 64-bit file length in *bits* at the end of the buffer. */ |
|||
*(md5_uint32 *) (&ctx->buffer[bytes + pad]) = SWAP (ctx->total[0] << 3); |
|||
*(md5_uint32 *) (&ctx->buffer[bytes + pad + 4]) = SWAP ((ctx->total[1] << 3) | |
|||
(ctx->total[0] >> 29)); |
|||
|
|||
/* Process last bytes. */ |
|||
md5_process_block (ctx->buffer, bytes + pad + 8, ctx); |
|||
|
|||
return md5_read_ctx (ctx, resbuf); |
|||
} |
|||
|
|||
/* Compute MD5 message digest for bytes read from STREAM. The
|
|||
* resulting message digest number will be written into the 16 bytes |
|||
* beginning at RESBLOCK. */ |
|||
int |
|||
md5_stream ( FILE *stream, void *resblock ) |
|||
{ |
|||
/* Important: BLOCKSIZE must be a multiple of 64. */ |
|||
#define BLOCKSIZE 4096
|
|||
struct md5_ctx ctx; |
|||
char buffer[BLOCKSIZE + 72]; |
|||
size_t sum; |
|||
|
|||
/* Initialize the computation context. */ |
|||
md5_init_ctx (&ctx); |
|||
|
|||
/* Iterate over full file contents. */ |
|||
while (1) |
|||
{ |
|||
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
|||
* computation function processes the whole buffer so that with the |
|||
* next round of the loop another block can be read. */ |
|||
size_t n; |
|||
sum = 0; |
|||
|
|||
/* Read block. Take care for partial reads. */ |
|||
do |
|||
{ |
|||
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); |
|||
|
|||
sum += n; |
|||
} |
|||
while (sum < BLOCKSIZE && n != 0); |
|||
if (n == 0 && ferror (stream)) |
|||
return 1; |
|||
|
|||
/* If end of file is reached, end the loop. */ |
|||
if (n == 0) |
|||
break; |
|||
|
|||
/* Process buffer with BLOCKSIZE bytes. Note that
|
|||
* BLOCKSIZE % 64 == 0 |
|||
*/ |
|||
md5_process_block (buffer, BLOCKSIZE, &ctx); |
|||
} |
|||
|
|||
/* Add the last bytes if necessary. */ |
|||
if (sum > 0) |
|||
md5_process_bytes (buffer, sum, &ctx); |
|||
|
|||
/* Construct result in desired memory. */ |
|||
md5_finish_ctx (&ctx, resblock); |
|||
return 0; |
|||
} |
|||
|
|||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
|||
* result is always in little endian byte order, so that a byte-wise |
|||
* output yields to the wanted ASCII representation of the message |
|||
* digest. */ |
|||
void * |
|||
md5_buffer ( const char *buffer, size_t len, void *resblock ) |
|||
{ |
|||
struct md5_ctx ctx; |
|||
|
|||
/* Initialize the computation context. */ |
|||
md5_init_ctx (&ctx); |
|||
|
|||
/* Process whole buffer but last len % 64 bytes. */ |
|||
md5_process_bytes (buffer, len, &ctx); |
|||
|
|||
/* Put result in desired memory area. */ |
|||
return md5_finish_ctx (&ctx, resblock); |
|||
} |
|||
|
|||
|
|||
void |
|||
md5_process_bytes ( const void *buffer, size_t len, struct md5_ctx *ctx ) |
|||
{ |
|||
/* When we already have some bits in our internal buffer concatenate
|
|||
* both inputs first. */ |
|||
if (ctx->buflen != 0) |
|||
{ |
|||
size_t left_over = ctx->buflen; |
|||
size_t add = 128 - left_over > len ? len : 128 - left_over; |
|||
|
|||
memcpy (&ctx->buffer[left_over], buffer, add); |
|||
ctx->buflen += add; |
|||
|
|||
if (left_over + add > 64) |
|||
{ |
|||
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); |
|||
/* The regions in the following copy operation cannot overlap. */ |
|||
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], |
|||
(left_over + add) & 63); |
|||
ctx->buflen = (left_over + add) & 63; |
|||
} |
|||
|
|||
buffer = (const void *) ((const char *) buffer + add); |
|||
len -= add; |
|||
} |
|||
|
|||
/* Process available complete blocks. */ |
|||
if (len > 64) |
|||
{ |
|||
md5_process_block (buffer, len & ~63, ctx); |
|||
buffer = (const void *) ((const char *) buffer + (len & ~63)); |
|||
len &= 63; |
|||
} |
|||
|
|||
/* Move remaining bytes in internal buffer. */ |
|||
if (len > 0) |
|||
{ |
|||
memcpy (ctx->buffer, buffer, len); |
|||
ctx->buflen = len; |
|||
} |
|||
} |
|||
|
|||
|
|||
/* These are the four functions used in the four steps of the MD5 algorithm
|
|||
* and defined in the RFC 1321. The first function is a little bit optimized |
|||
* (as found in Colin Plumbs public domain implementation). */ |
|||
/* #define FF(b, c, d) ((b & c) | (~b & d)) */ |
|||
#define FF(b, c, d) (d ^ (b & (c ^ d)))
|
|||
#define FG(b, c, d) FF (d, b, c)
|
|||
#define FH(b, c, d) (b ^ c ^ d)
|
|||
#define FI(b, c, d) (c ^ (b | ~d))
|
|||
|
|||
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
|||
* It is assumed that LEN % 64 == 0. */ |
|||
|
|||
void |
|||
md5_process_block ( const void *buffer, size_t len, struct md5_ctx *ctx ) |
|||
{ |
|||
md5_uint32 correct_words[16]; |
|||
const md5_uint32 *words = (const md5_uint32 *) buffer; |
|||
size_t nwords = len / sizeof (md5_uint32); |
|||
const md5_uint32 *endp = words + nwords; |
|||
md5_uint32 A = ctx->A; |
|||
md5_uint32 B = ctx->B; |
|||
md5_uint32 C = ctx->C; |
|||
md5_uint32 D = ctx->D; |
|||
|
|||
/* First increment the byte count. RFC 1321 specifies the possible
|
|||
* length of the file up to 2^64 bits. Here we only compute the |
|||
* number of bytes. Do a double word increment. */ |
|||
ctx->total[0] += len; |
|||
if (ctx->total[0] < len) |
|||
++ctx->total[1]; |
|||
|
|||
/* Process all bytes in the buffer with 64 bytes in each round of
|
|||
* the loop. */ |
|||
while (words < endp) |
|||
{ |
|||
md5_uint32 *cwp = correct_words; |
|||
md5_uint32 A_save = A; |
|||
md5_uint32 B_save = B; |
|||
md5_uint32 C_save = C; |
|||
md5_uint32 D_save = D; |
|||
|
|||
/* First round: using the given function, the context and a constant
|
|||
* the next context is computed. Because the algorithms processing |
|||
* unit is a 32-bit word and it is determined to work on words in |
|||
* little endian byte order we perhaps have to change the byte order |
|||
* before the computation. To reduce the work for the next steps |
|||
* we store the swapped words in the array CORRECT_WORDS. */ |
|||
|
|||
#define OP(a, b, c, d, s, T) \
|
|||
do \ |
|||
{ \ |
|||
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ |
|||
++words; \ |
|||
CYCLIC (a, s); \ |
|||
a += b; \ |
|||
} \ |
|||
while (0) |
|||
|
|||
/* It is unfortunate that C does not provide an operator for
|
|||
* cyclic rotation. Hope the C compiler is smart enough. */ |
|||
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
|
|||
|
|||
/* Before we start, one word to the strange constants.
|
|||
* They are defined in RFC 1321 as |
|||
* |
|||
* T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 |
|||
*/ |
|||
|
|||
/* Round 1. */ |
|||
OP (A, B, C, D, 7, (md5_uint32) 0xd76aa478); |
|||
OP (D, A, B, C, 12, (md5_uint32) 0xe8c7b756); |
|||
OP (C, D, A, B, 17, (md5_uint32) 0x242070db); |
|||
OP (B, C, D, A, 22, (md5_uint32) 0xc1bdceee); |
|||
OP (A, B, C, D, 7, (md5_uint32) 0xf57c0faf); |
|||
OP (D, A, B, C, 12, (md5_uint32) 0x4787c62a); |
|||
OP (C, D, A, B, 17, (md5_uint32) 0xa8304613); |
|||
OP (B, C, D, A, 22, (md5_uint32) 0xfd469501); |
|||
OP (A, B, C, D, 7, (md5_uint32) 0x698098d8); |
|||
OP (D, A, B, C, 12, (md5_uint32) 0x8b44f7af); |
|||
OP (C, D, A, B, 17, (md5_uint32) 0xffff5bb1); |
|||
OP (B, C, D, A, 22, (md5_uint32) 0x895cd7be); |
|||
OP (A, B, C, D, 7, (md5_uint32) 0x6b901122); |
|||
OP (D, A, B, C, 12, (md5_uint32) 0xfd987193); |
|||
OP (C, D, A, B, 17, (md5_uint32) 0xa679438e); |
|||
OP (B, C, D, A, 22, (md5_uint32) 0x49b40821); |
|||
|
|||
/* For the second to fourth round we have the possibly swapped words
|
|||
* in CORRECT_WORDS. Redefine the macro to take an additional first |
|||
* argument specifying the function to use. */ |
|||
#undef OP
|
|||
#define OP(a, b, c, d, k, s, T) \
|
|||
do \ |
|||
{ \ |
|||
a += FX (b, c, d) + correct_words[k] + T; \ |
|||
CYCLIC (a, s); \ |
|||
a += b; \ |
|||
} \ |
|||
while (0) |
|||
|
|||
#define FX(b, c, d) FG (b, c, d)
|
|||
|
|||
/* Round 2. */ |
|||
OP (A, B, C, D, 1, 5, (md5_uint32) 0xf61e2562); |
|||
OP (D, A, B, C, 6, 9, (md5_uint32) 0xc040b340); |
|||
OP (C, D, A, B, 11, 14, (md5_uint32) 0x265e5a51); |
|||
OP (B, C, D, A, 0, 20, (md5_uint32) 0xe9b6c7aa); |
|||
OP (A, B, C, D, 5, 5, (md5_uint32) 0xd62f105d); |
|||
OP (D, A, B, C, 10, 9, (md5_uint32) 0x02441453); |
|||
OP (C, D, A, B, 15, 14, (md5_uint32) 0xd8a1e681); |
|||
OP (B, C, D, A, 4, 20, (md5_uint32) 0xe7d3fbc8); |
|||
OP (A, B, C, D, 9, 5, (md5_uint32) 0x21e1cde6); |
|||
OP (D, A, B, C, 14, 9, (md5_uint32) 0xc33707d6); |
|||
OP (C, D, A, B, 3, 14, (md5_uint32) 0xf4d50d87); |
|||
OP (B, C, D, A, 8, 20, (md5_uint32) 0x455a14ed); |
|||
OP (A, B, C, D, 13, 5, (md5_uint32) 0xa9e3e905); |
|||
OP (D, A, B, C, 2, 9, (md5_uint32) 0xfcefa3f8); |
|||
OP (C, D, A, B, 7, 14, (md5_uint32) 0x676f02d9); |
|||
OP (B, C, D, A, 12, 20, (md5_uint32) 0x8d2a4c8a); |
|||
|
|||
#undef FX
|
|||
#define FX(b, c, d) FH (b, c, d)
|
|||
|
|||
/* Round 3. */ |
|||
OP (A, B, C, D, 5, 4, (md5_uint32) 0xfffa3942); |
|||
OP (D, A, B, C, 8, 11, (md5_uint32) 0x8771f681); |
|||
OP (C, D, A, B, 11, 16, (md5_uint32) 0x6d9d6122); |
|||
OP (B, C, D, A, 14, 23, (md5_uint32) 0xfde5380c); |
|||
OP (A, B, C, D, 1, 4, (md5_uint32) 0xa4beea44); |
|||
OP (D, A, B, C, 4, 11, (md5_uint32) 0x4bdecfa9); |
|||
OP (C, D, A, B, 7, 16, (md5_uint32) 0xf6bb4b60); |
|||
OP (B, C, D, A, 10, 23, (md5_uint32) 0xbebfbc70); |
|||
OP (A, B, C, D, 13, 4, (md5_uint32) 0x289b7ec6); |
|||
OP (D, A, B, C, 0, 11, (md5_uint32) 0xeaa127fa); |
|||
OP (C, D, A, B, 3, 16, (md5_uint32) 0xd4ef3085); |
|||
OP (B, C, D, A, 6, 23, (md5_uint32) 0x04881d05); |
|||
OP (A, B, C, D, 9, 4, (md5_uint32) 0xd9d4d039); |
|||
OP (D, A, B, C, 12, 11, (md5_uint32) 0xe6db99e5); |
|||
OP (C, D, A, B, 15, 16, (md5_uint32) 0x1fa27cf8); |
|||
OP (B, C, D, A, 2, 23, (md5_uint32) 0xc4ac5665); |
|||
|
|||
#undef FX
|
|||
#define FX(b, c, d) FI (b, c, d)
|
|||
|
|||
/* Round 4. */ |
|||
OP (A, B, C, D, 0, 6, (md5_uint32) 0xf4292244); |
|||
OP (D, A, B, C, 7, 10, (md5_uint32) 0x432aff97); |
|||
OP (C, D, A, B, 14, 15, (md5_uint32) 0xab9423a7); |
|||
OP (B, C, D, A, 5, 21, (md5_uint32) 0xfc93a039); |
|||
OP (A, B, C, D, 12, 6, (md5_uint32) 0x655b59c3); |
|||
OP (D, A, B, C, 3, 10, (md5_uint32) 0x8f0ccc92); |
|||
OP (C, D, A, B, 10, 15, (md5_uint32) 0xffeff47d); |
|||
OP (B, C, D, A, 1, 21, (md5_uint32) 0x85845dd1); |
|||
OP (A, B, C, D, 8, 6, (md5_uint32) 0x6fa87e4f); |
|||
OP (D, A, B, C, 15, 10, (md5_uint32) 0xfe2ce6e0); |
|||
OP (C, D, A, B, 6, 15, (md5_uint32) 0xa3014314); |
|||
OP (B, C, D, A, 13, 21, (md5_uint32) 0x4e0811a1); |
|||
OP (A, B, C, D, 4, 6, (md5_uint32) 0xf7537e82); |
|||
OP (D, A, B, C, 11, 10, (md5_uint32) 0xbd3af235); |
|||
OP (C, D, A, B, 2, 15, (md5_uint32) 0x2ad7d2bb); |
|||
OP (B, C, D, A, 9, 21, (md5_uint32) 0xeb86d391); |
|||
|
|||
/* Add the starting values of the context. */ |
|||
A += A_save; |
|||
B += B_save; |
|||
C += C_save; |
|||
D += D_save; |
|||
} |
|||
|
|||
/* Put checksum in context given as argument. */ |
|||
ctx->A = A; |
|||
ctx->B = B; |
|||
ctx->C = C; |
|||
ctx->D = D; |
|||
} |
@ -1,146 +0,0 @@ |
|||
/* md5.h - Declaration of functions and data types used for MD5 sum |
|||
computing library functions. |
|||
|
|||
Copyright 1995, 1996, 2000 Free Software Foundation, Inc. |
|||
NOTE: The canonical source of this file is maintained with the GNU C |
|||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. |
|||
|
|||
This program is free software; you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by the |
|||
Free Software Foundation; either version 2, or (at your option) any |
|||
later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software Foundation, |
|||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|||
*/ |
|||
|
|||
#ifndef _MD5_H |
|||
#define _MD5_H 1 |
|||
|
|||
#include <stdio.h> |
|||
|
|||
#if defined HAVE_LIMITS_H || _LIBC |
|||
# include <limits.h> |
|||
#endif |
|||
|
|||
/* The following contortions are an attempt to use the C preprocessor |
|||
to determine an unsigned integral type that is 32 bits wide. An |
|||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but |
|||
doing that would require that the configure script compile and *run* |
|||
the resulting executable. Locally running cross-compiled executables |
|||
is usually not possible. |
|||
*/ |
|||
|
|||
#ifdef _LIBC |
|||
# include <sys/types.h> |
|||
typedef u_int32_t md5_uint32; |
|||
#else |
|||
# define INT_MAX_32_BITS 2147483647 |
|||
|
|||
/* If UINT_MAX isn't defined, assume it's a 32-bit type. |
|||
This should be valid for all systems GNU cares about because |
|||
that doesn't include 16-bit systems, and only modern systems |
|||
(that certainly have <limits.h>) have 64+-bit integral types. |
|||
*/ |
|||
|
|||
# ifndef INT_MAX |
|||
# define INT_MAX INT_MAX_32_BITS |
|||
# endif |
|||
|
|||
# if INT_MAX == INT_MAX_32_BITS |
|||
typedef unsigned int md5_uint32; |
|||
# else |
|||
# if SHRT_MAX == INT_MAX_32_BITS |
|||
typedef unsigned short md5_uint32; |
|||
# else |
|||
# if LONG_MAX == INT_MAX_32_BITS |
|||
typedef unsigned long md5_uint32; |
|||
# else |
|||
/* The following line is intended to evoke an error. |
|||
* Using #error is not portable enough. */ |
|||
"Cannot determine unsigned 32-bit data type." |
|||
# endif |
|||
# endif |
|||
# endif |
|||
#endif |
|||
|
|||
#undef __P |
|||
#if defined (__STDC__) && __STDC__ |
|||
#define __P(x) x |
|||
#else |
|||
#define __P(x) () |
|||
#endif |
|||
|
|||
/* Structure to save state of computation between the single steps. */ |
|||
struct md5_ctx |
|||
{ |
|||
md5_uint32 A; |
|||
md5_uint32 B; |
|||
md5_uint32 C; |
|||
md5_uint32 D; |
|||
|
|||
md5_uint32 total[2]; |
|||
md5_uint32 buflen; |
|||
char buffer[128]; |
|||
}; |
|||
|
|||
/* |
|||
* The following three functions are build up the low level used in |
|||
* the functions `md5_stream' and `md5_buffer'. |
|||
*/ |
|||
|
|||
/* Initialize structure containing state of computation. |
|||
(RFC 1321, 3.3: Step 3) */ |
|||
extern void md5_init_ctx __P ((struct md5_ctx *ctx)); |
|||
|
|||
/* Starting with the result of former calls of this function (or the |
|||
initialization function update the context for the next LEN bytes |
|||
starting at BUFFER. |
|||
It is necessary that LEN is a multiple of 64!!! */ |
|||
extern void md5_process_block __P ((const void *buffer, size_t len, |
|||
struct md5_ctx *ctx)); |
|||
|
|||
/* Starting with the result of former calls of this function (or the |
|||
initialization function update the context for the next LEN bytes |
|||
starting at BUFFER. |
|||
It is NOT required that LEN is a multiple of 64. */ |
|||
extern void md5_process_bytes __P ((const void *buffer, size_t len, |
|||
struct md5_ctx *ctx)); |
|||
|
|||
/* Process the remaining bytes in the buffer and put result from CTX |
|||
in first 16 bytes following RESBUF. The result is always in little |
|||
endian byte order, so that a byte-wise output yields to the wanted |
|||
ASCII representation of the message digest. |
|||
|
|||
IMPORTANT: On some systems it is required that RESBUF is correctly |
|||
aligned for a 32 bits value. */ |
|||
extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); |
|||
|
|||
|
|||
/* Put result from CTX in first 16 bytes following RESBUF. The result is |
|||
always in little endian byte order, so that a byte-wise output yields |
|||
to the wanted ASCII representation of the message digest. |
|||
|
|||
IMPORTANT: On some systems it is required that RESBUF is correctly |
|||
aligned for a 32 bits value. */ |
|||
extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); |
|||
|
|||
|
|||
/* Compute MD5 message digest for bytes read from STREAM. The |
|||
resulting message digest number will be written into the 16 bytes |
|||
beginning at RESBLOCK. */ |
|||
extern int md5_stream __P ((FILE *stream, void *resblock)); |
|||
|
|||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The |
|||
result is always in little endian byte order, so that a byte-wise |
|||
output yields to the wanted ASCII representation of the message |
|||
digest. */ |
|||
extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); |
|||
|
|||
#endif |
Write
Preview
Loading…
Cancel
Save
Reference in new issue