Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:24

0001 /*
0002  * Copyright (c) 2019 Opticks Team. All Rights Reserved.
0003  *
0004  * This file is part of Opticks
0005  * (see https://bitbucket.org/simoncblyth/opticks).
0006  *
0007  * Licensed under the Apache License, Version 2.0 (the "License"); 
0008  * you may not use this file except in compliance with the License.  
0009  * You may obtain a copy of the License at
0010  *
0011  *   http://www.apache.org/licenses/LICENSE-2.0
0012  *
0013  * Unless required by applicable law or agreed to in writing, software 
0014  * distributed under the License is distributed on an "AS IS" BASIS, 
0015  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
0016  * See the License for the specific language governing permissions and 
0017  * limitations under the License.
0018  */
0019 
0020 //  see solarmd5-
0021 /*
0022  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
0023  * MD5 Message-Digest Algorithm (RFC 1321).
0024  *
0025  * Homepage:
0026  * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
0027  *
0028  * Author:
0029  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
0030  *
0031  * This software was written by Alexander Peslyak in 2001.  No copyright is
0032  * claimed, and the software is hereby placed in the public domain.
0033  * In case this attempt to disclaim copyright and place the software in the
0034  * public domain is deemed null and void, then the software is
0035  * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
0036  * general public under the following terms:
0037  *
0038  * Redistribution and use in source and binary forms, with or without
0039  * modification, are permitted.
0040  *
0041  * There's ABSOLUTELY NO WARRANTY, express or implied.
0042  *
0043  * (This is a heavily cut-down "BSD license".)
0044  *
0045  * This differs from Colin Plumb's older public domain implementation in that
0046  * no exactly 32-bit integer data type is required (any 32-bit or wider
0047  * unsigned integer data type will do), there's no compile-time endianness
0048  * configuration, and the function prototypes match OpenSSL's.  No code from
0049  * Colin Plumb's implementation has been reused; this comment merely compares
0050  * the properties of the two independent implementations.
0051  *
0052  * The primary goals of this implementation are portability and ease of use.
0053  * It is meant to be fast, but not as fast as possible.  Some known
0054  * optimizations are not included to reduce source code size and avoid
0055  * compile-time configuration.
0056  */
0057 
0058 #ifndef HAVE_OPENSSL
0059 
0060 #include <cstring>
0061 
0062 #include "md5.hh"
0063 
0064 /*
0065  * The basic MD5 functions.
0066  *
0067  * F and G are optimized compared to their RFC 1321 definitions for
0068  * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
0069  * implementation.
0070  */
0071 #define F(x, y, z)          ((z) ^ ((x) & ((y) ^ (z))))
0072 #define G(x, y, z)          ((y) ^ ((z) & ((x) ^ (y))))
0073 #define H(x, y, z)          (((x) ^ (y)) ^ (z))
0074 #define H2(x, y, z)         ((x) ^ ((y) ^ (z)))
0075 #define I(x, y, z)          ((y) ^ ((x) | ~(z)))
0076 
0077 /*
0078  * The MD5 transformation for all four rounds.
0079  */
0080 #define STEP(f, a, b, c, d, x, t, s) \
0081     (a) += f((b), (c), (d)) + (x) + (t); \
0082     (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
0083     (a) += (b);
0084 
0085 /*
0086  * SET reads 4 input bytes in little-endian byte order and stores them
0087  * in a properly aligned word in host byte order.
0088  *
0089  * The check for little-endian architectures that tolerate unaligned
0090  * memory accesses is just an optimization.  Nothing will break if it
0091  * doesn't work.
0092  */
0093 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
0094 #define SET(n) \
0095     (*(MD5_u32plus *)&ptr[(n) * 4])
0096 #define GET(n) \
0097     SET(n)
0098 #else
0099 #define SET(n) \
0100     (ctx->block[(n)] = \
0101     (MD5_u32plus)ptr[(n) * 4] | \
0102     ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
0103     ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
0104     ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
0105 #define GET(n) \
0106     (ctx->block[(n)])
0107 #endif
0108 
0109 /*
0110  * This processes one or more 64-byte data blocks, but does NOT update
0111  * the bit counters.  There are no alignment requirements.
0112  */
0113 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
0114 {
0115     const unsigned char *ptr;
0116     MD5_u32plus a, b, c, d;
0117     MD5_u32plus saved_a, saved_b, saved_c, saved_d;
0118 
0119     ptr = (const unsigned char *)data;
0120 
0121     a = ctx->a;
0122     b = ctx->b;
0123     c = ctx->c;
0124     d = ctx->d;
0125 
0126     do {
0127         saved_a = a;
0128         saved_b = b;
0129         saved_c = c;
0130         saved_d = d;
0131 
0132 /* Round 1 */
0133         STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
0134         STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
0135         STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
0136         STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
0137         STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
0138         STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
0139         STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
0140         STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
0141         STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
0142         STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
0143         STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
0144         STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
0145         STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
0146         STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
0147         STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
0148         STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
0149 
0150 /* Round 2 */
0151         STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
0152         STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
0153         STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
0154         STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
0155         STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
0156         STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
0157         STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
0158         STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
0159         STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
0160         STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
0161         STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
0162         STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
0163         STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
0164         STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
0165         STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
0166         STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
0167 
0168 /* Round 3 */
0169         STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
0170         STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
0171         STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
0172         STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
0173         STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
0174         STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
0175         STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
0176         STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
0177         STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
0178         STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
0179         STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
0180         STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
0181         STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
0182         STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
0183         STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
0184         STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
0185 
0186 /* Round 4 */
0187         STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
0188         STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
0189         STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
0190         STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
0191         STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
0192         STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
0193         STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
0194         STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
0195         STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
0196         STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
0197         STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
0198         STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
0199         STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
0200         STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
0201         STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
0202         STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
0203 
0204         a += saved_a;
0205         b += saved_b;
0206         c += saved_c;
0207         d += saved_d;
0208 
0209         ptr += 64;
0210     } while (size -= 64);
0211 
0212     ctx->a = a;
0213     ctx->b = b;
0214     ctx->c = c;
0215     ctx->d = d;
0216 
0217     return ptr;
0218 }
0219 
0220 void MD5_Init(MD5_CTX *ctx)
0221 {
0222     ctx->a = 0x67452301;
0223     ctx->b = 0xefcdab89;
0224     ctx->c = 0x98badcfe;
0225     ctx->d = 0x10325476;
0226 
0227     ctx->lo = 0;
0228     ctx->hi = 0;
0229 }
0230 
0231 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
0232 {
0233     MD5_u32plus saved_lo;
0234     unsigned long used, available;
0235 
0236     saved_lo = ctx->lo;
0237     if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
0238         ctx->hi++;
0239     ctx->hi += size >> 29;
0240 
0241     used = saved_lo & 0x3f;
0242 
0243     if (used) {
0244         available = 64 - used;
0245 
0246         if (size < available) {
0247             memcpy(&ctx->buffer[used], data, size);
0248             return;
0249         }
0250 
0251         memcpy(&ctx->buffer[used], data, available);
0252         data = (const unsigned char *)data + available;
0253         size -= available;
0254         body(ctx, ctx->buffer, 64);
0255     }
0256 
0257     if (size >= 64) {
0258         data = body(ctx, data, size & ~(unsigned long)0x3f);
0259         size &= 0x3f;
0260     }
0261 
0262     memcpy(ctx->buffer, data, size);
0263 }
0264 
0265 
0266 
0267 #ifdef _MSC_VER
0268 // possible loss in conversion
0269 #pragma warning( disable : 4244 )
0270 #endif
0271 
0272 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
0273 {
0274     unsigned long used, available;
0275 
0276     used = ctx->lo & 0x3f;
0277 
0278     ctx->buffer[used++] = 0x80;
0279 
0280     available = 64 - used;
0281 
0282     if (available < 8) {
0283         memset(&ctx->buffer[used], 0, available);
0284         body(ctx, ctx->buffer, 64);
0285         used = 0;
0286         available = 64;
0287     }
0288 
0289     memset(&ctx->buffer[used], 0, available - 8);
0290 
0291     ctx->lo <<= 3;
0292     ctx->buffer[56] = ctx->lo;
0293     ctx->buffer[57] = ctx->lo >> 8;
0294     ctx->buffer[58] = ctx->lo >> 16;
0295     ctx->buffer[59] = ctx->lo >> 24;
0296     ctx->buffer[60] = ctx->hi;
0297     ctx->buffer[61] = ctx->hi >> 8;
0298     ctx->buffer[62] = ctx->hi >> 16;
0299     ctx->buffer[63] = ctx->hi >> 24;
0300 
0301     body(ctx, ctx->buffer, 64);
0302 
0303     result[0] = ctx->a;
0304     result[1] = ctx->a >> 8;
0305     result[2] = ctx->a >> 16;
0306     result[3] = ctx->a >> 24;
0307     result[4] = ctx->b;
0308     result[5] = ctx->b >> 8;
0309     result[6] = ctx->b >> 16;
0310     result[7] = ctx->b >> 24;
0311     result[8] = ctx->c;
0312     result[9] = ctx->c >> 8;
0313     result[10] = ctx->c >> 16;
0314     result[11] = ctx->c >> 24;
0315     result[12] = ctx->d;
0316     result[13] = ctx->d >> 8;
0317     result[14] = ctx->d >> 16;
0318     result[15] = ctx->d >> 24;
0319 
0320     memset(ctx, 0, sizeof(*ctx));
0321 }
0322 
0323 #endif