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/crypto.h> 63#include <openssl/des.h> 64#include <openssl/mdc2.h> 65 66#undef c2l 67#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ 68 l|=((DES_LONG)(*((c)++)))<< 8L, \ 69 l|=((DES_LONG)(*((c)++)))<<16L, \ 70 l|=((DES_LONG)(*((c)++)))<<24L) 71 72#undef l2c 73#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 74 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 75 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 76 *((c)++)=(unsigned char)(((l)>>24L)&0xff)) 77 78static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); 79fips_md_init(MDC2) 80{ 81 c->num = 0; 82 c->pad_type = 1; 83 memset(&(c->h[0]), 0x52, MDC2_BLOCK); 84 memset(&(c->hh[0]), 0x25, MDC2_BLOCK); 85 return 1; 86} 87 88int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len) 89{ 90 size_t i, j; 91 92 i = c->num; 93 if (i != 0) { 94 if (len < MDC2_BLOCK - i) { 95 /* partial block */ 96 memcpy(&(c->data[i]), in, len); 97 c->num += (int)len; 98 return 1; 99 } else { 100 /* filled one */ 101 j = MDC2_BLOCK - i; 102 memcpy(&(c->data[i]), in, j); 103 len -= j; 104 in += j; 105 c->num = 0; 106 mdc2_body(c, &(c->data[0]), MDC2_BLOCK); 107 } 108 } 109 i = len & ~((size_t)MDC2_BLOCK - 1); 110 if (i > 0) 111 mdc2_body(c, in, i); 112 j = len - i; 113 if (j > 0) { 114 memcpy(&(c->data[0]), &(in[i]), j); 115 c->num = (int)j; 116 } 117 return 1; 118} 119 120static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len) 121{ 122 register DES_LONG tin0, tin1; 123 register DES_LONG ttin0, ttin1; 124 DES_LONG d[2], dd[2]; 125 DES_key_schedule k; 126 unsigned char *p; 127 size_t i; 128 129 for (i = 0; i < len; i += 8) { 130 c2l(in, tin0); 131 d[0] = dd[0] = tin0; 132 c2l(in, tin1); 133 d[1] = dd[1] = tin1; 134 c->h[0] = (c->h[0] & 0x9f) | 0x40; 135 c->hh[0] = (c->hh[0] & 0x9f) | 0x20; 136 137 DES_set_odd_parity(&c->h); 138 DES_set_key_unchecked(&c->h, &k); 139 DES_encrypt1(d, &k, 1); 140 141 DES_set_odd_parity(&c->hh); 142 DES_set_key_unchecked(&c->hh, &k); 143 DES_encrypt1(dd, &k, 1); 144 145 ttin0 = tin0 ^ dd[0]; 146 ttin1 = tin1 ^ dd[1]; 147 tin0 ^= d[0]; 148 tin1 ^= d[1]; 149 150 p = c->h; 151 l2c(tin0, p); 152 l2c(ttin1, p); 153 p = c->hh; 154 l2c(ttin0, p); 155 l2c(tin1, p); 156 } 157} 158 159int MDC2_Final(unsigned char *md, MDC2_CTX *c) 160{ 161 unsigned int i; 162 int j; 163 164 i = c->num; 165 j = c->pad_type; 166 if ((i > 0) || (j == 2)) { 167 if (j == 2) 168 c->data[i++] = 0x80; 169 memset(&(c->data[i]), 0, MDC2_BLOCK - i); 170 mdc2_body(c, c->data, MDC2_BLOCK); 171 } 172 memcpy(md, (char *)c->h, MDC2_BLOCK); 173 memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK); 174 return 1; 175} 176 177#undef TEST 178 179#ifdef TEST 180main() 181{ 182 unsigned char md[MDC2_DIGEST_LENGTH]; 183 int i; 184 MDC2_CTX c; 185 static char *text = "Now is the time for all "; 186 187 MDC2_Init(&c); 188 MDC2_Update(&c, text, strlen(text)); 189 MDC2_Final(&(md[0]), &c); 190 191 for (i = 0; i < MDC2_DIGEST_LENGTH; i++) 192 printf("%02X", md[i]); 193 printf("\n"); 194} 195 196#endif 197