]> wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
test_digest: Test all block sizes and alignments
authorVitaly Chikunov <vt@altlinux.org>
Sun, 1 Mar 2020 03:03:40 +0000 (06:03 +0300)
committerDmitry Belyavskiy <beldmit@users.noreply.github.com>
Sun, 1 Mar 2020 09:24:50 +0000 (12:24 +0300)
There need to be more tests than 2 constant fixed size blocks.
Final digest values are generated from the first run.

Test description in comments.

test_digest.c

index 1628ab2bcbb1c4a563d8e0b753918ec9f3ae009d..1e539ae982963660a45774295c2b00ce49046730 100644 (file)
@@ -50,6 +50,8 @@ struct hash_testvec {
        const char *plaintext;
        const char *digest;
        unsigned short psize;
+       unsigned short mdsize;
+       unsigned short block_size;
 };
 
 static const struct hash_testvec testvecs[] = {
@@ -126,6 +128,30 @@ static const struct hash_testvec testvecs[] = {
        { 0 }
 };
 
+/* synthetic test */
+static const struct hash_testvec stestvecs[] = {
+       {
+               .nid = NID_id_GostR3411_2012_256,
+               .name = "streebog256",
+               .mdsize = 32,
+               .block_size = 64,
+               .digest =
+                       "\xa2\xf3\x6d\x9c\x42\xa1\x1e\xad\xe3\xc1\xfe\x99\xf9\x99\xc3\x84"
+                       "\xe7\x98\xae\x24\x50\x75\x73\xd7\xfc\x99\x81\xa0\x45\x85\x41\xf6"
+       }, {
+               .nid = NID_id_GostR3411_2012_512,
+               .name = "streebog512",
+               .mdsize = 64,
+               .block_size = 64,
+               .digest =
+                       "\x1d\x14\x4d\xd8\xb8\x27\xfb\x55\x1a\x5a\x7d\x03\xbb\xdb\xfa\xcb"
+                       "\x43\x6b\x5b\xc5\x77\x59\xfd\x5f\xf2\x3b\x8e\xf9\xc4\xdd\x6f\x79"
+                       "\x45\xd8\x16\x59\x9e\xaa\xbc\xf2\xb1\x4f\xd0\xe4\xf6\xad\x46\x60"
+                       "\x90\x89\xf7\x2f\x93\xd8\x85\x0c\xb0\x43\xff\x5a\xb6\xe3\x69\xbd"
+       },
+       { 0 }
+};
+
 static int do_digest(int hash_nid, const char *plaintext, unsigned int psize,
     const char *etalon)
 {
@@ -166,7 +192,7 @@ static int do_test(const struct hash_testvec *tv)
                mdname = "streebog256";
        else if (tv->nid == NID_id_GostR3411_2012_512)
                mdname = "streebog512";
-       printf(cBLUE "Test %s %s: " cNORM, mdname, tv->name);
+       printf(cBLUE "Test %s %s: " cNORM, mdname, tv->name);
        fflush(stdout);
        ret |= do_digest(tv->nid, tv->plaintext, tv->psize, tv->digest);
 
@@ -188,6 +214,106 @@ static int do_test(const struct hash_testvec *tv)
        return ret;
 }
 
+#define SUPER_SIZE 256
+/*
+ * For 256-byte buffer filled with 256 bytes from 0 to 255;
+ * Digest them 256 times from the buffer end with lengths from 0 to 256,
+ * and from beginning of the buffer with lengths from 0 to 256;
+ * Each produced digest is digested again into final sum.
+ */
+static int do_stest_once(const struct hash_testvec *tv, unsigned int shifts)
+{
+    unsigned char *ibuf, *md;
+    T(ibuf = OPENSSL_zalloc(SUPER_SIZE + shifts));
+
+    /* fill with pattern */
+    unsigned int len;
+    for (len = 0; len < SUPER_SIZE; len++)
+           ibuf[shifts + len] = len & 0xff;
+
+    const EVP_MD *mdtype;
+    T(mdtype = EVP_get_digestbynid(tv->nid));
+    OPENSSL_assert(tv->nid == EVP_MD_type(mdtype));
+    EVP_MD_CTX *ctx, *ctx2;
+    T(ctx  = EVP_MD_CTX_new());
+    T(ctx2 = EVP_MD_CTX_new());
+    T(EVP_DigestInit(ctx2, mdtype));
+    OPENSSL_assert(tv->nid == EVP_MD_CTX_type(ctx2));
+    OPENSSL_assert(EVP_MD_block_size(mdtype) == tv->block_size);
+    OPENSSL_assert(EVP_MD_CTX_size(ctx2) == tv->mdsize);
+    OPENSSL_assert(EVP_MD_CTX_block_size(ctx2) == tv->block_size);
+
+    const unsigned int mdlen = EVP_MD_size(mdtype);
+    OPENSSL_assert(mdlen == tv->mdsize);
+    T(md = OPENSSL_zalloc(mdlen + shifts));
+    md += shifts; /* test for output digest alignment problems */
+
+    /* digest cycles */
+    for (len = 0; len < SUPER_SIZE; len++) {
+       /* for each len digest len bytes from the end of buf */
+       T(EVP_DigestInit(ctx, mdtype));
+       T(EVP_DigestUpdate(ctx, ibuf + shifts + SUPER_SIZE - len, len));
+       T(EVP_DigestFinal(ctx, md, NULL));
+       T(EVP_DigestUpdate(ctx2, md, mdlen));
+    }
+
+    for (len = 0; len < SUPER_SIZE; len++) {
+       /* for each len digest len bytes from the beginning of buf */
+       T(EVP_DigestInit(ctx, mdtype));
+       T(EVP_DigestUpdate(ctx, ibuf + shifts, len));
+       T(EVP_DigestFinal(ctx, md, NULL));
+       T(EVP_DigestUpdate(ctx2, md, mdlen));
+    }
+
+    OPENSSL_free(ibuf);
+    EVP_MD_CTX_free(ctx);
+
+    T(EVP_DigestFinal(ctx2, md, &len));
+    EVP_MD_CTX_free(ctx2);
+
+    if (len != mdlen) {
+       printf(cRED "digest output len mismatch %u != %u (expected)\n" cNORM,
+           len, mdlen);
+       goto err;
+    }
+
+    if (memcmp(md, tv->digest, mdlen) != 0) {
+       printf(cRED "digest mismatch\n" cNORM);
+
+       unsigned int i;
+       printf("  Expected value is: ");
+       for (i = 0; i < mdlen; i++)
+           printf("\\x%02x", md[i]);
+       printf("\n");
+       goto err;
+    }
+
+    OPENSSL_free(md - shifts);
+    return 0;
+err:
+    OPENSSL_free(md - shifts);
+    return 1;
+}
+
+/* do different block sizes and different memory offsets */
+static int do_stest(const struct hash_testvec *tv)
+{
+    int ret = 0;
+
+    printf(cBLUE "Test 2 %s: " cNORM, tv->name);
+    fflush(stdout);
+
+    unsigned int shifts;
+    for (shifts = 0; shifts < 16 && !ret; shifts++)
+       ret |= do_stest_once(tv, shifts);
+
+    if (!ret)
+       printf(cGREEN "success\n" cNORM);
+    else
+       printf(cRED "fail\n" cNORM);
+    return 0;
+}
+
 int main(int argc, char **argv)
 {
     int ret = 0;
@@ -207,6 +333,8 @@ int main(int argc, char **argv)
     const struct hash_testvec *tv;
     for (tv = testvecs; tv->nid; tv++)
            ret |= do_test(tv);
+    for (tv = stestvecs; tv->nid; tv++)
+           ret |= do_stest(tv);
 
     ENGINE_finish(eng);
     ENGINE_free(eng);