1 /*      mdfile.c  - Message Digest routines for PGP.
2    PGP: Pretty Good(tm) Privacy - public key cryptography for the masses.
3 
4    (c) Copyright 1990-1996 by Philip Zimmermann.  All rights reserved.
5    The author assumes no liability for damages resulting from the use
6    of this software, even if the damage results from defects in this
7    software.  No warranty is expressed or implied.
8 
9    Note that while most PGP source modules bear Philip Zimmermann's
10    copyright notice, many of them have been revised or entirely written
11    by contributors who frequently failed to put their names in their
12    code.  Code that has been incorporated into PGP from other authors
13    was either originally published in the public domain or is used with
14    permission from the various authors.
15 
16    PGP is available for free to the public under certain restrictions.
17    See the PGP User's Guide (included in the release package) for
18    important information about licensing, patent restrictions on
19    certain algorithms, trademarks, copyrights, and export controls.
20  */
21 
22 #include <stdio.h>
23 #include "mpilib.h"
24 #include "mdfile.h"
25 #include "fileio.h"
26 #include "language.h"
27 #include "pgp.h"
28 #ifdef MACTC5
29 #include "Macutil3.h"
30 #endif
31 
32 /* Begin MD5 routines */
33 
34 /* Note - the routines in this module, except for MD_addbuffer,
35  * do not "finish" the MD5 calculation.  MD_addbuffer finishes the
36  * calculation in each case, usually to append the timestamp and class info.
37  */
38 
39 /* Computes the message digest for a file from current position for
40    longcount bytes.
41    Uses the RSA Data Security Inc. MD5 Message Digest Algorithm */
MDfile0_len(struct MD5Context * mdContext,FILE * f,word32 longcount)42 int MDfile0_len(struct MD5Context *mdContext, FILE * f, word32 longcount)
43 {
44     int bytecount;
45     unsigned char buffer[1024];
46 
47     MD5Init(mdContext);
48     /* Process 1024 bytes at a time... */
49     do {
50 	if (longcount < (word32) 1024)
51 	    bytecount = (int) longcount;
52 	else
53 	    bytecount = 1024;
54 	bytecount = fread(buffer, 1, bytecount, f);
55 	if (bytecount > 0) {
56 	    MD5Update(mdContext, buffer, bytecount);
57 	    longcount -= bytecount;
58 #ifdef MACTC5
59 		mac_poll_for_break();
60 #endif
61 	}
62 	/* if text block was short, exit loop */
63     } while (bytecount == 1024);
64     return 0;
65 }				/* MDfile0_len */
66 
67 
68 /* Computes the message digest for a file from current position to EOF.
69    Uses the RSA Data Security Inc. MD5 Message Digest Algorithm */
70 
MDfile0(struct MD5Context * mdContext,FILE * inFile)71 static int MDfile0(struct MD5Context *mdContext, FILE * inFile)
72 {
73     int bytes;
74     unsigned char buffer[1024];
75 
76     MD5Init(mdContext);
77     while ((bytes = fread(buffer, 1, 1024, inFile)) != 0)
78 #ifdef MACTC5
79 		{
80 		mac_poll_for_break();
81 		MD5Update(mdContext,buffer,bytes);
82 		}
83 #else
84 	MD5Update(mdContext, buffer, bytes);
85 #endif
86     return 0;
87 }
88 
89 /* Computes the message digest for a specified file */
90 
MDfile(struct MD5Context * mdContext,char * filename)91 int MDfile(struct MD5Context *mdContext, char *filename)
92 {
93     FILE *inFile;
94     inFile = fopen(filename, FOPRBIN);
95 
96     if (inFile == NULL) {
97 	fprintf(pgpout, LANG("\n\007Can't open file '%s'\n"), filename);
98 	return -1;
99     }
100     MDfile0(mdContext, inFile);
101     fclose(inFile);
102     return 0;
103 }
104 
105 /* Add a buffer's worth of data to the MD5 computation.  If a digest
106  * pointer is supplied, complete the computation and write the digest.
107  */
MD_addbuffer(struct MD5Context * mdContext,byte * buf,int buflen,byte digest[16])108 void MD_addbuffer(struct MD5Context *mdContext, byte * buf, int buflen,
109 		  byte digest[16])
110 {
111     MD5Update(mdContext, buf, buflen);
112     if (digest) {
113 	MD5Final(digest, mdContext);
114 	burn(*mdContext);	/* Paranoia */
115     }
116 }
117 
118 /* End MD5 routines */
119