125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Functions to compute MD5 message digest of files or memory blocks. 225b3c049e70834cf33790a28643ab058b507b35cBen Cheng according to the definition of MD5 in RFC 1321 from April 1992. 325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Copyright (C) 1995-2011 Red Hat, Inc. 425b3c049e70834cf33790a28643ab058b507b35cBen Cheng This file is part of Red Hat elfutils. 525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Written by Ulrich Drepper <drepper@redhat.com>, 1995. 625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is free software; you can redistribute it and/or modify 825b3c049e70834cf33790a28643ab058b507b35cBen Cheng it under the terms of the GNU General Public License as published by the 925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Free Software Foundation; version 2 of the License. 1025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is distributed in the hope that it will be useful, but 1225b3c049e70834cf33790a28643ab058b507b35cBen Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 1325b3c049e70834cf33790a28643ab058b507b35cBen Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1425b3c049e70834cf33790a28643ab058b507b35cBen Cheng General Public License for more details. 1525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1625b3c049e70834cf33790a28643ab058b507b35cBen Cheng You should have received a copy of the GNU General Public License along 1725b3c049e70834cf33790a28643ab058b507b35cBen Cheng with Red Hat elfutils; if not, write to the Free Software Foundation, 1825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 1925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is an included package of the Open Invention Network. 2125b3c049e70834cf33790a28643ab058b507b35cBen Cheng An included package of the Open Invention Network is a package for which 2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Open Invention Network licensees cross-license their patents. No patent 2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng license is granted, either expressly or impliedly, by designation as an 2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng included package. Should you wish to participate in the Open Invention 2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Network licensing program, please visit www.openinventionnetwork.com 2625b3c049e70834cf33790a28643ab058b507b35cBen Cheng <http://www.openinventionnetwork.com>. */ 2725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef HAVE_CONFIG_H 2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng# include <config.h> 3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdlib.h> 3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <string.h> 3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/types.h> 3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "md5.h" 3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "system.h" 3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define SWAP(n) LE32 (n) 4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* This array contains the bytes used to pad the buffer to the next 4225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 64-byte boundary. (RFC 1321, 3.1: Step 1) */ 4325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; 4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Initialize structure containing state of computation. 4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (RFC 1321, 3.3: Step 3) */ 4825b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 4925b3c049e70834cf33790a28643ab058b507b35cBen Chengmd5_init_ctx (ctx) 5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct md5_ctx *ctx; 5125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->A = 0x67452301; 5325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->B = 0xefcdab89; 5425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->C = 0x98badcfe; 5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->D = 0x10325476; 5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->total[0] = ctx->total[1] = 0; 5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->buflen = 0; 5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 6025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Put result from CTX in first 16 bytes following RESBUF. The result 6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng must be in little endian byte order. 6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 6425b3c049e70834cf33790a28643ab058b507b35cBen Cheng IMPORTANT: On some systems it is required that RESBUF is correctly 6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng aligned for a 32 bits value. */ 6625b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid * 6725b3c049e70834cf33790a28643ab058b507b35cBen Chengmd5_read_ctx (ctx, resbuf) 6825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct md5_ctx *ctx; 6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *resbuf; 7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 7125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); 7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); 7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); 7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); 7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 7625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return resbuf; 7725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 7925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 8025b3c049e70834cf33790a28643ab058b507b35cBen Chengle64_copy (char *dest, uint64_t x) 8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < 8; ++i) 8325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 8425b3c049e70834cf33790a28643ab058b507b35cBen Cheng dest[i] = (uint8_t) x; 8525b3c049e70834cf33790a28643ab058b507b35cBen Cheng x >>= 8; 8625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 8725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Process the remaining bytes in the internal buffer and the usual 9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng prolog according to the standard and write the result to RESBUF. 9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9225b3c049e70834cf33790a28643ab058b507b35cBen Cheng IMPORTANT: On some systems it is required that RESBUF is correctly 9325b3c049e70834cf33790a28643ab058b507b35cBen Cheng aligned for a 32 bits value. */ 9425b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid * 9525b3c049e70834cf33790a28643ab058b507b35cBen Chengmd5_finish_ctx (ctx, resbuf) 9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct md5_ctx *ctx; 9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *resbuf; 9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 9925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Take yet unprocessed bytes into account. */ 10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 bytes = ctx->buflen; 10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t pad; 10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now count remaining bytes. */ 10425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->total[0] += bytes; 10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ctx->total[0] < bytes) 10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ctx->total[1]; 10725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10825b3c049e70834cf33790a28643ab058b507b35cBen Cheng pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; 10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (&ctx->buffer[bytes], fillbuf, pad); 11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Put the 64-bit file length in *bits* at the end of the buffer. */ 11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const uint64_t bit_length = ((ctx->total[0] << 3) 11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng + ((uint64_t) ((ctx->total[1] << 3) | 11425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (ctx->total[0] >> 29)) << 32)); 11525b3c049e70834cf33790a28643ab058b507b35cBen Cheng le64_copy (&ctx->buffer[bytes + pad], bit_length); 11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Process last bytes. */ 11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_block (ctx->buffer, bytes + pad + 8, ctx); 11925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return md5_read_ctx (ctx, resbuf); 12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 12225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef NEED_MD5_STREAM 12525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Compute MD5 message digest for bytes read from STREAM. The 12625b3c049e70834cf33790a28643ab058b507b35cBen Cheng resulting message digest number will be written into the 16 bytes 12725b3c049e70834cf33790a28643ab058b507b35cBen Cheng beginning at RESBLOCK. */ 12825b3c049e70834cf33790a28643ab058b507b35cBen Chengint 12925b3c049e70834cf33790a28643ab058b507b35cBen Chengmd5_stream (stream, resblock) 13025b3c049e70834cf33790a28643ab058b507b35cBen Cheng FILE *stream; 13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *resblock; 13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Important: BLOCKSIZE must be a multiple of 64. */ 13425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define BLOCKSIZE 4096 13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct md5_ctx ctx; 13625b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buffer[BLOCKSIZE + 72]; 13725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t sum; 13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize the computation context. */ 14025b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_init_ctx (&ctx); 14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Iterate over full file contents. */ 14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (1) 14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We read the file in blocks of BLOCKSIZE bytes. One call of the 14625b3c049e70834cf33790a28643ab058b507b35cBen Cheng computation function processes the whole buffer so that with the 14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng next round of the loop another block can be read. */ 14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t n; 14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng sum = 0; 15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Read block. Take care for partial reads. */ 15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); 15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sum += n; 15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 15825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (sum < BLOCKSIZE && n != 0); 15925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (n == 0 && ferror (stream)) 16025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 16125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If end of file is reached, end the loop. */ 16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (n == 0) 16425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Process buffer with BLOCKSIZE bytes. Note that 16725b3c049e70834cf33790a28643ab058b507b35cBen Cheng BLOCKSIZE % 64 == 0 16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng */ 16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_block (buffer, BLOCKSIZE, &ctx); 17025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the last bytes if necessary. */ 17325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sum > 0) 17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_bytes (buffer, sum, &ctx); 17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Construct result in desired memory. */ 17725b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_finish_ctx (&ctx, resblock); 17825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 17925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 18025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 18125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef NEED_MD5_BUFFER 18425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The 18525b3c049e70834cf33790a28643ab058b507b35cBen Cheng result is always in little endian byte order, so that a byte-wise 18625b3c049e70834cf33790a28643ab058b507b35cBen Cheng output yields to the wanted ASCII representation of the message 18725b3c049e70834cf33790a28643ab058b507b35cBen Cheng digest. */ 18825b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid * 18925b3c049e70834cf33790a28643ab058b507b35cBen Chengmd5_buffer (buffer, len, resblock) 19025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *buffer; 19125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len; 19225b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *resblock; 19325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 19425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct md5_ctx ctx; 19525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize the computation context. */ 19725b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_init_ctx (&ctx); 19825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Process whole buffer but last len % 64 bytes. */ 20025b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_bytes (buffer, len, &ctx); 20125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Put result in desired memory area. */ 20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return md5_finish_ctx (&ctx, resblock); 20425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 20525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 20625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20825b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 20925b3c049e70834cf33790a28643ab058b507b35cBen Chengmd5_process_bytes (buffer, len, ctx) 21025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const void *buffer; 21125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len; 21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct md5_ctx *ctx; 21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When we already have some bits in our internal buffer concatenate 21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng both inputs first. */ 21625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ctx->buflen != 0) 21725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t left_over = ctx->buflen; 21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t add = 128 - left_over > len ? len : 128 - left_over; 22025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22125b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (&ctx->buffer[left_over], buffer, add); 22225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->buflen += add; 22325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ctx->buflen > 64) 22525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 22625b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); 22725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->buflen &= 63; 22925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The regions in the following copy operation cannot overlap. */ 23025b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], 23125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->buflen); 23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 23325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23425b3c049e70834cf33790a28643ab058b507b35cBen Cheng buffer = (const char *) buffer + add; 23525b3c049e70834cf33790a28643ab058b507b35cBen Cheng len -= add; 23625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 23725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Process available complete blocks. */ 23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (len >= 64) 24025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 24125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if !_STRING_ARCH_unaligned 24225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* To check alignment gcc has an appropriate operator. Other 24325b3c049e70834cf33790a28643ab058b507b35cBen Cheng compilers don't. */ 24425b3c049e70834cf33790a28643ab058b507b35cBen Cheng# if __GNUC__ >= 2 24525b3c049e70834cf33790a28643ab058b507b35cBen Cheng# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0) 24625b3c049e70834cf33790a28643ab058b507b35cBen Cheng# else 24725b3c049e70834cf33790a28643ab058b507b35cBen Cheng# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0) 24825b3c049e70834cf33790a28643ab058b507b35cBen Cheng# endif 24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (UNALIGNED_P (buffer)) 25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (len > 64) 25125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 25225b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); 25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng buffer = (const char *) buffer + 64; 25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng len -= 64; 25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 25825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 25925b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_block (buffer, len & ~63, ctx); 26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng buffer = (const char *) buffer + (len & ~63); 26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng len &= 63; 26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Move remaining bytes in internal buffer. */ 26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (len > 0) 26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t left_over = ctx->buflen; 26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (&ctx->buffer[left_over], buffer, len); 27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng left_over += len; 27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (left_over >= 64) 27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_process_block (ctx->buffer, 64, ctx); 27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng left_over -= 64; 27625b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ctx->buffer, &ctx->buffer[64], left_over); 27725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->buflen = left_over; 27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 28125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* These are the four functions used in the four steps of the MD5 algorithm 28425b3c049e70834cf33790a28643ab058b507b35cBen Cheng and defined in the RFC 1321. The first function is a little bit optimized 28525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (as found in Colin Plumbs public domain implementation). */ 28625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* #define FF(b, c, d) ((b & c) | (~b & d)) */ 28725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define FF(b, c, d) (d ^ (b & (c ^ d))) 28825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define FG(b, c, d) FF (d, b, c) 28925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define FH(b, c, d) (b ^ c ^ d) 29025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define FI(b, c, d) (c ^ (b | ~d)) 29125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 29225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Process LEN bytes of BUFFER, accumulating context into CTX. 29325b3c049e70834cf33790a28643ab058b507b35cBen Cheng It is assumed that LEN % 64 == 0. */ 29425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 29525b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 29625b3c049e70834cf33790a28643ab058b507b35cBen Chengmd5_process_block (buffer, len, ctx) 29725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const void *buffer; 29825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len; 29925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct md5_ctx *ctx; 30025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 30125b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 correct_words[16]; 30225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const md5_uint32 *words = buffer; 30325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nwords = len / sizeof (md5_uint32); 30425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const md5_uint32 *endp = words + nwords; 30525b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 A = ctx->A; 30625b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 B = ctx->B; 30725b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 C = ctx->C; 30825b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 D = ctx->D; 30925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 31025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First increment the byte count. RFC 1321 specifies the possible 31125b3c049e70834cf33790a28643ab058b507b35cBen Cheng length of the file up to 2^64 bits. Here we only compute the 31225b3c049e70834cf33790a28643ab058b507b35cBen Cheng number of bytes. Do a double word increment. */ 31325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->total[0] += len; 31425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ctx->total[0] < len) 31525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ctx->total[1]; 31625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 31725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Process all bytes in the buffer with 64 bytes in each round of 31825b3c049e70834cf33790a28643ab058b507b35cBen Cheng the loop. */ 31925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (words < endp) 32025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 32125b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 *cwp = correct_words; 32225b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 A_save = A; 32325b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 B_save = B; 32425b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 C_save = C; 32525b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_uint32 D_save = D; 32625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 32725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First round: using the given function, the context and a constant 32825b3c049e70834cf33790a28643ab058b507b35cBen Cheng the next context is computed. Because the algorithms processing 32925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unit is a 32-bit word and it is determined to work on words in 33025b3c049e70834cf33790a28643ab058b507b35cBen Cheng little endian byte order we perhaps have to change the byte order 33125b3c049e70834cf33790a28643ab058b507b35cBen Cheng before the computation. To reduce the work for the next steps 33225b3c049e70834cf33790a28643ab058b507b35cBen Cheng we store the swapped words in the array CORRECT_WORDS. */ 33325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 33425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define OP(a, b, c, d, s, T) \ 33525b3c049e70834cf33790a28643ab058b507b35cBen Cheng do \ 33625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { \ 33725b3c049e70834cf33790a28643ab058b507b35cBen Cheng a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ 33825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++words; \ 33925b3c049e70834cf33790a28643ab058b507b35cBen Cheng CYCLIC (a, s); \ 34025b3c049e70834cf33790a28643ab058b507b35cBen Cheng a += b; \ 34125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } \ 34225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (0) 34325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 34425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* It is unfortunate that C does not provide an operator for 34525b3c049e70834cf33790a28643ab058b507b35cBen Cheng cyclic rotation. Hope the C compiler is smart enough. */ 34625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) 34725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 34825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Before we start, one word to the strange constants. 34925b3c049e70834cf33790a28643ab058b507b35cBen Cheng They are defined in RFC 1321 as 35025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 35125b3c049e70834cf33790a28643ab058b507b35cBen Cheng T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 35225b3c049e70834cf33790a28643ab058b507b35cBen Cheng */ 35325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 35425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Round 1. */ 35525b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (A, B, C, D, 7, 0xd76aa478); 35625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (D, A, B, C, 12, 0xe8c7b756); 35725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (C, D, A, B, 17, 0x242070db); 35825b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (B, C, D, A, 22, 0xc1bdceee); 35925b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (A, B, C, D, 7, 0xf57c0faf); 36025b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (D, A, B, C, 12, 0x4787c62a); 36125b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (C, D, A, B, 17, 0xa8304613); 36225b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (B, C, D, A, 22, 0xfd469501); 36325b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (A, B, C, D, 7, 0x698098d8); 36425b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (D, A, B, C, 12, 0x8b44f7af); 36525b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (C, D, A, B, 17, 0xffff5bb1); 36625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (B, C, D, A, 22, 0x895cd7be); 36725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (A, B, C, D, 7, 0x6b901122); 36825b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (D, A, B, C, 12, 0xfd987193); 36925b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (C, D, A, B, 17, 0xa679438e); 37025b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (B, C, D, A, 22, 0x49b40821); 37125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 37225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* For the second to fourth round we have the possibly swapped words 37325b3c049e70834cf33790a28643ab058b507b35cBen Cheng in CORRECT_WORDS. Redefine the macro to take an additional first 37425b3c049e70834cf33790a28643ab058b507b35cBen Cheng argument specifying the function to use. */ 37525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef OP 37625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define OP(f, a, b, c, d, k, s, T) \ 37725b3c049e70834cf33790a28643ab058b507b35cBen Cheng do \ 37825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { \ 37925b3c049e70834cf33790a28643ab058b507b35cBen Cheng a += f (b, c, d) + correct_words[k] + T; \ 38025b3c049e70834cf33790a28643ab058b507b35cBen Cheng CYCLIC (a, s); \ 38125b3c049e70834cf33790a28643ab058b507b35cBen Cheng a += b; \ 38225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } \ 38325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (0) 38425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 38525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Round 2. */ 38625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, A, B, C, D, 1, 5, 0xf61e2562); 38725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, D, A, B, C, 6, 9, 0xc040b340); 38825b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, C, D, A, B, 11, 14, 0x265e5a51); 38925b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); 39025b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, A, B, C, D, 5, 5, 0xd62f105d); 39125b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, D, A, B, C, 10, 9, 0x02441453); 39225b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); 39325b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); 39425b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); 39525b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, D, A, B, C, 14, 9, 0xc33707d6); 39625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); 39725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, B, C, D, A, 8, 20, 0x455a14ed); 39825b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); 39925b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); 40025b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, C, D, A, B, 7, 14, 0x676f02d9); 40125b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); 40225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 40325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Round 3. */ 40425b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, A, B, C, D, 5, 4, 0xfffa3942); 40525b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, D, A, B, C, 8, 11, 0x8771f681); 40625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); 40725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, B, C, D, A, 14, 23, 0xfde5380c); 40825b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, A, B, C, D, 1, 4, 0xa4beea44); 40925b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); 41025b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); 41125b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); 41225b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); 41325b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); 41425b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); 41525b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, B, C, D, A, 6, 23, 0x04881d05); 41625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); 41725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); 41825b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); 41925b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); 42025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 42125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Round 4. */ 42225b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, A, B, C, D, 0, 6, 0xf4292244); 42325b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, D, A, B, C, 7, 10, 0x432aff97); 42425b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, C, D, A, B, 14, 15, 0xab9423a7); 42525b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, B, C, D, A, 5, 21, 0xfc93a039); 42625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, A, B, C, D, 12, 6, 0x655b59c3); 42725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); 42825b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, C, D, A, B, 10, 15, 0xffeff47d); 42925b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, B, C, D, A, 1, 21, 0x85845dd1); 43025b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); 43125b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); 43225b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, C, D, A, B, 6, 15, 0xa3014314); 43325b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); 43425b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, A, B, C, D, 4, 6, 0xf7537e82); 43525b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, D, A, B, C, 11, 10, 0xbd3af235); 43625b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); 43725b3c049e70834cf33790a28643ab058b507b35cBen Cheng OP (FI, B, C, D, A, 9, 21, 0xeb86d391); 43825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 43925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the starting values of the context. */ 44025b3c049e70834cf33790a28643ab058b507b35cBen Cheng A += A_save; 44125b3c049e70834cf33790a28643ab058b507b35cBen Cheng B += B_save; 44225b3c049e70834cf33790a28643ab058b507b35cBen Cheng C += C_save; 44325b3c049e70834cf33790a28643ab058b507b35cBen Cheng D += D_save; 44425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 44625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Put checksum in context given as argument. */ 44725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->A = A; 44825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->B = B; 44925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->C = C; 45025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ctx->D = D; 45125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 452