1/* 2 * md5.c -- 3 * 4 * Implements and registers message digest generator MD5. 5 * 6 * 7 * Copyright (c) 1996 Andreas Kupries (a.kupries@westend.com) 8 * All rights reserved. 9 * 10 * Permission is hereby granted, without written agreement and without 11 * license or royalty fees, to use, copy, modify, and distribute this 12 * software and its documentation for any purpose, provided that the 13 * above copyright notice and the following two paragraphs appear in 14 * all copies of this software. 15 * 16 * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 17 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS 18 * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE 19 * POSSIBILITY OF SUCH DAMAGE. 20 * 21 * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 24 * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 25 * ENHANCEMENTS, OR MODIFICATIONS. 26 * 27 * CVS: $Id: md5dig.c,v 1.5 2008/12/11 19:04:25 andreas_kupries Exp $ 28 */ 29 30#include "loadman.h" 31 32/* 33 * Generator description 34 * --------------------- 35 * 36 * The MD5 alogrithm is used to compute a cryptographically strong 37 * message digest. 38 */ 39 40#define MD5_CTXP (MD5_CTX*) 41 42#ifndef OTP 43#define DIGEST_SIZE (16) 44#else 45#define DIGEST_SIZE (8) 46#endif 47#define CTX_TYPE MD5_CTX 48 49/* 50 * Declarations of internal procedures. 51 */ 52 53static void MDmd5_Start _ANSI_ARGS_ ((VOID* context)); 54static void MDmd5_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); 55static void MDmd5_UpdateBuf _ANSI_ARGS_ ((VOID* context, 56 unsigned char* buffer, int bufLen)); 57static void MDmd5_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); 58static int MDmd5_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); 59 60/* 61 * Generator definition. 62 */ 63 64static Trf_MessageDigestDescription 65mdDescription = { /* THREADING: constant, read-only => safe */ 66#ifndef OTP 67 "md5", 68#else 69 "otp_md5", 70#endif 71 sizeof (CTX_TYPE), 72 DIGEST_SIZE, 73 MDmd5_Start, 74 MDmd5_Update, 75 MDmd5_UpdateBuf, 76 MDmd5_Final, 77 MDmd5_Check 78}; 79 80/* 81 *------------------------------------------------------* 82 * 83 * TrfInit_MD5 -- 84 * 85 * ------------------------------------------------* 86 * Register the generator implemented in this file. 87 * ------------------------------------------------* 88 * 89 * Sideeffects: 90 * As of 'Trf_Register'. 91 * 92 * Result: 93 * A standard Tcl error code. 94 * 95 *------------------------------------------------------* 96 */ 97 98int 99#ifndef OTP 100TrfInit_MD5 (interp) 101#else 102TrfInit_OTP_MD5 (interp) 103#endif 104Tcl_Interp* interp; 105{ 106 return Trf_RegisterMessageDigest (interp, &mdDescription); 107} 108 109/* 110 *------------------------------------------------------* 111 * 112 * MDmd5_Start -- 113 * 114 * ------------------------------------------------* 115 * Initialize the internal state of the message 116 * digest generator. 117 * ------------------------------------------------* 118 * 119 * Sideeffects: 120 * As of the called procedure. 121 * 122 * Result: 123 * None. 124 * 125 *------------------------------------------------------* 126 */ 127 128static void 129MDmd5_Start (context) 130VOID* context; 131{ 132 /* MD5Init ((MD5_CTX*) context);*/ 133 md5f.init (MD5_CTXP context); 134 135#ifdef TRF_DEBUG 136 { 137 MD5_CTX* c = MD5_CTXP context; 138 PRINT ("Init ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; 139 } 140#endif 141} 142 143/* 144 *------------------------------------------------------* 145 * 146 * MDmd5_Update -- 147 * 148 * ------------------------------------------------* 149 * Update the internal state of the message digest 150 * generator for a single character. 151 * ------------------------------------------------* 152 * 153 * Sideeffects: 154 * As of the called procedure. 155 * 156 * Result: 157 * None. 158 * 159 *------------------------------------------------------* 160 */ 161 162static void 163MDmd5_Update (context, character) 164VOID* context; 165unsigned int character; 166{ 167 unsigned char buf = character; 168 169 /* MD5Update ((MD5_CTX*) context, &buf, 1); */ 170 171 md5f.update (MD5_CTXP context, &buf, 1); 172} 173 174/* 175 *------------------------------------------------------* 176 * 177 * MDmd5_UpdateBuf -- 178 * 179 * ------------------------------------------------* 180 * Update the internal state of the message digest 181 * generator for a character buffer. 182 * ------------------------------------------------* 183 * 184 * Sideeffects: 185 * As of the called procedure. 186 * 187 * Result: 188 * None. 189 * 190 *------------------------------------------------------* 191 */ 192 193static void 194MDmd5_UpdateBuf (context, buffer, bufLen) 195VOID* context; 196unsigned char* buffer; 197int bufLen; 198{ 199 /* MD5Update ((MD5_CTX*) context, (unsigned char*) buffer, bufLen);*/ 200 201 PRTSTR ("update by %d (%s)\n", bufLen, buffer); 202#ifdef TRF_DEBUG 203 { 204 MD5_CTX* c = MD5_CTXP context; 205 PRINT ("Upd1 ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; 206 } 207#endif 208 209 md5f.update (MD5_CTXP context, (unsigned char*) buffer, bufLen); 210 211#ifdef TRF_DEBUG 212 { 213 MD5_CTX* c = MD5_CTXP context; 214 PRINT ("Upd2 ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; 215 } 216#endif 217} 218 219/* 220 *------------------------------------------------------* 221 * 222 * MDmd5_Final -- 223 * 224 * ------------------------------------------------* 225 * Generate the digest from the internal state of 226 * the message digest generator. 227 * ------------------------------------------------* 228 * 229 * Sideeffects: 230 * As of the called procedure. 231 * 232 * Result: 233 * None. 234 * 235 *------------------------------------------------------* 236 */ 237 238static void 239MDmd5_Final (context, digest) 240VOID* context; 241VOID* digest; 242{ 243#ifndef OTP 244 /* MD5Final ((unsigned char*) digest, (MD5_CTX*) context); */ 245 md5f.final ((unsigned char*) digest, MD5_CTXP context); 246#else 247 int i; 248 unsigned char result[16]; 249 250 /* MD5Final ((unsigned char*) result, (MD5_CTX*) context);*/ 251 md5f.final ((unsigned char*) result, MD5_CTXP context); 252 253 for (i = 0; i < 8; i++) 254 result[i] ^= result[i + 8]; 255 256 memcpy ((VOID *) digest, (VOID *) result, DIGEST_SIZE); 257#endif 258 259#ifdef TRF_DEBUG 260 { 261 MD5_CTX* c = MD5_CTXP context; 262 PRINT ("Flsh ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; 263 } 264#endif 265} 266 267/* 268 *------------------------------------------------------* 269 * 270 * MDmd5_Check -- 271 * 272 * ------------------------------------------------* 273 * Do global one-time initializations of the message 274 * digest generator. 275 * ------------------------------------------------* 276 * 277 * Sideeffects: 278 * Loads the shared library containing the 279 * SHA1 functionality 280 * 281 * Result: 282 * A standard Tcl error code. 283 * 284 *------------------------------------------------------* 285 */ 286 287static int 288MDmd5_Check (interp) 289Tcl_Interp* interp; 290{ 291 return TrfLoadMD5 (interp); 292#ifdef MD5_STATIC_BUILD 293 /*return TCL_OK;*/ 294#else 295#endif 296} 297 298#if 0 299/* Import the MD5 code in case of static linkage. 300 */ 301#ifdef MD5_STATIC_BUILD 302/* 303 * External code from here on. 304 */ 305 306#ifndef OTP 307#include "../md5-crypt/md5.c" /* THREADING: import of one constant var, read-only => safe */ 308#endif 309 310md5Functions md5f = { 311 0, 312 md5_init_ctx, 313 md5_process_bytes, 314 md5_finish_ctx, 315 0, /* no crypt code! */ 316}; 317 318#endif 319#endif 320