1a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* 2a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 3a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * MD5 Message-Digest Algorithm (RFC 1321). 4a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 5a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * Homepage: 6a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 8a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * Author: 9a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 10a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 11a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * This software was written by Alexander Peslyak in 2001. No copyright is 12a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * claimed, and the software is hereby placed in the public domain. 13a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * In case this attempt to disclaim copyright and place the software in the 14a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * public domain is deemed null and void, then the software is 15a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 16a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * general public under the following terms: 17a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 18a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * Redistribution and use in source and binary forms, with or without 19a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * modification, are permitted. 20a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 21a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * There's ABSOLUTELY NO WARRANTY, express or implied. 22a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 23a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * (This is a heavily cut-down "BSD license".) 24a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 25a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * This differs from Colin Plumb's older public domain implementation in that 26a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * no exactly 32-bit integer data type is required (any 32-bit or wider 27a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * unsigned integer data type will do), there's no compile-time endianness 28a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * configuration, and the function prototypes match OpenSSL's. No code from 29a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * Colin Plumb's implementation has been reused; this comment merely compares 30a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * the properties of the two independent implementations. 31a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 32a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * The primary goals of this implementation are portability and ease of use. 33a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * It is meant to be fast, but not as fast as possible. Some known 34a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * optimizations are not included to reduce source code size and avoid 35a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * compile-time configuration. 36a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang */ 37a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 38a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#ifndef HAVE_OPENSSL 39a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 40a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include <string.h> 41a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 42a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "md5.h" 43a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 44a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* 45a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * The basic MD5 functions. 46a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 47a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * F and G are optimized compared to their RFC 1321 definitions for 48a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * architectures that lack an AND-NOT instruction, just like in Colin Plumb's 49a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * implementation. 50a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang */ 51a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 52a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 53a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define H(x, y, z) ((x) ^ (y) ^ (z)) 54a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define I(x, y, z) ((y) ^ ((x) | ~(z))) 55a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 56a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* 57a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * The MD5 transformation for all four rounds. 58a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang */ 59a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define STEP(f, a, b, c, d, x, t, s) \ 60a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (a) += f((b), (c), (d)) + (x) + (t); \ 61a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 62a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (a) += (b); 63a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 64a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* 65a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * SET reads 4 input bytes in little-endian byte order and stores them 66a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * in a properly aligned word in host byte order. 67a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * 68a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * The check for little-endian architectures that tolerate unaligned 69a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * memory accesses is just an optimization. Nothing will break if it 70a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * doesn't work. 71a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang */ 72a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) 73a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define SET(n) \ 74a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (*(MD5_u32plus *)&ptr[(n) * 4]) 75a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define GET(n) \ 76a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang SET(n) 77a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#else 78a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define SET(n) \ 79a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (ctx->block[(n)] = \ 80a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (MD5_u32plus)ptr[(n) * 4] | \ 81a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ 82a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ 83a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) 84a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define GET(n) \ 85a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (ctx->block[(n)]) 86a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#endif 87a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 88a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* 89a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * This processes one or more 64-byte data blocks, but does NOT update 90a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang * the bit counters. There are no alignment requirements. 91a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang */ 92a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wangstatic void *body(MD5_CTX *ctx, void *data, unsigned long size) 93a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang{ 94a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned char *ptr; 95a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang MD5_u32plus a, b, c, d; 96a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang MD5_u32plus saved_a, saved_b, saved_c, saved_d; 97a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 98a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ptr = (unsigned char *)data; 99a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 100a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang a = ctx->a; 101a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang b = ctx->b; 102a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang c = ctx->c; 103a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang d = ctx->d; 104a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 105a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang do { 106a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang saved_a = a; 107a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang saved_b = b; 108a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang saved_c = c; 109a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang saved_d = d; 110a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 111a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* Round 1 */ 112a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 113a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 114a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 115a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 116a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 117a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 118a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 119a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 120a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 121a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 122a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 123a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 124a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 125a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 126a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 127a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 128a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 129a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* Round 2 */ 130a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 131a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 132a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 133a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 134a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 135a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 136a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 137a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 138a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 139a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 140a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 141a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 142a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 143a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 144a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 145a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 146a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 147a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* Round 3 */ 148a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 149a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) 150a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 151a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) 152a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 153a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) 154a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 155a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) 156a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 157a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) 158a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 159a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) 160a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 161a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) 162a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 163a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) 164a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 165a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* Round 4 */ 166a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 167a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 168a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 169a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 170a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 171a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 172a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 173a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 174a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 175a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 176a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 177a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 178a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 179a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 180a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 181a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 182a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 183a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang a += saved_a; 184a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang b += saved_b; 185a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang c += saved_c; 186a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang d += saved_d; 187a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 188a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ptr += 64; 189a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } while (size -= 64); 190a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 191a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->a = a; 192a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->b = b; 193a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->c = c; 194a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->d = d; 195a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 196a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return ptr; 197a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang} 198a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 199a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wangvoid MD5_Init(MD5_CTX *ctx) 200a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang{ 201a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->a = 0x67452301; 202a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->b = 0xefcdab89; 203a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->c = 0x98badcfe; 204a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->d = 0x10325476; 205a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 206a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->lo = 0; 207a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->hi = 0; 208a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang} 209a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 210a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wangvoid MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) 211a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang{ 212a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang MD5_u32plus saved_lo; 213a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned long used, free; 214a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 215a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang saved_lo = ctx->lo; 216a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) 217a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->hi++; 218a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->hi += size >> 29; 219a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 220a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang used = saved_lo & 0x3f; 221a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 222a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if (used) { 223a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang free = 64 - used; 224a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 225a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if (size < free) { 226a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang memcpy(&ctx->buffer[used], data, size); 227a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return; 228a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 229a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 230a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang memcpy(&ctx->buffer[used], data, free); 231a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang data = (unsigned char *)data + free; 232a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang size -= free; 233a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang body(ctx, ctx->buffer, 64); 234a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 235a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 236a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if (size >= 64) { 237a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang data = body(ctx, data, size & ~(unsigned long)0x3f); 238a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang size &= 0x3f; 239a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 240a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 241a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang memcpy(ctx->buffer, data, size); 242a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang} 243a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 244a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wangvoid MD5_Final(unsigned char *result, MD5_CTX *ctx) 245a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang{ 246a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned long used, free; 247a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 248a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang used = ctx->lo & 0x3f; 249a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 250a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[used++] = 0x80; 251a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 252a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang free = 64 - used; 253a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 254a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if (free < 8) { 255a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang memset(&ctx->buffer[used], 0, free); 256a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang body(ctx, ctx->buffer, 64); 257a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang used = 0; 258a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang free = 64; 259a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 260a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 261a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang memset(&ctx->buffer[used], 0, free - 8); 262a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 263a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->lo <<= 3; 264a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[56] = ctx->lo; 265a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[57] = ctx->lo >> 8; 266a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[58] = ctx->lo >> 16; 267a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[59] = ctx->lo >> 24; 268a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[60] = ctx->hi; 269a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[61] = ctx->hi >> 8; 270a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[62] = ctx->hi >> 16; 271a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ctx->buffer[63] = ctx->hi >> 24; 272a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 273a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang body(ctx, ctx->buffer, 64); 274a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 275a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[0] = ctx->a; 276a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[1] = ctx->a >> 8; 277a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[2] = ctx->a >> 16; 278a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[3] = ctx->a >> 24; 279a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[4] = ctx->b; 280a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[5] = ctx->b >> 8; 281a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[6] = ctx->b >> 16; 282a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[7] = ctx->b >> 24; 283a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[8] = ctx->c; 284a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[9] = ctx->c >> 8; 285a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[10] = ctx->c >> 16; 286a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[11] = ctx->c >> 24; 287a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[12] = ctx->d; 288a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[13] = ctx->d >> 8; 289a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[14] = ctx->d >> 16; 290a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang result[15] = ctx->d >> 24; 291a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 292a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang memset(ctx, 0, sizeof(*ctx)); 293a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang} 294a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 295a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#endif 296