Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
md5/md5.c@0:0a841b89d614, 2010-10-11 (annotated)
- Committer:
- AjK
- Date:
- Mon Oct 11 10:34:55 2010 +0000
- Revision:
- 0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AjK | 0:0a841b89d614 | 1 | /**************************************************************************** |
AjK | 0:0a841b89d614 | 2 | * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd |
AjK | 0:0a841b89d614 | 3 | * |
AjK | 0:0a841b89d614 | 4 | * This file is part of the Satellite Observers Workbench (SOWB). |
AjK | 0:0a841b89d614 | 5 | * |
AjK | 0:0a841b89d614 | 6 | * SOWB is free software: you can redistribute it and/or modify |
AjK | 0:0a841b89d614 | 7 | * it under the terms of the GNU General Public License as published by |
AjK | 0:0a841b89d614 | 8 | * the Free Software Foundation, either version 3 of the License, or |
AjK | 0:0a841b89d614 | 9 | * (at your option) any later version. |
AjK | 0:0a841b89d614 | 10 | * |
AjK | 0:0a841b89d614 | 11 | * SOWB is distributed in the hope that it will be useful, |
AjK | 0:0a841b89d614 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
AjK | 0:0a841b89d614 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
AjK | 0:0a841b89d614 | 14 | * GNU General Public License for more details. |
AjK | 0:0a841b89d614 | 15 | * |
AjK | 0:0a841b89d614 | 16 | * You should have received a copy of the GNU General Public License |
AjK | 0:0a841b89d614 | 17 | * along with SOWB. If not, see <http://www.gnu.org/licenses/>. |
AjK | 0:0a841b89d614 | 18 | * |
AjK | 0:0a841b89d614 | 19 | * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ |
AjK | 0:0a841b89d614 | 20 | * |
AjK | 0:0a841b89d614 | 21 | ***************************************************************************/ |
AjK | 0:0a841b89d614 | 22 | |
AjK | 0:0a841b89d614 | 23 | /* |
AjK | 0:0a841b89d614 | 24 | Not even sure where I lifted this code now, but I think it was the |
AjK | 0:0a841b89d614 | 25 | FreeBSD project. So any copyright that is attributable to that project |
AjK | 0:0a841b89d614 | 26 | and the BSD license is acknowledged. This module is dual licensed:- |
AjK | 0:0a841b89d614 | 27 | |
AjK | 0:0a841b89d614 | 28 | http://www.opensource.org/licenses/bsd-license.php |
AjK | 0:0a841b89d614 | 29 | |
AjK | 0:0a841b89d614 | 30 | Copyright (c) 2010, Stellar Technologies Ltd/Andy Kirkham |
AjK | 0:0a841b89d614 | 31 | All rights reserved. |
AjK | 0:0a841b89d614 | 32 | |
AjK | 0:0a841b89d614 | 33 | Redistribution and use in source and binary forms, with or without modification, |
AjK | 0:0a841b89d614 | 34 | are permitted provided that the following conditions are met: |
AjK | 0:0a841b89d614 | 35 | |
AjK | 0:0a841b89d614 | 36 | * Redistributions of source code must retain the above copyright notice, this |
AjK | 0:0a841b89d614 | 37 | list of conditions and the following disclaimer. |
AjK | 0:0a841b89d614 | 38 | * Redistributions in binary form must reproduce the above copyright notice, |
AjK | 0:0a841b89d614 | 39 | this list of conditions and the following disclaimer in the documentation |
AjK | 0:0a841b89d614 | 40 | and/or other materials provided with the distribution. |
AjK | 0:0a841b89d614 | 41 | * Neither the name of the <ORGANIZATION> nor the names of its contributors may |
AjK | 0:0a841b89d614 | 42 | be used to endorse or promote products derived from this software without |
AjK | 0:0a841b89d614 | 43 | specific prior written permission. |
AjK | 0:0a841b89d614 | 44 | |
AjK | 0:0a841b89d614 | 45 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
AjK | 0:0a841b89d614 | 46 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
AjK | 0:0a841b89d614 | 47 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
AjK | 0:0a841b89d614 | 48 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
AjK | 0:0a841b89d614 | 49 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
AjK | 0:0a841b89d614 | 50 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
AjK | 0:0a841b89d614 | 51 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
AjK | 0:0a841b89d614 | 52 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
AjK | 0:0a841b89d614 | 53 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
AjK | 0:0a841b89d614 | 54 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
AjK | 0:0a841b89d614 | 55 | |
AjK | 0:0a841b89d614 | 56 | Additionally see http://www.freebsd.org/copyright/license.html |
AjK | 0:0a841b89d614 | 57 | */ |
AjK | 0:0a841b89d614 | 58 | |
AjK | 0:0a841b89d614 | 59 | #include "sowb.h" |
AjK | 0:0a841b89d614 | 60 | |
AjK | 0:0a841b89d614 | 61 | /** |
AjK | 0:0a841b89d614 | 62 | * MD5 context structure. |
AjK | 0:0a841b89d614 | 63 | */ |
AjK | 0:0a841b89d614 | 64 | typedef struct { |
AjK | 0:0a841b89d614 | 65 | uint32_t lo, hi; |
AjK | 0:0a841b89d614 | 66 | uint32_t a, b, c, d; |
AjK | 0:0a841b89d614 | 67 | unsigned char buffer[64]; |
AjK | 0:0a841b89d614 | 68 | uint32_t block[16]; |
AjK | 0:0a841b89d614 | 69 | } MD5_CTX; |
AjK | 0:0a841b89d614 | 70 | |
AjK | 0:0a841b89d614 | 71 | /* Used to create human text for MD5 */ |
AjK | 0:0a841b89d614 | 72 | static const char hexits[17] = "0123456789ABCDEF"; |
AjK | 0:0a841b89d614 | 73 | |
AjK | 0:0a841b89d614 | 74 | /** |
AjK | 0:0a841b89d614 | 75 | * Internal function prototypes. |
AjK | 0:0a841b89d614 | 76 | */ |
AjK | 0:0a841b89d614 | 77 | static void make_digest(char *md5str, unsigned char *digest); |
AjK | 0:0a841b89d614 | 78 | static void md5_init(MD5_CTX *); |
AjK | 0:0a841b89d614 | 79 | static void md5_update(MD5_CTX *, const void *, unsigned int); |
AjK | 0:0a841b89d614 | 80 | static void md5_final(unsigned char *, MD5_CTX *); |
AjK | 0:0a841b89d614 | 81 | static const void *body(MD5_CTX *, const void *, unsigned int); |
AjK | 0:0a841b89d614 | 82 | |
AjK | 0:0a841b89d614 | 83 | void md5(const char *s, char *md5str) { |
AjK | 0:0a841b89d614 | 84 | |
AjK | 0:0a841b89d614 | 85 | // A local MD5 context. |
AjK | 0:0a841b89d614 | 86 | MD5_CTX context; |
AjK | 0:0a841b89d614 | 87 | |
AjK | 0:0a841b89d614 | 88 | // Place to store the raw MD5 digest. |
AjK | 0:0a841b89d614 | 89 | unsigned char digest[16]; |
AjK | 0:0a841b89d614 | 90 | |
AjK | 0:0a841b89d614 | 91 | // Clear the output string and initialise the context. |
AjK | 0:0a841b89d614 | 92 | md5str[0] = '\0'; |
AjK | 0:0a841b89d614 | 93 | md5_init(&context); |
AjK | 0:0a841b89d614 | 94 | |
AjK | 0:0a841b89d614 | 95 | // Make the MD5 and finalise. |
AjK | 0:0a841b89d614 | 96 | md5_update(&context, s, strlen(s)); |
AjK | 0:0a841b89d614 | 97 | md5_final(digest, &context); |
AjK | 0:0a841b89d614 | 98 | |
AjK | 0:0a841b89d614 | 99 | // Convert the binary digest into human text in the caller's output buffer. |
AjK | 0:0a841b89d614 | 100 | make_digest(md5str, digest); |
AjK | 0:0a841b89d614 | 101 | } |
AjK | 0:0a841b89d614 | 102 | |
AjK | 0:0a841b89d614 | 103 | /** |
AjK | 0:0a841b89d614 | 104 | * md5_short |
AjK | 0:0a841b89d614 | 105 | * |
AjK | 0:0a841b89d614 | 106 | * As MD5 function but selects 5 fixed characters |
AjK | 0:0a841b89d614 | 107 | * from the 32 generated to return a short name. |
AjK | 0:0a841b89d614 | 108 | */ |
AjK | 0:0a841b89d614 | 109 | void md5_short(const char *s, char *md5str, int d) { |
AjK | 0:0a841b89d614 | 110 | char temp[33]; |
AjK | 0:0a841b89d614 | 111 | static const int day[7][5] = { |
AjK | 0:0a841b89d614 | 112 | { 18, 3, 8, 27, 19 }, // 01 |
AjK | 0:0a841b89d614 | 113 | { 12, 11, 6, 21, 15 }, // 02 |
AjK | 0:0a841b89d614 | 114 | { 27, 14, 12, 4, 11 }, // 03 |
AjK | 0:0a841b89d614 | 115 | { 12, 18, 13, 6, 2 }, // 04 |
AjK | 0:0a841b89d614 | 116 | { 29, 13, 8, 1, 15 }, // 05 |
AjK | 0:0a841b89d614 | 117 | { 13, 12, 9, 30, 22 }, // 06 |
AjK | 0:0a841b89d614 | 118 | { 29, 31, 2, 5, 14 } // 07 |
AjK | 0:0a841b89d614 | 119 | }; |
AjK | 0:0a841b89d614 | 120 | |
AjK | 0:0a841b89d614 | 121 | // Get the full MD5 string. |
AjK | 0:0a841b89d614 | 122 | md5(s, temp); |
AjK | 0:0a841b89d614 | 123 | |
AjK | 0:0a841b89d614 | 124 | // Ensure we stay within our array boundaries. |
AjK | 0:0a841b89d614 | 125 | d &= 0x7; |
AjK | 0:0a841b89d614 | 126 | |
AjK | 0:0a841b89d614 | 127 | // Get the shortened version of the MD5. |
AjK | 0:0a841b89d614 | 128 | md5str[0] = temp[day[d][0]]; |
AjK | 0:0a841b89d614 | 129 | md5str[1] = temp[day[d][1]]; |
AjK | 0:0a841b89d614 | 130 | md5str[2] = temp[day[d][2]]; |
AjK | 0:0a841b89d614 | 131 | md5str[3] = temp[day[d][3]]; |
AjK | 0:0a841b89d614 | 132 | md5str[4] = temp[day[d][4]]; |
AjK | 0:0a841b89d614 | 133 | md5str[5] = '\0'; |
AjK | 0:0a841b89d614 | 134 | } |
AjK | 0:0a841b89d614 | 135 | |
AjK | 0:0a841b89d614 | 136 | static void make_digest(char *md5str, unsigned char *digest) { |
AjK | 0:0a841b89d614 | 137 | int i; |
AjK | 0:0a841b89d614 | 138 | |
AjK | 0:0a841b89d614 | 139 | for (i = 0; i < 16; i++) { |
AjK | 0:0a841b89d614 | 140 | md5str[i * 2] = hexits[digest[i] >> 4]; |
AjK | 0:0a841b89d614 | 141 | md5str[(i * 2) + 1] = hexits[digest[i] & 0x0F]; |
AjK | 0:0a841b89d614 | 142 | } |
AjK | 0:0a841b89d614 | 143 | |
AjK | 0:0a841b89d614 | 144 | md5str[32] = '\0'; |
AjK | 0:0a841b89d614 | 145 | } |
AjK | 0:0a841b89d614 | 146 | |
AjK | 0:0a841b89d614 | 147 | /* |
AjK | 0:0a841b89d614 | 148 | * This is an OpenSSL-compatible implementation of the RSA Data Security, |
AjK | 0:0a841b89d614 | 149 | * Inc. MD5 Message-Digest Algorithm (RFC 1321). |
AjK | 0:0a841b89d614 | 150 | * |
AjK | 0:0a841b89d614 | 151 | * Written by Solar Designer <solar at openwall.com> in 2001, and placed |
AjK | 0:0a841b89d614 | 152 | * in the public domain. There's absolutely no warranty. |
AjK | 0:0a841b89d614 | 153 | * |
AjK | 0:0a841b89d614 | 154 | * This differs from Colin Plumb's older public domain implementation in |
AjK | 0:0a841b89d614 | 155 | * that no 32-bit integer data type is required, there's no compile-time |
AjK | 0:0a841b89d614 | 156 | * endianness configuration, and the function prototypes match OpenSSL's. |
AjK | 0:0a841b89d614 | 157 | * The primary goals are portability and ease of use. |
AjK | 0:0a841b89d614 | 158 | * |
AjK | 0:0a841b89d614 | 159 | * This implementation is meant to be fast, but not as fast as possible. |
AjK | 0:0a841b89d614 | 160 | * Some known optimizations are not included to reduce source code size |
AjK | 0:0a841b89d614 | 161 | * and avoid compile-time configuration. |
AjK | 0:0a841b89d614 | 162 | */ |
AjK | 0:0a841b89d614 | 163 | |
AjK | 0:0a841b89d614 | 164 | |
AjK | 0:0a841b89d614 | 165 | /* |
AjK | 0:0a841b89d614 | 166 | * The basic MD5 functions. |
AjK | 0:0a841b89d614 | 167 | * |
AjK | 0:0a841b89d614 | 168 | * F and G are optimized compared to their RFC 1321 definitions for |
AjK | 0:0a841b89d614 | 169 | * architectures that lack an AND-NOT instruction, just like in Colin Plumb's |
AjK | 0:0a841b89d614 | 170 | * implementation. |
AjK | 0:0a841b89d614 | 171 | */ |
AjK | 0:0a841b89d614 | 172 | #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) |
AjK | 0:0a841b89d614 | 173 | #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) |
AjK | 0:0a841b89d614 | 174 | #define H(x, y, z) ((x) ^ (y) ^ (z)) |
AjK | 0:0a841b89d614 | 175 | #define I(x, y, z) ((y) ^ ((x) | ~(z))) |
AjK | 0:0a841b89d614 | 176 | |
AjK | 0:0a841b89d614 | 177 | /* |
AjK | 0:0a841b89d614 | 178 | * The MD5 transformation for all four rounds. |
AjK | 0:0a841b89d614 | 179 | */ |
AjK | 0:0a841b89d614 | 180 | #define STEP(f, a, b, c, d, x, t, s) \ |
AjK | 0:0a841b89d614 | 181 | (a) += f((b), (c), (d)) + (x) + (t); \ |
AjK | 0:0a841b89d614 | 182 | (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ |
AjK | 0:0a841b89d614 | 183 | (a) += (b); |
AjK | 0:0a841b89d614 | 184 | |
AjK | 0:0a841b89d614 | 185 | # define SET(n) \ |
AjK | 0:0a841b89d614 | 186 | (ctx->block[(n)] = \ |
AjK | 0:0a841b89d614 | 187 | (uint32_t)ptr[(n) * 4] | \ |
AjK | 0:0a841b89d614 | 188 | ((uint32_t)ptr[(n) * 4 + 1] << 8) | \ |
AjK | 0:0a841b89d614 | 189 | ((uint32_t)ptr[(n) * 4 + 2] << 16) | \ |
AjK | 0:0a841b89d614 | 190 | ((uint32_t)ptr[(n) * 4 + 3] << 24)) |
AjK | 0:0a841b89d614 | 191 | # define GET(n) \ |
AjK | 0:0a841b89d614 | 192 | (ctx->block[(n)]) |
AjK | 0:0a841b89d614 | 193 | |
AjK | 0:0a841b89d614 | 194 | /* |
AjK | 0:0a841b89d614 | 195 | * This processes one or more 64-byte data blocks, but does NOT update |
AjK | 0:0a841b89d614 | 196 | * the bit counters. There are no alignment requirements. |
AjK | 0:0a841b89d614 | 197 | */ |
AjK | 0:0a841b89d614 | 198 | static const void *body(MD5_CTX *ctx, const void *data, unsigned int size) { |
AjK | 0:0a841b89d614 | 199 | const unsigned char *ptr; |
AjK | 0:0a841b89d614 | 200 | uint32_t a, b, c, d; |
AjK | 0:0a841b89d614 | 201 | uint32_t saved_a, saved_b, saved_c, saved_d; |
AjK | 0:0a841b89d614 | 202 | |
AjK | 0:0a841b89d614 | 203 | ptr = (const unsigned char *)data; |
AjK | 0:0a841b89d614 | 204 | |
AjK | 0:0a841b89d614 | 205 | a = ctx->a; |
AjK | 0:0a841b89d614 | 206 | b = ctx->b; |
AjK | 0:0a841b89d614 | 207 | c = ctx->c; |
AjK | 0:0a841b89d614 | 208 | d = ctx->d; |
AjK | 0:0a841b89d614 | 209 | |
AjK | 0:0a841b89d614 | 210 | do { |
AjK | 0:0a841b89d614 | 211 | saved_a = a; |
AjK | 0:0a841b89d614 | 212 | saved_b = b; |
AjK | 0:0a841b89d614 | 213 | saved_c = c; |
AjK | 0:0a841b89d614 | 214 | saved_d = d; |
AjK | 0:0a841b89d614 | 215 | |
AjK | 0:0a841b89d614 | 216 | /* Round 1 */ |
AjK | 0:0a841b89d614 | 217 | STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) |
AjK | 0:0a841b89d614 | 218 | STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) |
AjK | 0:0a841b89d614 | 219 | STEP(F, c, d, a, b, SET(2), 0x242070db, 17) |
AjK | 0:0a841b89d614 | 220 | STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) |
AjK | 0:0a841b89d614 | 221 | STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) |
AjK | 0:0a841b89d614 | 222 | STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) |
AjK | 0:0a841b89d614 | 223 | STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) |
AjK | 0:0a841b89d614 | 224 | STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) |
AjK | 0:0a841b89d614 | 225 | STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) |
AjK | 0:0a841b89d614 | 226 | STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) |
AjK | 0:0a841b89d614 | 227 | STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) |
AjK | 0:0a841b89d614 | 228 | STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) |
AjK | 0:0a841b89d614 | 229 | STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) |
AjK | 0:0a841b89d614 | 230 | STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) |
AjK | 0:0a841b89d614 | 231 | STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) |
AjK | 0:0a841b89d614 | 232 | STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) |
AjK | 0:0a841b89d614 | 233 | |
AjK | 0:0a841b89d614 | 234 | /* Round 2 */ |
AjK | 0:0a841b89d614 | 235 | STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) |
AjK | 0:0a841b89d614 | 236 | STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) |
AjK | 0:0a841b89d614 | 237 | STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) |
AjK | 0:0a841b89d614 | 238 | STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) |
AjK | 0:0a841b89d614 | 239 | STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) |
AjK | 0:0a841b89d614 | 240 | STEP(G, d, a, b, c, GET(10), 0x02441453, 9) |
AjK | 0:0a841b89d614 | 241 | STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) |
AjK | 0:0a841b89d614 | 242 | STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) |
AjK | 0:0a841b89d614 | 243 | STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) |
AjK | 0:0a841b89d614 | 244 | STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) |
AjK | 0:0a841b89d614 | 245 | STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) |
AjK | 0:0a841b89d614 | 246 | STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) |
AjK | 0:0a841b89d614 | 247 | STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) |
AjK | 0:0a841b89d614 | 248 | STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) |
AjK | 0:0a841b89d614 | 249 | STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) |
AjK | 0:0a841b89d614 | 250 | STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) |
AjK | 0:0a841b89d614 | 251 | |
AjK | 0:0a841b89d614 | 252 | /* Round 3 */ |
AjK | 0:0a841b89d614 | 253 | STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) |
AjK | 0:0a841b89d614 | 254 | STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) |
AjK | 0:0a841b89d614 | 255 | STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) |
AjK | 0:0a841b89d614 | 256 | STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) |
AjK | 0:0a841b89d614 | 257 | STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) |
AjK | 0:0a841b89d614 | 258 | STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) |
AjK | 0:0a841b89d614 | 259 | STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) |
AjK | 0:0a841b89d614 | 260 | STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) |
AjK | 0:0a841b89d614 | 261 | STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) |
AjK | 0:0a841b89d614 | 262 | STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) |
AjK | 0:0a841b89d614 | 263 | STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) |
AjK | 0:0a841b89d614 | 264 | STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) |
AjK | 0:0a841b89d614 | 265 | STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) |
AjK | 0:0a841b89d614 | 266 | STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) |
AjK | 0:0a841b89d614 | 267 | STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) |
AjK | 0:0a841b89d614 | 268 | STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) |
AjK | 0:0a841b89d614 | 269 | |
AjK | 0:0a841b89d614 | 270 | /* Round 4 */ |
AjK | 0:0a841b89d614 | 271 | STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) |
AjK | 0:0a841b89d614 | 272 | STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) |
AjK | 0:0a841b89d614 | 273 | STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) |
AjK | 0:0a841b89d614 | 274 | STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) |
AjK | 0:0a841b89d614 | 275 | STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) |
AjK | 0:0a841b89d614 | 276 | STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) |
AjK | 0:0a841b89d614 | 277 | STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) |
AjK | 0:0a841b89d614 | 278 | STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) |
AjK | 0:0a841b89d614 | 279 | STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) |
AjK | 0:0a841b89d614 | 280 | STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) |
AjK | 0:0a841b89d614 | 281 | STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) |
AjK | 0:0a841b89d614 | 282 | STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) |
AjK | 0:0a841b89d614 | 283 | STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) |
AjK | 0:0a841b89d614 | 284 | STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) |
AjK | 0:0a841b89d614 | 285 | STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) |
AjK | 0:0a841b89d614 | 286 | STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) |
AjK | 0:0a841b89d614 | 287 | |
AjK | 0:0a841b89d614 | 288 | a += saved_a; |
AjK | 0:0a841b89d614 | 289 | b += saved_b; |
AjK | 0:0a841b89d614 | 290 | c += saved_c; |
AjK | 0:0a841b89d614 | 291 | d += saved_d; |
AjK | 0:0a841b89d614 | 292 | |
AjK | 0:0a841b89d614 | 293 | ptr += 64; |
AjK | 0:0a841b89d614 | 294 | } while (size -= 64); |
AjK | 0:0a841b89d614 | 295 | |
AjK | 0:0a841b89d614 | 296 | ctx->a = a; |
AjK | 0:0a841b89d614 | 297 | ctx->b = b; |
AjK | 0:0a841b89d614 | 298 | ctx->c = c; |
AjK | 0:0a841b89d614 | 299 | ctx->d = d; |
AjK | 0:0a841b89d614 | 300 | |
AjK | 0:0a841b89d614 | 301 | return ptr; |
AjK | 0:0a841b89d614 | 302 | } |
AjK | 0:0a841b89d614 | 303 | |
AjK | 0:0a841b89d614 | 304 | static void md5_init(MD5_CTX *ctx) { |
AjK | 0:0a841b89d614 | 305 | ctx->a = 0x67452301; |
AjK | 0:0a841b89d614 | 306 | ctx->b = 0xefcdab89; |
AjK | 0:0a841b89d614 | 307 | ctx->c = 0x98badcfe; |
AjK | 0:0a841b89d614 | 308 | ctx->d = 0x10325476; |
AjK | 0:0a841b89d614 | 309 | |
AjK | 0:0a841b89d614 | 310 | ctx->lo = 0; |
AjK | 0:0a841b89d614 | 311 | ctx->hi = 0; |
AjK | 0:0a841b89d614 | 312 | } |
AjK | 0:0a841b89d614 | 313 | |
AjK | 0:0a841b89d614 | 314 | static void md5_update(MD5_CTX *ctx, const void *data, unsigned int size) { |
AjK | 0:0a841b89d614 | 315 | uint32_t saved_lo; |
AjK | 0:0a841b89d614 | 316 | uint32_t used, free; |
AjK | 0:0a841b89d614 | 317 | |
AjK | 0:0a841b89d614 | 318 | saved_lo = ctx->lo; |
AjK | 0:0a841b89d614 | 319 | if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) { |
AjK | 0:0a841b89d614 | 320 | ctx->hi++; |
AjK | 0:0a841b89d614 | 321 | } |
AjK | 0:0a841b89d614 | 322 | ctx->hi += size >> 29; |
AjK | 0:0a841b89d614 | 323 | |
AjK | 0:0a841b89d614 | 324 | used = saved_lo & 0x3f; |
AjK | 0:0a841b89d614 | 325 | |
AjK | 0:0a841b89d614 | 326 | if (used) { |
AjK | 0:0a841b89d614 | 327 | free = 64 - used; |
AjK | 0:0a841b89d614 | 328 | |
AjK | 0:0a841b89d614 | 329 | if (size < free) { |
AjK | 0:0a841b89d614 | 330 | memcpy(&ctx->buffer[used], data, size); |
AjK | 0:0a841b89d614 | 331 | return; |
AjK | 0:0a841b89d614 | 332 | } |
AjK | 0:0a841b89d614 | 333 | |
AjK | 0:0a841b89d614 | 334 | memcpy(&ctx->buffer[used], data, free); |
AjK | 0:0a841b89d614 | 335 | data = (unsigned char *)data + free; |
AjK | 0:0a841b89d614 | 336 | size -= free; |
AjK | 0:0a841b89d614 | 337 | body(ctx, ctx->buffer, 64); |
AjK | 0:0a841b89d614 | 338 | } |
AjK | 0:0a841b89d614 | 339 | |
AjK | 0:0a841b89d614 | 340 | if (size >= 64) { |
AjK | 0:0a841b89d614 | 341 | data = body(ctx, data, size & ~(size_t)0x3f); |
AjK | 0:0a841b89d614 | 342 | size &= 0x3f; |
AjK | 0:0a841b89d614 | 343 | } |
AjK | 0:0a841b89d614 | 344 | |
AjK | 0:0a841b89d614 | 345 | memcpy(ctx->buffer, data, size); |
AjK | 0:0a841b89d614 | 346 | } |
AjK | 0:0a841b89d614 | 347 | |
AjK | 0:0a841b89d614 | 348 | static void md5_final(unsigned char *result, MD5_CTX *ctx) { |
AjK | 0:0a841b89d614 | 349 | uint32_t used, free; |
AjK | 0:0a841b89d614 | 350 | |
AjK | 0:0a841b89d614 | 351 | used = ctx->lo & 0x3f; |
AjK | 0:0a841b89d614 | 352 | |
AjK | 0:0a841b89d614 | 353 | ctx->buffer[used++] = 0x80; |
AjK | 0:0a841b89d614 | 354 | |
AjK | 0:0a841b89d614 | 355 | free = 64 - used; |
AjK | 0:0a841b89d614 | 356 | |
AjK | 0:0a841b89d614 | 357 | if (free < 8) { |
AjK | 0:0a841b89d614 | 358 | memset(&ctx->buffer[used], 0, free); |
AjK | 0:0a841b89d614 | 359 | body(ctx, ctx->buffer, 64); |
AjK | 0:0a841b89d614 | 360 | used = 0; |
AjK | 0:0a841b89d614 | 361 | free = 64; |
AjK | 0:0a841b89d614 | 362 | } |
AjK | 0:0a841b89d614 | 363 | |
AjK | 0:0a841b89d614 | 364 | memset(&ctx->buffer[used], 0, free - 8); |
AjK | 0:0a841b89d614 | 365 | |
AjK | 0:0a841b89d614 | 366 | ctx->lo <<= 3; |
AjK | 0:0a841b89d614 | 367 | ctx->buffer[56] = (unsigned char)ctx->lo; |
AjK | 0:0a841b89d614 | 368 | ctx->buffer[57] = (unsigned char)(ctx->lo >> 8); |
AjK | 0:0a841b89d614 | 369 | ctx->buffer[58] = (unsigned char)(ctx->lo >> 16); |
AjK | 0:0a841b89d614 | 370 | ctx->buffer[59] = (unsigned char)(ctx->lo >> 24); |
AjK | 0:0a841b89d614 | 371 | ctx->buffer[60] = (unsigned char)(ctx->hi); |
AjK | 0:0a841b89d614 | 372 | ctx->buffer[61] = (unsigned char)(ctx->hi >> 8); |
AjK | 0:0a841b89d614 | 373 | ctx->buffer[62] = (unsigned char)(ctx->hi >> 16); |
AjK | 0:0a841b89d614 | 374 | ctx->buffer[63] = (unsigned char)(ctx->hi >> 24); |
AjK | 0:0a841b89d614 | 375 | |
AjK | 0:0a841b89d614 | 376 | body(ctx, ctx->buffer, 64); |
AjK | 0:0a841b89d614 | 377 | |
AjK | 0:0a841b89d614 | 378 | result[0] = (unsigned char)ctx->a; |
AjK | 0:0a841b89d614 | 379 | result[1] = (unsigned char)(ctx->a >> 8); |
AjK | 0:0a841b89d614 | 380 | result[2] = (unsigned char)(ctx->a >> 16); |
AjK | 0:0a841b89d614 | 381 | result[3] = (unsigned char)(ctx->a >> 24); |
AjK | 0:0a841b89d614 | 382 | result[4] = (unsigned char)ctx->b; |
AjK | 0:0a841b89d614 | 383 | result[5] = (unsigned char)(ctx->b >> 8); |
AjK | 0:0a841b89d614 | 384 | result[6] = (unsigned char)(ctx->b >> 16); |
AjK | 0:0a841b89d614 | 385 | result[7] = (unsigned char)(ctx->b >> 24); |
AjK | 0:0a841b89d614 | 386 | result[8] = (unsigned char)ctx->c; |
AjK | 0:0a841b89d614 | 387 | result[9] = (unsigned char)(ctx->c >> 8); |
AjK | 0:0a841b89d614 | 388 | result[10] = (unsigned char)(ctx->c >> 16); |
AjK | 0:0a841b89d614 | 389 | result[11] = (unsigned char)(ctx->c >> 24); |
AjK | 0:0a841b89d614 | 390 | result[12] = (unsigned char)ctx->d; |
AjK | 0:0a841b89d614 | 391 | result[13] = (unsigned char)(ctx->d >> 8); |
AjK | 0:0a841b89d614 | 392 | result[14] = (unsigned char)(ctx->d >> 16); |
AjK | 0:0a841b89d614 | 393 | result[15] = (unsigned char)(ctx->d >> 24); |
AjK | 0:0a841b89d614 | 394 | |
AjK | 0:0a841b89d614 | 395 | memset(ctx, 0, sizeof(*ctx)); |
AjK | 0:0a841b89d614 | 396 | } |