Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
md5.c
00001 /**************************************************************************** 00002 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd 00003 * 00004 * This file is part of the Satellite Observers Workbench (SOWB). 00005 * 00006 * SOWB is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * SOWB is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with SOWB. If not, see <http://www.gnu.org/licenses/>. 00018 * 00019 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ 00020 * 00021 ***************************************************************************/ 00022 00023 /* 00024 Not even sure where I lifted this code now, but I think it was the 00025 FreeBSD project. So any copyright that is attributable to that project 00026 and the BSD license is acknowledged. This module is dual licensed:- 00027 00028 http://www.opensource.org/licenses/bsd-license.php 00029 00030 Copyright (c) 2010, Stellar Technologies Ltd/Andy Kirkham 00031 All rights reserved. 00032 00033 Redistribution and use in source and binary forms, with or without modification, 00034 are permitted provided that the following conditions are met: 00035 00036 * Redistributions of source code must retain the above copyright notice, this 00037 list of conditions and the following disclaimer. 00038 * Redistributions in binary form must reproduce the above copyright notice, 00039 this list of conditions and the following disclaimer in the documentation 00040 and/or other materials provided with the distribution. 00041 * Neither the name of the <ORGANIZATION> nor the names of its contributors may 00042 be used to endorse or promote products derived from this software without 00043 specific prior written permission. 00044 00045 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00046 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00047 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00048 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00049 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00050 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00051 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00052 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00053 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00054 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00055 00056 Additionally see http://www.freebsd.org/copyright/license.html 00057 */ 00058 00059 #include "sowb.h" 00060 00061 /** 00062 * MD5 context structure. 00063 */ 00064 typedef struct { 00065 uint32_t lo, hi; 00066 uint32_t a, b, c, d; 00067 unsigned char buffer[64]; 00068 uint32_t block[16]; 00069 } MD5_CTX; 00070 00071 /* Used to create human text for MD5 */ 00072 static const char hexits[17] = "0123456789ABCDEF"; 00073 00074 /** 00075 * Internal function prototypes. 00076 */ 00077 static void make_digest(char *md5str, unsigned char *digest); 00078 static void md5_init(MD5_CTX *); 00079 static void md5_update(MD5_CTX *, const void *, unsigned int); 00080 static void md5_final(unsigned char *, MD5_CTX *); 00081 static const void *body(MD5_CTX *, const void *, unsigned int); 00082 00083 void md5(const char *s, char *md5str) { 00084 00085 // A local MD5 context. 00086 MD5_CTX context; 00087 00088 // Place to store the raw MD5 digest. 00089 unsigned char digest[16]; 00090 00091 // Clear the output string and initialise the context. 00092 md5str[0] = '\0'; 00093 md5_init(&context); 00094 00095 // Make the MD5 and finalise. 00096 md5_update(&context, s, strlen(s)); 00097 md5_final(digest, &context); 00098 00099 // Convert the binary digest into human text in the caller's output buffer. 00100 make_digest(md5str, digest); 00101 } 00102 00103 /** 00104 * md5_short 00105 * 00106 * As MD5 function but selects 5 fixed characters 00107 * from the 32 generated to return a short name. 00108 */ 00109 void md5_short(const char *s, char *md5str, int d) { 00110 char temp[33]; 00111 static const int day[7][5] = { 00112 { 18, 3, 8, 27, 19 }, // 01 00113 { 12, 11, 6, 21, 15 }, // 02 00114 { 27, 14, 12, 4, 11 }, // 03 00115 { 12, 18, 13, 6, 2 }, // 04 00116 { 29, 13, 8, 1, 15 }, // 05 00117 { 13, 12, 9, 30, 22 }, // 06 00118 { 29, 31, 2, 5, 14 } // 07 00119 }; 00120 00121 // Get the full MD5 string. 00122 md5(s, temp); 00123 00124 // Ensure we stay within our array boundaries. 00125 d &= 0x7; 00126 00127 // Get the shortened version of the MD5. 00128 md5str[0] = temp[day[d][0]]; 00129 md5str[1] = temp[day[d][1]]; 00130 md5str[2] = temp[day[d][2]]; 00131 md5str[3] = temp[day[d][3]]; 00132 md5str[4] = temp[day[d][4]]; 00133 md5str[5] = '\0'; 00134 } 00135 00136 static void make_digest(char *md5str, unsigned char *digest) { 00137 int i; 00138 00139 for (i = 0; i < 16; i++) { 00140 md5str[i * 2] = hexits[digest[i] >> 4]; 00141 md5str[(i * 2) + 1] = hexits[digest[i] & 0x0F]; 00142 } 00143 00144 md5str[32] = '\0'; 00145 } 00146 00147 /* 00148 * This is an OpenSSL-compatible implementation of the RSA Data Security, 00149 * Inc. MD5 Message-Digest Algorithm (RFC 1321). 00150 * 00151 * Written by Solar Designer <solar at openwall.com> in 2001, and placed 00152 * in the public domain. There's absolutely no warranty. 00153 * 00154 * This differs from Colin Plumb's older public domain implementation in 00155 * that no 32-bit integer data type is required, there's no compile-time 00156 * endianness configuration, and the function prototypes match OpenSSL's. 00157 * The primary goals are portability and ease of use. 00158 * 00159 * This implementation is meant to be fast, but not as fast as possible. 00160 * Some known optimizations are not included to reduce source code size 00161 * and avoid compile-time configuration. 00162 */ 00163 00164 00165 /* 00166 * The basic MD5 functions. 00167 * 00168 * F and G are optimized compared to their RFC 1321 definitions for 00169 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's 00170 * implementation. 00171 */ 00172 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 00173 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 00174 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00175 #define I(x, y, z) ((y) ^ ((x) | ~(z))) 00176 00177 /* 00178 * The MD5 transformation for all four rounds. 00179 */ 00180 #define STEP(f, a, b, c, d, x, t, s) \ 00181 (a) += f((b), (c), (d)) + (x) + (t); \ 00182 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 00183 (a) += (b); 00184 00185 # define SET(n) \ 00186 (ctx->block[(n)] = \ 00187 (uint32_t)ptr[(n) * 4] | \ 00188 ((uint32_t)ptr[(n) * 4 + 1] << 8) | \ 00189 ((uint32_t)ptr[(n) * 4 + 2] << 16) | \ 00190 ((uint32_t)ptr[(n) * 4 + 3] << 24)) 00191 # define GET(n) \ 00192 (ctx->block[(n)]) 00193 00194 /* 00195 * This processes one or more 64-byte data blocks, but does NOT update 00196 * the bit counters. There are no alignment requirements. 00197 */ 00198 static const void *body(MD5_CTX *ctx, const void *data, unsigned int size) { 00199 const unsigned char *ptr; 00200 uint32_t a, b, c, d; 00201 uint32_t saved_a, saved_b, saved_c, saved_d; 00202 00203 ptr = (const unsigned char *)data; 00204 00205 a = ctx->a; 00206 b = ctx->b; 00207 c = ctx->c; 00208 d = ctx->d; 00209 00210 do { 00211 saved_a = a; 00212 saved_b = b; 00213 saved_c = c; 00214 saved_d = d; 00215 00216 /* Round 1 */ 00217 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 00218 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 00219 STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 00220 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 00221 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 00222 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 00223 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 00224 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 00225 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 00226 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 00227 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 00228 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 00229 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 00230 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 00231 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 00232 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 00233 00234 /* Round 2 */ 00235 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 00236 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 00237 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 00238 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 00239 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 00240 STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 00241 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 00242 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 00243 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 00244 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 00245 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 00246 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 00247 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 00248 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 00249 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 00250 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 00251 00252 /* Round 3 */ 00253 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 00254 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) 00255 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 00256 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) 00257 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 00258 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) 00259 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 00260 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) 00261 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 00262 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) 00263 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 00264 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) 00265 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 00266 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) 00267 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 00268 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) 00269 00270 /* Round 4 */ 00271 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 00272 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 00273 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 00274 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 00275 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 00276 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 00277 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 00278 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 00279 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 00280 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 00281 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 00282 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 00283 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 00284 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 00285 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 00286 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 00287 00288 a += saved_a; 00289 b += saved_b; 00290 c += saved_c; 00291 d += saved_d; 00292 00293 ptr += 64; 00294 } while (size -= 64); 00295 00296 ctx->a = a; 00297 ctx->b = b; 00298 ctx->c = c; 00299 ctx->d = d; 00300 00301 return ptr; 00302 } 00303 00304 static void md5_init(MD5_CTX *ctx) { 00305 ctx->a = 0x67452301; 00306 ctx->b = 0xefcdab89; 00307 ctx->c = 0x98badcfe; 00308 ctx->d = 0x10325476; 00309 00310 ctx->lo = 0; 00311 ctx->hi = 0; 00312 } 00313 00314 static void md5_update(MD5_CTX *ctx, const void *data, unsigned int size) { 00315 uint32_t saved_lo; 00316 uint32_t used, free; 00317 00318 saved_lo = ctx->lo; 00319 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) { 00320 ctx->hi++; 00321 } 00322 ctx->hi += size >> 29; 00323 00324 used = saved_lo & 0x3f; 00325 00326 if (used) { 00327 free = 64 - used; 00328 00329 if (size < free) { 00330 memcpy(&ctx->buffer[used], data, size); 00331 return; 00332 } 00333 00334 memcpy(&ctx->buffer[used], data, free); 00335 data = (unsigned char *)data + free; 00336 size -= free; 00337 body(ctx, ctx->buffer, 64); 00338 } 00339 00340 if (size >= 64) { 00341 data = body(ctx, data, size & ~(size_t)0x3f); 00342 size &= 0x3f; 00343 } 00344 00345 memcpy(ctx->buffer, data, size); 00346 } 00347 00348 static void md5_final(unsigned char *result, MD5_CTX *ctx) { 00349 uint32_t used, free; 00350 00351 used = ctx->lo & 0x3f; 00352 00353 ctx->buffer[used++] = 0x80; 00354 00355 free = 64 - used; 00356 00357 if (free < 8) { 00358 memset(&ctx->buffer[used], 0, free); 00359 body(ctx, ctx->buffer, 64); 00360 used = 0; 00361 free = 64; 00362 } 00363 00364 memset(&ctx->buffer[used], 0, free - 8); 00365 00366 ctx->lo <<= 3; 00367 ctx->buffer[56] = (unsigned char)ctx->lo; 00368 ctx->buffer[57] = (unsigned char)(ctx->lo >> 8); 00369 ctx->buffer[58] = (unsigned char)(ctx->lo >> 16); 00370 ctx->buffer[59] = (unsigned char)(ctx->lo >> 24); 00371 ctx->buffer[60] = (unsigned char)(ctx->hi); 00372 ctx->buffer[61] = (unsigned char)(ctx->hi >> 8); 00373 ctx->buffer[62] = (unsigned char)(ctx->hi >> 16); 00374 ctx->buffer[63] = (unsigned char)(ctx->hi >> 24); 00375 00376 body(ctx, ctx->buffer, 64); 00377 00378 result[0] = (unsigned char)ctx->a; 00379 result[1] = (unsigned char)(ctx->a >> 8); 00380 result[2] = (unsigned char)(ctx->a >> 16); 00381 result[3] = (unsigned char)(ctx->a >> 24); 00382 result[4] = (unsigned char)ctx->b; 00383 result[5] = (unsigned char)(ctx->b >> 8); 00384 result[6] = (unsigned char)(ctx->b >> 16); 00385 result[7] = (unsigned char)(ctx->b >> 24); 00386 result[8] = (unsigned char)ctx->c; 00387 result[9] = (unsigned char)(ctx->c >> 8); 00388 result[10] = (unsigned char)(ctx->c >> 16); 00389 result[11] = (unsigned char)(ctx->c >> 24); 00390 result[12] = (unsigned char)ctx->d; 00391 result[13] = (unsigned char)(ctx->d >> 8); 00392 result[14] = (unsigned char)(ctx->d >> 16); 00393 result[15] = (unsigned char)(ctx->d >> 24); 00394 00395 memset(ctx, 0, sizeof(*ctx)); 00396 }
Generated on Tue Jul 12 2022 18:05:35 by 1.7.2