diff -c pgp_262/crypto.c pgp_sha1/crypto.c *** pgp_262/crypto.c Fri Jun 21 23:31:01 1996 --- pgp_sha1/crypto.c Sat Jun 22 00:02:32 1996 *************** *** 63,69 **** --- 63,75 ---- /* This variable stores the md5 hash of the current file, if it is available. It is used in make_random_ideakey. */ + #ifdef SHA1 + #include "sha1.h" + static boolean local_sha1_flag = FALSE; + static unsigned char md5buf[20]; + #else static unsigned char md5buf[16]; + #endif /* This flag is set if the buffer above has been filled. */ static char already_have_md5 = 0; *************** *** 697,702 **** --- 703,715 ---- complete message digest packet in a single RSA block. */ blocksize = countbytes(n)-1; /* size of a plaintext block */ + #ifdef SHA1 + if ((blocksize < 32) && local_sha1_flag) { + fprintf(pgpout, + "\n\007Error: RSA key length must be at least 264 bits.\n"); + return -1; + } else + #endif if (blocksize < 31) { fprintf(pgpout, "\n\007Error: RSA key length must be at least 256 bits.\n"); *************** *** 714,721 **** --- 727,744 ---- convert_byteorder(timestamp,4); /* convert to external form */ /* Finish off message digest calculation with this information */ + #ifdef SHA1 + if (local_sha1_flag) { + SHA1_addbuffer ((struct SHA1Context *)MD, &class, 1, 0); + SHA1_addbuffer ((struct SHA1Context *)MD, timestamp, 4, md5buf); + } else { + MD_addbuffer (MD, &class, 1, 0); + MD_addbuffer (MD, timestamp, 4, md5buf); + } + #else MD_addbuffer (MD, &class, 1, 0); MD_addbuffer (MD, timestamp, 4, md5buf); + #endif /* We wrote the digest to a static variable because we want to keep it around for random number generation later. Also make a note of that fact. */ already_have_md5 = 1; *************** *** 727,734 **** --- 750,766 ---- } /* do RSA signature calculation: */ + #ifdef SHA1 + if (local_sha1_flag) + i = rsa_private_encrypt((unitptr)outbuf, md5buf, 20, + e, d, p, q, u, n); + else + i = rsa_private_encrypt((unitptr)outbuf, md5buf, 16, + e, d, p, q, u, n); + #else i = rsa_private_encrypt((unitptr)outbuf, md5buf, sizeof(md5buf), e, d, p, q, u, n); + #endif if (i < 0) { if (i == -4) { fprintf(pgpout, *************** *** 786,791 **** --- 818,828 ---- certificate[certificate_length++] = keyID[i]; certificate[certificate_length++] = RSA_ALGORITHM_BYTE; + #ifdef SHA1 + if (local_sha1_flag) + certificate[certificate_length++] = SHA1_ALGORITHM_BYTE; + else + #endif certificate[certificate_length++] = MD5_ALGORITHM_BYTE; /* Now append first two bytes of message digest */ *************** *** 855,860 **** --- 892,900 ---- char keyfile[MAX_PATH]; int status; struct MD5Context MD; + #ifdef SHA1 + struct SHA1Context SH; + #endif byte keyID[KEYFRAGSIZE]; unit n[MAX_UNIT_PRECISION], e[MAX_UNIT_PRECISION]; unit d[MAX_UNIT_PRECISION]; *************** *** 869,874 **** --- 909,923 ---- "signfile: infile = '%s', outfile = '%s', mode = '%c', literalfile = '%s'\n", infile,outfile,lit_mode,literalfile); + #ifdef SHA1 + local_sha1_flag = FALSE; + if (mdalg_flag == SHA1_ALGORITHM_BYTE) + { + if (SHA1file(&SH, infile) < 0) + return -1; /* problem with input file. error return */ + } + else + #endif if (MDfile(&MD, infile) < 0) return -1; /* problem with input file. error return */ *************** *** 893,901 **** --- 942,963 ---- if (lit_mode==MODE_TEXT) signature_class = SM_SIGNATURE_BYTE; else signature_class = SB_SIGNATURE_BYTE; + #ifdef SHA1 + if (mdalg_flag == SHA1_ALGORITHM_BYTE) + { + local_sha1_flag = TRUE; + certificate_length = make_signature_certificate(certificate, + (struct MD5Context *)&SH, + signature_class, e, d, p, q, u, n); + } + else + #endif certificate_length = make_signature_certificate(certificate, &MD, signature_class, e, d, p, q, u, n); + #ifdef SHA1 + local_sha1_flag = FALSE; + #endif if (certificate_length < 0) return -1; /* error return from make_signature_certificate() */ *************** *** 1051,1056 **** --- 1113,1121 ---- } set_precision(prec); + #ifdef SHA1 + local_sha1_flag = FALSE; + #endif certificate_length = make_signature_certificate(certificate, &MD, KC_SIGNATURE_BYTE, e, d, p, q, u, n); if (certificate_length < 0) { *************** *** 1242,1247 **** --- 1307,1315 ---- error return. */ } + #ifdef SHA1 + local_sha1_flag = FALSE; + #endif certificate_length = make_signature_certificate(certificate, &MD, K0_SIGNATURE_BYTE, e, d, p, q, *************** *** 1322,1328 **** --- 1390,1401 ---- word32 dummystamp; byte userid[256]; struct MD5Context MD; + #ifdef SHA1 + struct SHA1Context SH; + byte digest[20]; + #else byte digest[16]; + #endif boolean separate_signature; boolean fixedLiteral = FALSE; /* Whether it's a fixed literal2 packet */ *************** *** 1345,1350 **** --- 1418,1426 ---- short fdl_len; #endif int outbufoffset; + #ifdef SHA1 + local_sha1_flag = FALSE; + #endif fill0( keyID, KEYFRAGSIZE ); *************** *** 1422,1427 **** --- 1498,1508 ---- goto err1; algorithm = *certificate++; + #ifdef SHA1 + if (algorithm == SHA1_ALGORITHM_BYTE) + local_sha1_flag = TRUE; + else + #endif if (version_error(algorithm, MD5_ALGORITHM_BYTE)) goto err1; *************** *** 1610,1616 **** --- 1691,1702 ---- /*==================================================================*/ /* Look at nested stuff within RSA block... */ + #ifdef SHA1 + if (count == -7 || (count > 0 && local_sha1_flag && count != 20) + || (count > 0 && !local_sha1_flag && count != 16)) + #else if (count == -7 || (count > 0 && count != sizeof(digest))) + #endif { fputs(LANG("\007\nUnrecognized message digest algorithm.\n\ This may require a newer version of PGP.\n\ *************** *** 1640,1646 **** --- 1726,1738 ---- } /* Distinguish PKCS-compatible from pre-3.3 which has an extra byte */ + #ifdef SHA1 + outbufoffset = (count==16) ? 0 : 1; + if (local_sha1_flag) + outbufoffset = 0; + #else outbufoffset = (count==sizeof(digest)) ? 0 : 1; + #endif if (outbuf[outbufoffset] != mdlow2[0] || outbuf[outbufoffset+1] != mdlow2[1]) *************** *** 1655,1663 **** --- 1747,1765 ---- /* Reposition file to where that plaintext begins... */ fseek(f,start_text,SEEK_SET); /* reposition file from last ftell */ + #ifdef SHA1 + if (local_sha1_flag) + SHA1file0_len(&SH,f,text_len); + else + #endif MDfile0_len(&MD,f,text_len); /* compute a message digest from rest of file */ + #ifdef SHA1 + if (local_sha1_flag) + SHA1_addbuffer (&SH, mdextras, mdlensave, digest); + else + #endif MD_addbuffer (&MD, mdextras, mdlensave, digest); /* Finish message digest */ *************** *** 1667,1673 **** --- 1769,1779 ---- /* now compare computed MD with claimed MD */ /* Assume MSB external byte ordering */ + #ifdef SHA1 + if (!equal_buffers(digest, outbuf+outbufoffset, local_sha1_flag ? 20 : 16)) { + #else if (!equal_buffers(digest, outbuf+outbufoffset, 16)) { + #endif /* IF the signature is bad, AND this machine does not use MSDOS-stype canonical text as its native text format, AND this is a detached signature certificate, AND this file *************** *** 1692,1698 **** --- 1798,1815 ---- != NULL ) { /* Now check the signature */ + #ifdef SHA1 + if (local_sha1_flag) + SHA1file0_len(&SH, tempFile, -1L ); + else + #endif MDfile0_len(&MD, tempFile, -1L ); + #ifdef SHA1 + if (local_sha1_flag) + SHA1_addbuffer(&SH, mdextras, mdlensave, + digest); + else + #endif MD_addbuffer(&MD, mdextras, mdlensave, digest); *************** *** 1703,1714 **** --- 1820,1839 ---- /* Check if the signature is OK this time round */ /* Assume MSB external byte ordering */ + #ifdef SHA1 if(equal_buffers(digest, outbuf+outbufoffset, + local_sha1_flag ? 20 : 16)) + #else + if(equal_buffers(digest, outbuf+outbufoffset, 16)) + #endif goto goodsig; } } + #ifdef SHA1 + local_sha1_flag = FALSE; + #endif fprintf(pgpout, LANG("\007\nWARNING: Bad signature, doesn't match file contents!\007\n")); fprintf(pgpout,LANG("\nBad signature from user \"%s\".\n"), *************** *** 1730,1735 **** --- 1855,1866 ---- LOCAL_CHARSET((char *)userid)); fprintf(pgpout, LANG("Signature made %s\n"),ctdate((word32 *)timestamp)); + #ifdef SHA1 + if (local_sha1_flag) + fprintf(pgpout, + LANG("Signature made using the SHA1 message digest algorithm.\n")); + local_sha1_flag = FALSE; + #endif warnsig: /* warn only, don't ask if user wants to use the key */ diff -c pgp_262/pgp.c pgp_sha1/pgp.c *** pgp_262/pgp.c Fri Jun 21 23:31:16 1996 --- pgp_sha1/pgp.c Sat Jun 22 07:16:22 1996 *************** *** 131,136 **** --- 131,141 ---- #include "keymaint.h" #include "keyadd.h" #include "rsaglue.h" + + #ifdef SHA1 + #include "sha1.h" + #endif + #ifdef M_XENIX char *strstr(); long time(); *************** *** 661,666 **** --- 666,674 ---- case 'w': wipeflag = TRUE; break; + case 'x': + mdalg_flag = SHA1_ALGORITHM_BYTE; + break; case 'z': break; /* '+' special option: does not require - */ diff -c pgp_262/rsaglue1.c pgp_sha1/rsaglue1.c *** pgp_262/rsaglue1.c Fri Jun 21 23:31:17 1996 --- pgp_sha1/rsaglue1.c Sat Jun 22 07:22:07 1996 *************** *** 53,58 **** --- 53,99 ---- static byte asn_array[] = { /* PKCS 01 block type 01 data */ 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 0x02,0x05,0x05,0x00,0x04,0x10 }; + #ifdef SHA1 + static byte sha1_asn_array[] = { + 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a, + 0x05,0x00,0x04,0x14 }; + /* + Taken from Internet Draft draft-ietf-cat-spkmgss-06, + "The Simple Public-Key GSS-API Mechanism (SPKM)", by + C. Adams, Bell-Northern Research, Jan. 19, 1996. See + also "Working Implementation Agreements for Open Systems + Interconnection Protocols: Part 12 - OS Security, Output + from the December 1994 Open Systems Environment + Implementors' Workshop (OIW)" + + SHA1 OBJECT IDENTIFIER ::= { + iso(1) identified-organization(3) oiw(14) secsig(3) + algorithm(2) 26 + } + + ASN.1 encoding: + 0x30, / * Universal, Constructed, Sequence * / + 0x21, / * Length 33 (bytes following) * / + 0x30, / * Universal, Constructed, Sequence * / + 0x09, / * Length 9 * / + 0x06, / * Universal, Primitive, object-identifier * / + 0x05, / * Length 5 * / + 43, / * 43 = ISO(1)*40 + 3 * / + 14, + 3, + 2, + 26, + 0x05, / * Universal, Primitive, NULL * / + 0x00, / * Length 0 * / + 0x04, / * Universal, Primitive, Octet string * / + 0x14 / * Length 20 * / + / * 20 SHA.1 digest bytes go here * / + + Cf. "A Layman's Guide to a Subset of ASN.1, BER, and DER -- + An RSA Laboratories Technical Note" by Burton S. Kaliski Jr. + Revised November 1, 1993 + */ + #endif /* SHA1 */ /* This many bytes from the end, there's a zero byte */ #define ASN_ZERO_END 3 *************** *** 144,149 **** --- 185,195 ---- *p++ = 0; i = blocksize - 2 - bytes; /* Padding needed */ + #ifdef SHA1 + if (bytes == 20) + i -= sizeof(sha1_asn_array); /* Space for type encoding */ + else + #endif i -= sizeof(asn_array); /* Space for type encoding */ if (i < 0) { i = -4; /* Error code */ *************** *** 153,160 **** --- 199,215 ---- memset(p, ~0, i); /* All 1's padding */ p += i; *p++ = 0; /* Zero framing byte */ + #ifdef SHA1 + if (bytes == 20) { + memcpy(p, sha1_asn_array, sizeof(sha1_asn_array)); /* ASN data */ + p += sizeof(sha1_asn_array); + } else { + #endif memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */ p += sizeof(asn_array); + #ifdef SHA1 + } + #endif memcpy(p, inbuf, bytes); /* User data */ mp_convert_order((byte *)temp); *************** *** 241,250 **** --- 296,315 ---- if (front[-1]) /* First non-FF byte should be 0 */ goto ErrorReturn; /* Then comes the ASN header */ + #ifdef SHA1 + if (memcmp(front, asn_array, sizeof(asn_array))) { + if (memcmp(front, sha1_asn_array, sizeof(sha1_asn_array))) { + mp_burn(temp); + return -7; + } + front += sizeof(sha1_asn_array); + } else + #else if (memcmp(front, asn_array, sizeof(asn_array))) { mp_burn(temp); return -7; } + #endif front += sizeof(asn_array); } diff -c pgp_262/rsaglue2.c pgp_sha1/rsaglue2.c *** pgp_262/rsaglue2.c Fri Jun 21 23:31:02 1996 --- pgp_sha1/rsaglue2.c Sat Jun 22 07:27:59 1996 *************** *** 175,180 **** --- 175,221 ---- static byte asn_array[] = { /* PKCS 01 block type 01 data */ 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 0x02,0x05,0x05,0x00,0x04,0x10 }; + #ifdef SHA1 + static byte sha1_asn_array[] = { + 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a, + 0x05,0x00,0x04,0x14 }; + /* + Taken from Internet Draft draft-ietf-cat-spkmgss-06, + "The Simple Public-Key GSS-API Mechanism (SPKM)", by + C. Adams, Bell-Northern Research, Jan. 19, 1996. See + also "Working Implementation Agreements for Open Systems + Interconnection Protocols: Part 12 - OS Security, Output + from the December 1994 Open Systems Environment + Implementors' Workshop (OIW)" + + SHA1 OBJECT IDENTIFIER ::= { + iso(1) identified-organization(3) oiw(14) secsig(3) + algorithm(2) 26 + } + + ASN.1 encoding: + 0x30, / * Universal, Constructed, Sequence * / + 0x21, / * Length 33 (bytes following) * / + 0x30, / * Universal, Constructed, Sequence * / + 0x09, / * Length 9 * / + 0x06, / * Universal, Primitive, object-identifier * / + 0x05, / * Length 5 * / + 43, / * 43 = ISO(1)*40 + 3 * / + 14, + 3, + 2, + 26, + 0x05, / * Universal, Primitive, NULL * / + 0x00, / * Length 0 * / + 0x04, / * Universal, Primitive, Octet string * / + 0x14 / * Length 20 * / + / * 20 SHA.1 digest bytes go here * / + + Cf. "A Layman's Guide to a Subset of ASN.1, BER, and DER -- + An RSA Laboratories Technical Note" by Burton S. Kaliski Jr. + Revised November 1, 1993 + */ + #endif /* SHA1 */ /* This many bytes from the end, there's a zero byte */ #define ASN_ZERO_END 3 *************** *** 263,272 **** --- 304,328 ---- i = make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N); if (i < 0) goto Cleanup; + #ifdef SHA1 + if (bytes == 20) { + memcpy(p, sha1_asn_array, sizeof(sha1_asn_array)); /* ASN data */ + p += sizeof(sha1_asn_array); + } else { + #endif memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */ p += sizeof(asn_array); + #ifdef SHA1 + } + #endif memcpy(p, inbuf, bytes); /* User data */ /* Pad and encrypt */ + #ifdef SHA1 + if (bytes == 20) + i = RSAPrivateEncrypt((byte *)temp, &blocksize, + (byte *)temp, bytes+sizeof(sha1_asn_array), &PrivKey); + else + #endif i = RSAPrivateEncrypt((byte *)temp, &blocksize, (byte *)temp, bytes+sizeof(asn_array), &PrivKey); burn(PrivKey); *************** *** 322,331 **** --- 378,397 ---- front = (byte *)temp; back = front+blocksize; + #ifdef SHA1 + if (memcmp(front, asn_array, sizeof(asn_array))) { + if (memcmp(front, sha1_asn_array, sizeof(sha1_asn_array))) { + mp_burn(temp); + return -7; + } + front += sizeof(sha1_asn_array); + } else + #else if (memcmp(front, asn_array, sizeof(asn_array))) { mp_burn(temp); return -7; } + #endif front += sizeof(asn_array); /* We're done - copy user data to outbuf */