A Port of TI's Webserver for the CC3000
Embed:
(wiki syntax)
Show/hide line numbers
md5.cpp
00001 /* 00002 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 00003 * MD5 Message-Digest Algorithm (RFC 1321). 00004 * 00005 * Homepage: 00006 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 00007 * 00008 * Author: 00009 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 00010 * 00011 * This software was written by Alexander Peslyak in 2001. No copyright is 00012 * claimed, and the software is hereby placed in the public domain. 00013 * In case this attempt to disclaim copyright and place the software in the 00014 * public domain is deemed null and void, then the software is 00015 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 00016 * general public under the following terms: 00017 * 00018 * Redistribution and use in source and binary forms, with or without 00019 * modification, are permitted. 00020 * 00021 * There's ABSOLUTELY NO WARRANTY, express or implied. 00022 * 00023 * (This is a heavily cut-down "BSD license".) 00024 * 00025 * This differs from Colin Plumb's older public domain implementation in that 00026 * no exactly 32-bit integer data type is required (any 32-bit or wider 00027 * unsigned integer data type will do), there's no compile-time endianness 00028 * configuration, and the function prototypes match OpenSSL's. No code from 00029 * Colin Plumb's implementation has been reused; this comment merely compares 00030 * the properties of the two independent implementations. 00031 * 00032 * The primary goals of this implementation are portability and ease of use. 00033 * It is meant to be fast, but not as fast as possible. Some known 00034 * optimizations are not included to reduce source code size and avoid 00035 * compile-time configuration. 00036 */ 00037 00038 #ifndef HAVE_OPENSSL 00039 00040 #include "mbed.h" 00041 #include <string.h> 00042 00043 #include "md5.h" 00044 00045 /* 00046 * The basic MD5 functions. 00047 * 00048 * F and G are optimized compared to their RFC 1321 definitions for 00049 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's 00050 * implementation. 00051 */ 00052 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 00053 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 00054 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00055 #define I(x, y, z) ((y) ^ ((x) | ~(z))) 00056 00057 /* 00058 * The MD5 transformation for all four rounds. 00059 */ 00060 #define STEP(f, a, b, c, d, x, t, s) \ 00061 (a) += f((b), (c), (d)) + (x) + (t); \ 00062 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 00063 (a) += (b); 00064 00065 /* 00066 * SET reads 4 input bytes in little-endian byte order and stores them 00067 * in a properly aligned word in host byte order. 00068 * 00069 * The check for little-endian architectures that tolerate unaligned 00070 * memory accesses is just an optimization. Nothing will break if it 00071 * doesn't work. 00072 */ 00073 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) 00074 #define SET(n) \ 00075 (*(MD5_u32plus *)&ptr[(n) * 4]) 00076 #define GET(n) \ 00077 SET(n) 00078 #else 00079 #define SET(n) \ 00080 (ctx->block[(n)] = \ 00081 (MD5_u32plus)ptr[(n) * 4] | \ 00082 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ 00083 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ 00084 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) 00085 #define GET(n) \ 00086 (ctx->block[(n)]) 00087 #endif 00088 00089 /* 00090 * This processes one or more 64-byte data blocks, but does NOT update 00091 * the bit counters. There are no alignment requirements. 00092 */ 00093 static void *body(MD5_CTX *ctx, void *data, unsigned long size) 00094 { 00095 unsigned char *ptr; 00096 MD5_u32plus a, b, c, d; 00097 MD5_u32plus saved_a, saved_b, saved_c, saved_d; 00098 00099 ptr = (unsigned char*)data; 00100 00101 a = ctx->a; 00102 b = ctx->b; 00103 c = ctx->c; 00104 d = ctx->d; 00105 00106 do { 00107 saved_a = a; 00108 saved_b = b; 00109 saved_c = c; 00110 saved_d = d; 00111 00112 /* Round 1 */ 00113 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 00114 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 00115 STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 00116 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 00117 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 00118 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 00119 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 00120 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 00121 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 00122 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 00123 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 00124 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 00125 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 00126 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 00127 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 00128 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 00129 00130 /* Round 2 */ 00131 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 00132 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 00133 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 00134 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 00135 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 00136 STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 00137 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 00138 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 00139 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 00140 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 00141 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 00142 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 00143 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 00144 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 00145 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 00146 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 00147 00148 /* Round 3 */ 00149 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 00150 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) 00151 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 00152 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) 00153 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 00154 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) 00155 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 00156 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) 00157 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 00158 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) 00159 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 00160 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) 00161 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 00162 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) 00163 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 00164 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) 00165 00166 /* Round 4 */ 00167 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 00168 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 00169 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 00170 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 00171 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 00172 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 00173 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 00174 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 00175 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 00176 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 00177 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 00178 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 00179 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 00180 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 00181 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 00182 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 00183 00184 a += saved_a; 00185 b += saved_b; 00186 c += saved_c; 00187 d += saved_d; 00188 00189 ptr += 64; 00190 } while (size -= 64); 00191 00192 ctx->a = a; 00193 ctx->b = b; 00194 ctx->c = c; 00195 ctx->d = d; 00196 00197 return ptr; 00198 } 00199 00200 void MD5_Init(MD5_CTX *ctx) 00201 { 00202 ctx->a = 0x67452301; 00203 ctx->b = 0xefcdab89; 00204 ctx->c = 0x98badcfe; 00205 ctx->d = 0x10325476; 00206 00207 ctx->lo = 0; 00208 ctx->hi = 0; 00209 } 00210 00211 void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) 00212 { 00213 MD5_u32plus saved_lo; 00214 unsigned long used, free; 00215 00216 saved_lo = ctx->lo; 00217 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) 00218 ctx->hi++; 00219 ctx->hi += size >> 29; 00220 00221 used = saved_lo & 0x3f; 00222 00223 if (used) { 00224 free = 64 - used; 00225 00226 if (size < free) { 00227 memcpy(&ctx->buffer[used], data, size); 00228 return; 00229 } 00230 00231 memcpy(&ctx->buffer[used], data, free); 00232 data = (unsigned char *)data + free; 00233 size -= free; 00234 body(ctx, ctx->buffer, 64); 00235 } 00236 00237 if (size >= 64) { 00238 data = body(ctx, data, size & ~(unsigned long)0x3f); 00239 size &= 0x3f; 00240 } 00241 00242 memcpy(ctx->buffer, data, size); 00243 } 00244 00245 void MD5_Final(unsigned char *result, MD5_CTX *ctx) 00246 { 00247 unsigned long used, free; 00248 00249 used = ctx->lo & 0x3f; 00250 00251 ctx->buffer[used++] = 0x80; 00252 00253 free = 64 - used; 00254 00255 if (free < 8) { 00256 memset(&ctx->buffer[used], 0, free); 00257 body(ctx, ctx->buffer, 64); 00258 used = 0; 00259 free = 64; 00260 } 00261 00262 memset(&ctx->buffer[used], 0, free - 8); 00263 00264 ctx->lo <<= 3; 00265 ctx->buffer[56] = ctx->lo; 00266 ctx->buffer[57] = ctx->lo >> 8; 00267 ctx->buffer[58] = ctx->lo >> 16; 00268 ctx->buffer[59] = ctx->lo >> 24; 00269 ctx->buffer[60] = ctx->hi; 00270 ctx->buffer[61] = ctx->hi >> 8; 00271 ctx->buffer[62] = ctx->hi >> 16; 00272 ctx->buffer[63] = ctx->hi >> 24; 00273 00274 body(ctx, ctx->buffer, 64); 00275 00276 result[0] = ctx->a; 00277 result[1] = ctx->a >> 8; 00278 result[2] = ctx->a >> 16; 00279 result[3] = ctx->a >> 24; 00280 result[4] = ctx->b; 00281 result[5] = ctx->b >> 8; 00282 result[6] = ctx->b >> 16; 00283 result[7] = ctx->b >> 24; 00284 result[8] = ctx->c; 00285 result[9] = ctx->c >> 8; 00286 result[10] = ctx->c >> 16; 00287 result[11] = ctx->c >> 24; 00288 result[12] = ctx->d; 00289 result[13] = ctx->d >> 8; 00290 result[14] = ctx->d >> 16; 00291 result[15] = ctx->d >> 24; 00292 00293 memset(ctx, 0, sizeof(*ctx)); 00294 } 00295 00296 #endif 00297
Generated on Wed Jul 13 2022 13:30:51 by
1.7.2