mdc2dgst.c revision 306230
1/* crypto/mdc2/mdc2dgst.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include <stdio.h> 60#include <stdlib.h> 61#include <string.h> 62#include <openssl/des.h> 63#include <openssl/mdc2.h> 64#include <openssl/err.h> 65#ifdef OPENSSL_FIPS 66# include <openssl/fips.h> 67#endif 68 69#undef c2l 70#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ 71 l|=((DES_LONG)(*((c)++)))<< 8L, \ 72 l|=((DES_LONG)(*((c)++)))<<16L, \ 73 l|=((DES_LONG)(*((c)++)))<<24L) 74 75#undef l2c 76#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 77 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 78 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 79 *((c)++)=(unsigned char)(((l)>>24L)&0xff)) 80 81static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); 82FIPS_NON_FIPS_MD_Init(MDC2) 83{ 84 c->num = 0; 85 c->pad_type = 1; 86 memset(&(c->h[0]), 0x52, MDC2_BLOCK); 87 memset(&(c->hh[0]), 0x25, MDC2_BLOCK); 88 return 1; 89} 90 91int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len) 92{ 93 size_t i, j; 94 95 i = c->num; 96 if (i != 0) { 97 if (len < MDC2_BLOCK - i) { 98 /* partial block */ 99 memcpy(&(c->data[i]), in, len); 100 c->num += (int)len; 101 return 1; 102 } else { 103 /* filled one */ 104 j = MDC2_BLOCK - i; 105 memcpy(&(c->data[i]), in, j); 106 len -= j; 107 in += j; 108 c->num = 0; 109 mdc2_body(c, &(c->data[0]), MDC2_BLOCK); 110 } 111 } 112 i = len & ~((size_t)MDC2_BLOCK - 1); 113 if (i > 0) 114 mdc2_body(c, in, i); 115 j = len - i; 116 if (j > 0) { 117 memcpy(&(c->data[0]), &(in[i]), j); 118 c->num = (int)j; 119 } 120 return 1; 121} 122 123static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len) 124{ 125 register DES_LONG tin0, tin1; 126 register DES_LONG ttin0, ttin1; 127 DES_LONG d[2], dd[2]; 128 DES_key_schedule k; 129 unsigned char *p; 130 size_t i; 131 132 for (i = 0; i < len; i += 8) { 133 c2l(in, tin0); 134 d[0] = dd[0] = tin0; 135 c2l(in, tin1); 136 d[1] = dd[1] = tin1; 137 c->h[0] = (c->h[0] & 0x9f) | 0x40; 138 c->hh[0] = (c->hh[0] & 0x9f) | 0x20; 139 140 DES_set_odd_parity(&c->h); 141 DES_set_key_unchecked(&c->h, &k); 142 DES_encrypt1(d, &k, 1); 143 144 DES_set_odd_parity(&c->hh); 145 DES_set_key_unchecked(&c->hh, &k); 146 DES_encrypt1(dd, &k, 1); 147 148 ttin0 = tin0 ^ dd[0]; 149 ttin1 = tin1 ^ dd[1]; 150 tin0 ^= d[0]; 151 tin1 ^= d[1]; 152 153 p = c->h; 154 l2c(tin0, p); 155 l2c(ttin1, p); 156 p = c->hh; 157 l2c(ttin0, p); 158 l2c(tin1, p); 159 } 160} 161 162int MDC2_Final(unsigned char *md, MDC2_CTX *c) 163{ 164 unsigned int i; 165 int j; 166 167 i = c->num; 168 j = c->pad_type; 169 if ((i > 0) || (j == 2)) { 170 if (j == 2) 171 c->data[i++] = 0x80; 172 memset(&(c->data[i]), 0, MDC2_BLOCK - i); 173 mdc2_body(c, c->data, MDC2_BLOCK); 174 } 175 memcpy(md, (char *)c->h, MDC2_BLOCK); 176 memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK); 177 return 1; 178} 179 180#undef TEST 181 182#ifdef TEST 183main() 184{ 185 unsigned char md[MDC2_DIGEST_LENGTH]; 186 int i; 187 MDC2_CTX c; 188 static char *text = "Now is the time for all "; 189 190 MDC2_Init(&c); 191 MDC2_Update(&c, text, strlen(text)); 192 MDC2_Final(&(md[0]), &c); 193 194 for (i = 0; i < MDC2_DIGEST_LENGTH; i++) 195 printf("%02X", md[i]); 196 printf("\n"); 197} 198 199#endif 200