* t_shs3.c: New test file from Marcus Watts.
authorKen Raeburn <raeburn@mit.edu>
Mon, 16 Jul 2001 20:25:15 +0000 (20:25 +0000)
committerKen Raeburn <raeburn@mit.edu>
Mon, 16 Jul 2001 20:25:15 +0000 (20:25 +0000)
(longReverse): Resurrected function long since deleted from shs.c.
* Makefile.in (check-unix, check-windows): Use t_shs3 test.
(clean): Delete it.

* shs.c (SHSTransform): Make input data pointer point to const.
(SHSUpdate): Bugfixes suggested by Marcus Watts, to fix buffer overruns, bugs
with small or odd block sizes.

[mostly pr krb5-libs/626]

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13605 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/crypto/sha1/ChangeLog
src/lib/crypto/sha1/Makefile.in
src/lib/crypto/sha1/shs.c
src/lib/crypto/sha1/t_shs3.c [new file with mode: 0644]

index 40f73c801dd92849306abbf5365e636407c6a677..88469909bb299e9490d3d7de732164d5807f4033 100644 (file)
@@ -1,3 +1,15 @@
+2001-07-16  Ken Raeburn  <raeburn@mit.edu>
+
+       * t_shs3.c: New test file from Marcus Watts.
+       (longReverse): Resurrected function long since deleted from
+       shs.c.
+       * Makefile.in (check-unix, check-windows): Use t_shs3 test.
+       (clean): Delete it.
+
+       * shs.c (SHSTransform): Make input data pointer point to const.
+       (SHSUpdate): Bugfixes suggested by Marcus Watts, to fix buffer
+       overruns, bugs with small or odd block sizes.
+
 2001-07-05  Danilo Almeida  <dalmeida@mit.edu>
 
        * shs.h, shs.c, t_shs.c: Fix sha1 on Windows by renaming LONG to
index 5d1b69c4f9e7a6c2207243f57472b6eb7f61c397..094cc07fba5b6cf71336c9624ce04bf7e2bc60f7 100644 (file)
@@ -33,13 +33,18 @@ t_shs: t_shs.o shs.o
 $(OUTPRE)t_shs.exe: $(OUTPRE)t_shs.obj $(OUTPRE)shs.obj
        link -out:$@ $**
 
-check-unix:: t_shs
+check-unix:: t_shs t_shs3
        $(C)t_shs -x
+       $(C)t_shs3
 
-check-windows:: $(OUTPRE)t_shs.exe
+check-windows:: $(OUTPRE)t_shs.exe $(OUTPRE)t_shs3.exe
        $(OUTPRE)$(C)t_shs.exe -x
+       $(OUTPRE)$(C)t_shs3.exe
 
 clean:: 
-       $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT)
+       $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT) t_shs3$(EXEEXT) t_shs3.$(OBJEXT)
 
 clean-unix:: clean-libobjs
+
+t_shs3: t_shs3.o shs.o
+       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o t_shs3 t_shs3.o shs.o
index 819de479efdbd3bfe1c7b9aadb6f4d383595194f..873f8784e99a449c03999f30daecaa53e038b55b 100644 (file)
@@ -97,12 +97,12 @@ void shsInit(shsInfo)
 
    Note that this corrupts the shsInfo->data area */
 
-static void SHSTransform KRB5_PROTOTYPE((SHS_LONG *digest, SHS_LONG *data));
+static void SHSTransform (SHS_LONG *digest, const SHS_LONG *data);
 
 static
 void SHSTransform(digest, data)
     SHS_LONG *digest;
-    SHS_LONG *data;
+    const SHS_LONG *data;
 {
     SHS_LONG A, B, C, D, E;     /* Local vars */
     SHS_LONG eData[ 16 ];       /* Expanded data */
@@ -237,25 +237,21 @@ void shsUpdate(shsInfo, buffer, count)
     /* Handle any leading odd-sized chunks */
     if (dataCount) {
        lp = shsInfo->data + dataCount / 4;
-       canfill = (count >= dataCount);
        dataCount = SHS_DATASIZE - dataCount;
+       canfill = (count >= dataCount);
 
        if (dataCount % 4) {
            /* Fill out a full 32 bit word first if needed -- this
               is not very efficient (computed shift amount),
               but it shouldn't happen often. */
            while (dataCount % 4 && count > 0) {
-               *lp |= (SHS_LONG) *buffer++ << ((3 - dataCount++ % 4) * 8);
+               *lp |= (SHS_LONG) *buffer++ << ((--dataCount % 4) * 8);
                count--;
            }
            lp++;
        }
        while (lp < shsInfo->data + 16) {
-           *lp = (SHS_LONG) *buffer++ << 24;
-           *lp |= (SHS_LONG) *buffer++ << 16;
-           *lp |= (SHS_LONG) *buffer++ << 8;
-           *lp++ |= (SHS_LONG) *buffer++;
-           if ((count -= 4) < 4 && lp < shsInfo->data + 16) {
+           if (count < 4) {
                *lp = 0;
                switch (count % 4) {
                case 3:
@@ -265,9 +261,14 @@ void shsUpdate(shsInfo, buffer, count)
                case 1:
                    *lp |= (SHS_LONG) buffer[0] << 24;
                }
-               break;
                count = 0;
+               break;          /* out of while loop */
            }
+           *lp = (SHS_LONG) *buffer++ << 24;
+           *lp |= (SHS_LONG) *buffer++ << 16;
+           *lp |= (SHS_LONG) *buffer++ << 8;
+           *lp++ |= (SHS_LONG) *buffer++;
+           count -= 4;
        }
        if (canfill) {
            SHSTransform(shsInfo->digest, shsInfo->data);
diff --git a/src/lib/crypto/sha1/t_shs3.c b/src/lib/crypto/sha1/t_shs3.c
new file mode 100644 (file)
index 0000000..1ba030d
--- /dev/null
@@ -0,0 +1,583 @@
+/* test shs code */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "shs.h"
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+   array of longwords.  It is possible to make the code endianness-
+   independant by fiddling around with data at the byte level, but this
+   makes for very slow code, so we rely on the user to sort out endianness
+   at compile time */
+
+void longReverse( SHS_LONG *buffer, int byteCount )
+{
+    SHS_LONG value;
+    static int init = 0;
+    char *cp;
+
+    switch (init) {
+    case 0:
+       init=1;
+       cp = (char *) &init;
+       if (*cp == 1) {
+           init=2;
+           break;
+       }
+       init=1;
+       /* fall through - MSB */
+    case 1:
+       return;
+    }
+
+    byteCount /= sizeof( SHS_LONG );
+    while( byteCount-- ) {
+        value = *buffer;
+        value = ( ( value & 0xFF00FF00L ) >> 8  ) | 
+                ( ( value & 0x00FF00FFL ) << 8 );
+        *buffer++ = ( value << 16 ) | ( value >> 16 );
+    }
+}
+
+int rc;
+int mode;
+int Dflag;
+
+main(argc,argv)
+       char **argv;
+{
+       int f = 0;
+       char *argp;
+
+       while (--argc > 0) if (*(argp = *++argv)=='-')
+       while (*++argp) switch(*argp)
+       {
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+               if (mode) goto Usage;
+               mode = *argp;
+               break;
+       case 'D':
+               if (argc <= 1) goto Usage;
+               --argc;
+               Dflag = atoi(*++argv);
+               break;
+       case '-':
+               break;
+       default:
+               fprintf (stderr,"Bad switch char <%c>\n", *argp);
+       Usage:
+               fprintf(stderr, "Usage: t_shs [-1234567] [-D #]\n");
+               exit(1);
+       }
+       else goto Usage;
+
+       process();
+       exit(rc);
+}
+
+process()
+{
+       switch(mode)
+       {
+       case '1':
+               test1();
+               break;
+       case '2':
+               test2();
+               break;
+       case '3':
+               test3();
+               break;
+       case '4':
+               test4();
+               break;
+       case '5':
+               test5();
+               break;
+       case '6':
+               test6();
+               break;
+       case '7':
+               test7();
+               break;
+       default:
+               test1();
+               test2();
+               test3();
+               test4();
+               test5();
+               test6();
+               test7();
+       }
+}
+
+#ifndef shsDigest
+unsigned char *
+shsDigest(si)
+       SHS_INFO *si;
+{
+       longReverse(si->digest, SHS_DIGESTSIZE);
+       return (unsigned char*) si->digest;
+}
+#endif
+
+unsigned char results1[SHS_DIGESTSIZE] = {
+0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,
+0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d};
+
+test1()
+{
+       SHS_INFO si[1];
+       unsigned char digest[SHS_DIGESTSIZE];
+       int failed;
+       int i;
+
+       printf("Running SHS test 1 ...\n");
+       shsInit(si);
+       shsUpdate(si, "abc", 3);
+       shsFinal(si);
+       memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+       if (failed = memcmp(digest, results1, SHS_DIGESTSIZE))
+       {
+               fprintf(stderr,"SHS test 1 failed!\n");
+               rc = 1;
+       }
+       printf ("%s, results = ", failed ? "Failed" : "Passed");
+       for (i = 0; i < SHS_DIGESTSIZE; ++i)
+               printf("%02x",digest[i]);
+       if (failed)
+       {
+               printf ("\n, expected ");
+               for (i = 0; i < SHS_DIGESTSIZE; ++i)
+                       printf("%02x",results1[i]);
+       }
+       printf("\n");
+}
+
+unsigned char results2[SHS_DIGESTSIZE] = {
+0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,
+0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1};
+
+test2()
+{
+       SHS_INFO si[1];
+       unsigned char digest[SHS_DIGESTSIZE];
+       int failed;
+       int i;
+
+       printf("Running SHS test 2 ...\n");
+       shsInit(si);
+       shsUpdate(si,
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               56);
+       shsFinal(si);
+       memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+       if (failed = memcmp(digest, results2, SHS_DIGESTSIZE))
+       {
+               fprintf(stderr,"SHS test 2 failed!\n");
+               rc = 1;
+       }
+       printf ("%s, results = ", failed ? "Failed" : "Passed");
+       for (i = 0; i < SHS_DIGESTSIZE; ++i)
+               printf("%02x",digest[i]);
+       if (failed)
+       {
+               printf ("\n, expected ");
+               for (i = 0; i < SHS_DIGESTSIZE; ++i)
+                       printf("%02x",results2[i]);
+       }
+       printf("\n");
+}
+
+unsigned char results3[SHS_DIGESTSIZE] = {
+0x34,0xaa,0x97,0x3c,0xd4,0xc4,0xda,0xa4,0xf6,0x1e,
+0xeb,0x2b,0xdb,0xad,0x27,0x31,0x65,0x34,0x01,0x6f};
+
+test3()
+{
+       SHS_INFO si[1];
+       unsigned char digest[SHS_DIGESTSIZE];
+       int failed;
+       int i;
+
+       printf("Running SHS test 3 ...\n");
+       shsInit(si);
+       for (i = 0; i < 15625; ++i)
+               shsUpdate(si,
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+                       64);
+       shsFinal(si);
+       memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+       if (failed = memcmp(digest, results3, SHS_DIGESTSIZE))
+       {
+               fprintf(stderr,"SHS test 3 failed!\n");
+               rc = 1;
+       }
+       printf ("%s, results = ", failed ? "Failed" : "Passed");
+       for (i = 0; i < SHS_DIGESTSIZE; ++i)
+               printf("%02x",digest[i]);
+       if (failed)
+       {
+               printf ("\n, expected ");
+               for (i = 0; i < SHS_DIGESTSIZE; ++i)
+                       printf("%02x",results3[i]);
+       }
+       printf("\n");
+}
+
+unsigned char randdata[] = {
+0xfe,0x28,0x79,0x25,0xf5,0x03,0xf9,0x1c,0xcd,0x70,0x7b,0xb0,0x42,0x02,0xb8,0x2f,
+0xf3,0x63,0xa2,0x79,0x8e,0x9b,0x33,0xd7,0x2b,0xc4,0xb4,0xd2,0xcb,0x61,0xec,0xbb,
+0x94,0xe1,0x8f,0x53,0x80,0x55,0xd9,0x90,0xb2,0x03,0x58,0xfa,0xa6,0xe5,0x18,0x57,
+0x68,0x04,0x24,0x98,0x41,0x7e,0x84,0xeb,0xc1,0x39,0xbc,0x1d,0xf7,0x4e,0x92,0x72,
+0x1a,0x5b,0xb6,0x99,0x43,0xa5,0x0a,0x45,0x73,0x55,0xfd,0x57,0x83,0x45,0x36,0x5c,
+0xfd,0x39,0x08,0x6e,0xe2,0x01,0x9a,0x8c,0x4e,0x39,0xd2,0x0d,0x5f,0x0e,0x35,0x15,
+0xb9,0xac,0x5f,0xa1,0x8a,0xe6,0xdd,0x6e,0x68,0x9d,0xf6,0x29,0x95,0xf6,0x7d,0x7b,
+0xd9,0x5e,0xf4,0x67,0x25,0xbd,0xee,0xed,0x53,0x60,0xb0,0x47,0xdf,0xef,0xf4,0x41,
+0xbd,0x45,0xcf,0x5c,0x93,0x41,0x87,0x97,0x82,0x39,0x20,0x66,0xb4,0xda,0xcb,0x66,
+0x93,0x02,0x2e,0x7f,0x94,0x4c,0xc7,0x3b,0x2c,0xcf,0xf6,0x99,0x6f,0x13,0xf1,0xc5,
+0x28,0x2b,0xa6,0x6c,0x39,0x26,0x7f,0x76,0x24,0x4a,0x6e,0x01,0x40,0x63,0xf8,0x00,
+0x06,0x23,0x5a,0xaa,0xa6,0x2f,0xd1,0x37,0xc7,0xcc,0x76,0xe9,0x54,0x1e,0x57,0x73,
+0xf5,0x33,0xaa,0x96,0xbe,0x35,0xcd,0x1d,0xd5,0x7d,0xac,0x50,0xd5,0xf8,0x47,0x2d,
+0xd6,0x93,0x5f,0x6e,0x38,0xd3,0xac,0xd0,0x7e,0xad,0x9e,0xf8,0x87,0x95,0x63,0x15,
+0x65,0xa3,0xd4,0xb3,0x9a,0x6c,0xac,0xcd,0x2a,0x54,0x83,0x13,0xc4,0xb4,0x94,0xfa,
+0x76,0x87,0xc5,0x8b,0x4a,0x10,0x92,0x05,0xd1,0x0e,0x97,0xfd,0xc8,0xfb,0xc5,0xdc,
+0x21,0x4c,0xc8,0x77,0x5c,0xed,0x32,0x22,0x77,0xc1,0x38,0x30,0xd7,0x8e,0x2a,0x70,
+0x72,0x67,0x13,0xe4,0xb7,0x18,0xd4,0x76,0xdd,0x32,0x12,0xf4,0x5d,0xc9,0xec,0xc1,
+0x2c,0x8a,0xfe,0x08,0x6c,0xea,0xf6,0xab,0x5a,0x0e,0x8e,0x81,0x1d,0xc8,0x5a,0x4b,
+0xed,0xb9,0x7f,0x4b,0x67,0xe3,0x65,0x46,0xc9,0xf2,0xab,0x37,0x0a,0x98,0x67,0x5b,
+0xb1,0x3b,0x02,0x91,0x38,0x71,0xea,0x62,0x88,0xae,0xb6,0xdb,0xfc,0x55,0x79,0x33,
+0x69,0x95,0x51,0xb6,0xe1,0x3b,0xab,0x22,0x68,0x54,0xf9,0x89,0x9c,0x94,0xe0,0xe3,
+0xd3,0x48,0x5c,0xe9,0x78,0x5b,0xb3,0x4b,0xba,0xd8,0x48,0xd8,0xaf,0x91,0x4e,0x23,
+0x38,0x23,0x23,0x6c,0xdf,0x2e,0xf0,0xff,0xac,0x1d,0x2d,0x27,0x10,0x45,0xa3,0x2d,
+0x8b,0x00,0xcd,0xe2,0xfc,0xb7,0xdb,0x52,0x13,0xb7,0x66,0x79,0xd9,0xd8,0x29,0x0e,
+0x32,0xbd,0x52,0x6b,0x75,0x71,0x08,0x83,0x1b,0x67,0x28,0x93,0x97,0x97,0x32,0xff,
+0x8b,0xd3,0x98,0xa3,0xce,0x2b,0x88,0x37,0x1c,0xcc,0xa0,0xd1,0x19,0x9b,0xe6,0x11,
+0xfc,0xc0,0x3c,0x4e,0xe1,0x35,0x49,0x29,0x19,0xcf,0x1d,0xe1,0x60,0x74,0xc0,0xe9,
+0xf7,0xb4,0x99,0xa0,0x23,0x50,0x51,0x78,0xcf,0xc0,0xe5,0xc2,0x1c,0x16,0xd2,0x24,
+0x5a,0x63,0x54,0x83,0xaa,0x74,0x3d,0x41,0x0d,0x52,0xee,0xfe,0x0f,0x4d,0x13,0xe1,
+0x27,0x00,0xc4,0xf3,0x2b,0x55,0xe0,0x9c,0x81,0xe0,0xfc,0xc2,0x13,0xd4,0x39,0x09
+};
+
+unsigned char results4[SHS_DIGESTSIZE] = {
+0x13,0x62,0xfc,0x87,0x68,0x33,0xd5,0x1d,0x2f,0x0c,
+0x73,0xe3,0xfb,0x87,0x6a,0x6b,0xc3,0x25,0x54,0xfc};
+
+test4()
+{
+       SHS_INFO si[1];
+       unsigned char digest[SHS_DIGESTSIZE];
+       int failed;
+       int i, j, k;
+
+       printf("Running SHS test 4 ...\n");
+       shsInit(si);
+       shsUpdate(si, randdata, 19);
+       shsFinal(si);
+       memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+       if (failed = memcmp(digest, results4, SHS_DIGESTSIZE))
+       {
+               fprintf(stderr,"SHS test 4 failed!\n");
+               rc = 1;
+       }
+       printf ("%s, results = ", failed ? "Failed" : "Passed");
+       for (i = 0; i < SHS_DIGESTSIZE; ++i)
+               printf("%02x",digest[i]);
+       if (failed)
+       {
+               printf ("\n, expected ");
+               for (i = 0; i < SHS_DIGESTSIZE; ++i)
+                       printf("%02x",results4[i]);
+       }
+       printf("\n");
+}
+
+unsigned char results5[SHS_DIGESTSIZE] = {
+0x19,0x4d,0xf6,0xeb,0x8e,0x02,0x6d,0x37,0x58,0x64,
+0xe5,0x95,0x19,0x2a,0xdd,0x1c,0xc4,0x3c,0x24,0x86};
+
+test5()
+{
+       SHS_INFO si[1];
+       unsigned char digest[SHS_DIGESTSIZE];
+       int failed;
+       int i, j, k;
+
+       printf("Running SHS test 5 ...\n");
+       shsInit(si);
+       shsUpdate(si, randdata, 19);
+       shsUpdate(si, randdata+32, 15);
+       shsFinal(si);
+       memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+       if (failed = memcmp(digest, results5, SHS_DIGESTSIZE))
+       {
+               fprintf(stderr,"SHS test 5 failed!\n");
+               rc = 1;
+       }
+       printf ("%s, results = ", failed ? "Failed" : "Passed");
+       for (i = 0; i < SHS_DIGESTSIZE; ++i)
+               printf("%02x",digest[i]);
+       if (failed)
+       {
+               printf ("\n, expected ");
+               for (i = 0; i < SHS_DIGESTSIZE; ++i)
+                       printf("%02x",results5[i]);
+       }
+       printf("\n");
+}
+
+unsigned char results6[SHS_DIGESTSIZE] = {
+0x4e,0x16,0x57,0x9d,0x4b,0x48,0xa9,0x1c,0x88,0x72,
+0x83,0xdb,0x88,0xd1,0xea,0x3a,0x45,0xdf,0xa1,0x10};
+
+test6()
+{
+       struct {
+               long pad1;
+               SHS_INFO si1;
+               long pad2;
+               SHS_INFO si2;
+               long pad3;
+       } sdata;
+       unsigned char digest[SHS_DIGESTSIZE];
+       int failed;
+       int i, j, k;
+
+       printf("Running SHS test 6 ...\n");
+       sdata.pad1 = 0x12345678;
+       sdata.pad2 = 0x87654321;
+       sdata.pad3 = 0x78563412;
+       shsInit((&sdata.si2));
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #20 %#lx\n",
+sdata.pad2);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #21 %#lx\n",
+sdata.pad3);
+sdata.pad3 = 0x78563412;
+}
+       for (i = 0; i < 400; ++i)
+       {
+               shsInit(&sdata.si1);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #22 %#lx at %d\n",
+sdata.pad1, i);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #23 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+               shsUpdate(&sdata.si1, (randdata+sizeof(randdata))-i, i);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #24 %#lx at %d\n",
+sdata.pad1, i);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #25 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+               shsFinal(&sdata.si1);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #26 %#lx at %d\n",
+sdata.pad1, i);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #27 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+               memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE);
+               if (Dflag & 1)
+               {
+                       printf ("%d: ", i);
+                       for (j = 0; j < SHS_DIGESTSIZE; ++j)
+                               printf("%02x",digest[j]);
+                       printf("\n");
+               }
+               shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE);
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #28 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #29 %#lx at %d\n",
+sdata.pad3, i);
+sdata.pad3 = 0x78563412;
+}
+               if (Dflag & 2)
+                       printf ("%d: %08lx%08lx%08lx%08lx%08lx\n",
+                               i,
+                               sdata.si2.digest[0],
+                               sdata.si2.digest[1],
+                               sdata.si2.digest[2],
+                               sdata.si2.digest[3],
+                               sdata.si2.digest[4]);
+       }
+       shsFinal((&sdata.si2));
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #30 %#lx\n",
+sdata.pad2);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #31 %#lx\n",
+sdata.pad3);
+sdata.pad3 = 0x78563412;
+}
+       memcpy(digest, shsDigest((&sdata.si2)), SHS_DIGESTSIZE);
+       if (failed = memcmp(digest, results6, SHS_DIGESTSIZE))
+       {
+               fprintf(stderr,"SHS test 6 failed!\n");
+               rc = 1;
+       }
+       printf ("%s, results = ", failed ? "Failed" : "Passed");
+       for (i = 0; i < SHS_DIGESTSIZE; ++i)
+               printf("%02x",digest[i]);
+       if (failed)
+       {
+               printf ("\n, expected ");
+               for (i = 0; i < SHS_DIGESTSIZE; ++i)
+                       printf("%02x",results6[i]);
+       }
+       printf("\n");
+}
+
+unsigned char results7[SHS_DIGESTSIZE] = {
+0x89,0x41,0x65,0xce,0x76,0xc1,0xd1,0xd1,0xc3,0x6f,
+0xab,0x92,0x79,0x30,0x01,0x71,0x63,0x1f,0x74,0xfe};
+
+int jfsize[] = {0,1,31,32,
+       33,55,56,63,
+       64,65,71,72,
+       73,95,96,97,
+       119,120,123,127};
+int kfsize[] = {0,1,31,32,33,55,56,63};
+
+test7()
+{
+       struct {
+               long pad1;
+               SHS_INFO si1;
+               long pad2;
+               SHS_INFO si2;
+               long pad3;
+       } sdata;
+       unsigned char digest[SHS_DIGESTSIZE];
+       int failed;
+       int i, j, k, l;
+
+       printf("Running SHS test 7 ...\n");
+       sdata.pad1 = 0x12345678;
+       sdata.pad2 = 0x87654321;
+       sdata.pad3 = 0x78563412;
+       shsInit((&sdata.si2));
+       for (i = 1; i <= 128; ++i)
+       for (j = 0; j < 20; ++j)
+       for (k = 0; k < 8; ++k)
+       {
+               shsInit(&sdata.si1);
+               shsUpdate(&sdata.si1, (randdata+80+j), i);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #1 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #2 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+               shsUpdate(&sdata.si1, randdata+i, jfsize[j]);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #3 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #4 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+               if (k) shsUpdate(&sdata.si1, randdata+(i^j), kfsize[k]);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #5 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #6 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+               shsFinal(&sdata.si1);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #7 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #8 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+               memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE);
+               if (Dflag & 1)
+               {
+                       printf ("%d,%d,%d: ", i, j, k);
+                       for (l = 0; l < SHS_DIGESTSIZE; ++l)
+                               printf("%02x",digest[l]);
+                       printf("\n");
+               }
+               shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE);
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #9 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #10 %#lx at %d,%d,%d\n",
+sdata.pad3, i,j,k);
+sdata.pad3 = 0x78563412;
+}
+               if (Dflag & 2)
+                       printf ("%d,%d,%d: %08lx%08lx%08lx%08lx%08lx\n",
+                               i,j,k,
+                               sdata.si2.digest[0],
+                               sdata.si2.digest[1],
+                               sdata.si2.digest[2],
+                               sdata.si2.digest[3],
+                               sdata.si2.digest[4]);
+       }
+       shsFinal((&sdata.si2));
+       memcpy(digest, shsDigest((&sdata.si2)), SHS_DIGESTSIZE);
+       if (failed = memcmp(digest, results7, SHS_DIGESTSIZE))
+       {
+               fprintf(stderr,"SHS test 7 failed!\n");
+               rc = 1;
+       }
+       printf ("%s, results = ", failed ? "Failed" : "Passed");
+       for (i = 0; i < SHS_DIGESTSIZE; ++i)
+               printf("%02x",digest[i]);
+       if (failed)
+       {
+               printf ("\n, expected ");
+               for (i = 0; i < SHS_DIGESTSIZE; ++i)
+                       printf("%02x",results7[i]);
+       }
+       printf("\n");
+}