EVP_Digest*: enable SHA3 pre-hashing for DSA
[openssl.git] / test / evp_test.c
index 49d254dc2b3c12b451c0cbd3f3e2588a15f7c1c5..fa9cde8289109b2262c6d43122391cea0480d1aa 100644 (file)
@@ -463,6 +463,7 @@ typedef struct cipher_data_st {
     size_t aad_len[AAD_NUM];
     unsigned char *tag;
     size_t tag_len;
+    int tag_late;
 } CIPHER_DATA;
 
 static int cipher_test_init(EVP_TEST *t, const char *alg)
@@ -535,6 +536,15 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
         }
         if (strcmp(keyword, "Tag") == 0)
             return parse_bin(value, &cdat->tag, &cdat->tag_len);
+        if (strcmp(keyword, "SetTagLate") == 0) {
+            if (strcmp(value, "TRUE") == 0)
+                cdat->tag_late = 1;
+            else if (strcmp(value, "FALSE") == 0)
+                cdat->tag_late = 0;
+            else
+                return 0;
+            return 1;
+        }
     }
 
     if (strcmp(keyword, "Operation") == 0) {
@@ -620,7 +630,7 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
          * If encrypting or OCB just set tag length initially, otherwise
          * set tag length and value.
          */
-        if (enc || expected->aead == EVP_CIPH_OCB_MODE) {
+        if (enc || expected->aead == EVP_CIPH_OCB_MODE || expected->tag_late) {
             t->err = "TAG_LENGTH_SET_ERROR";
             tag = NULL;
         } else {
@@ -643,14 +653,6 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
         goto err;
     }
 
-    if (!enc && expected->aead == EVP_CIPH_OCB_MODE) {
-        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
-                                 expected->tag_len, expected->tag)) {
-            t->err = "TAG_SET_ERROR";
-            goto err;
-        }
-    }
-
     if (expected->aead == EVP_CIPH_CCM_MODE) {
         if (!EVP_CipherUpdate(ctx, NULL, &tmplen, NULL, out_len)) {
             t->err = "CCM_PLAINTEXT_LENGTH_SET_ERROR";
@@ -689,6 +691,15 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
             }
         }
     }
+
+    if (!enc && (expected->aead == EVP_CIPH_OCB_MODE || expected->tag_late)) {
+        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
+                                 expected->tag_len, expected->tag)) {
+            t->err = "TAG_SET_ERROR";
+            goto err;
+        }
+    }
+
     EVP_CIPHER_CTX_set_padding(ctx, 0);
     t->err = "CIPHERUPDATE_ERROR";
     tmplen = 0;
@@ -1378,6 +1389,7 @@ static int pkey_test_run(EVP_TEST *t)
     PKEY_DATA *expected = t->data;
     unsigned char *got = NULL;
     size_t got_len;
+    EVP_PKEY_CTX *copy = NULL;
 
     if (expected->keyop(expected->ctx, NULL, &got_len,
                         expected->input, expected->input_len) <= 0
@@ -1396,8 +1408,33 @@ static int pkey_test_run(EVP_TEST *t)
         goto err;
 
     t->err = NULL;
+    OPENSSL_free(got);
+    got = NULL;
+
+    /* Repeat the test on a copy. */
+    if (!TEST_ptr(copy = EVP_PKEY_CTX_dup(expected->ctx))) {
+        t->err = "INTERNAL_ERROR";
+        goto err;
+    }
+    if (expected->keyop(copy, NULL, &got_len, expected->input,
+                        expected->input_len) <= 0
+            || !TEST_ptr(got = OPENSSL_malloc(got_len))) {
+        t->err = "KEYOP_LENGTH_ERROR";
+        goto err;
+    }
+    if (expected->keyop(copy, got, &got_len, expected->input,
+                        expected->input_len) <= 0) {
+        t->err = "KEYOP_ERROR";
+        goto err;
+    }
+    if (!memory_err_compare(t, "KEYOP_MISMATCH",
+                            expected->output, expected->output_len,
+                            got, got_len))
+        goto err;
+
  err:
     OPENSSL_free(got);
+    EVP_PKEY_CTX_free(copy);
     return 1;
 }
 
@@ -1892,13 +1929,14 @@ static const EVP_TEST_METHOD encode_test_method = {
     encode_test_run,
 };
 
+
 /**
 ***  KDF TESTS
 **/
 
 typedef struct kdf_data_st {
     /* Context for this operation */
-    EVP_PKEY_CTX *ctx;
+    EVP_KDF_CTX *ctx;
     /* Expected output */
     unsigned char *output;
     size_t output_len;
@@ -1911,7 +1949,7 @@ typedef struct kdf_data_st {
 static int kdf_test_init(EVP_TEST *t, const char *name)
 {
     KDF_DATA *kdata;
-    int kdf_nid = OBJ_sn2nid(name);
+    const EVP_KDF *kdf;
 
 #ifdef OPENSSL_NO_SCRYPT
     if (strcmp(name, "scrypt") == 0) {
@@ -1920,21 +1958,17 @@ static int kdf_test_init(EVP_TEST *t, const char *name)
     }
 #endif
 
-    if (kdf_nid == NID_undef)
-        kdf_nid = OBJ_ln2nid(name);
+    kdf = EVP_get_kdfbyname(name);
+    if (kdf == NULL)
+        return 0;
 
     if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata))))
         return 0;
-    kdata->ctx = EVP_PKEY_CTX_new_id(kdf_nid, NULL);
+    kdata->ctx = EVP_KDF_CTX_new(kdf);
     if (kdata->ctx == NULL) {
         OPENSSL_free(kdata);
         return 0;
     }
-    if (EVP_PKEY_derive_init(kdata->ctx) <= 0) {
-        EVP_PKEY_CTX_free(kdata->ctx);
-        OPENSSL_free(kdata);
-        return 0;
-    }
     t->data = kdata;
     return 1;
 }
@@ -1943,7 +1977,42 @@ static void kdf_test_cleanup(EVP_TEST *t)
 {
     KDF_DATA *kdata = t->data;
     OPENSSL_free(kdata->output);
-    EVP_PKEY_CTX_free(kdata->ctx);
+    EVP_KDF_CTX_free(kdata->ctx);
+}
+
+static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx,
+                         const char *value)
+{
+    int rv;
+    char *p, *tmpval;
+
+    if (!TEST_ptr(tmpval = OPENSSL_strdup(value)))
+        return 0;
+    p = strchr(tmpval, ':');
+    if (p != NULL)
+        *p++ = '\0';
+    rv = EVP_KDF_ctrl_str(kctx, tmpval, p);
+    if (rv == -2) {
+        t->err = "KDF_CTRL_INVALID";
+        rv = 1;
+    } else if (p != NULL && rv <= 0) {
+        /* If p has an OID and lookup fails assume disabled algorithm */
+        int nid = OBJ_sn2nid(p);
+
+        if (nid == NID_undef)
+             nid = OBJ_ln2nid(p);
+        if (nid != NID_undef
+                && EVP_get_digestbynid(nid) == NULL
+                && EVP_get_cipherbynid(nid) == NULL) {
+            t->skip = 1;
+            rv = 1;
+        } else {
+            t->err = "KDF_CTRL_ERROR";
+            rv = 1;
+        }
+    }
+    OPENSSL_free(tmpval);
+    return rv > 0;
 }
 
 static int kdf_test_parse(EVP_TEST *t,
@@ -1954,7 +2023,7 @@ static int kdf_test_parse(EVP_TEST *t,
     if (strcmp(keyword, "Output") == 0)
         return parse_bin(value, &kdata->output, &kdata->output_len);
     if (strncmp(keyword, "Ctrl", 4) == 0)
-        return pkey_test_ctrl(t, kdata->ctx, value);
+        return kdf_test_ctrl(t, kdata->ctx, value);
     return 0;
 }
 
@@ -1968,7 +2037,7 @@ static int kdf_test_run(EVP_TEST *t)
         t->err = "INTERNAL_ERROR";
         goto err;
     }
-    if (EVP_PKEY_derive(expected->ctx, got, &got_len) <= 0) {
+    if (EVP_KDF_derive(expected->ctx, got, got_len) <= 0) {
         t->err = "KDF_DERIVE_ERROR";
         goto err;
     }
@@ -1993,6 +2062,106 @@ static const EVP_TEST_METHOD kdf_test_method = {
 };
 
 
+/**
+***  PKEY KDF TESTS
+**/
+
+typedef struct pkey_kdf_data_st {
+    /* Context for this operation */
+    EVP_PKEY_CTX *ctx;
+    /* Expected output */
+    unsigned char *output;
+    size_t output_len;
+} PKEY_KDF_DATA;
+
+/*
+ * Perform public key operation setup: lookup key, allocated ctx and call
+ * the appropriate initialisation function
+ */
+static int pkey_kdf_test_init(EVP_TEST *t, const char *name)
+{
+    PKEY_KDF_DATA *kdata;
+    int kdf_nid = OBJ_sn2nid(name);
+
+#ifdef OPENSSL_NO_SCRYPT
+    if (strcmp(name, "scrypt") == 0) {
+        t->skip = 1;
+        return 1;
+    }
+#endif
+
+    if (kdf_nid == NID_undef)
+        kdf_nid = OBJ_ln2nid(name);
+
+    if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata))))
+        return 0;
+    kdata->ctx = EVP_PKEY_CTX_new_id(kdf_nid, NULL);
+    if (kdata->ctx == NULL) {
+        OPENSSL_free(kdata);
+        return 0;
+    }
+    if (EVP_PKEY_derive_init(kdata->ctx) <= 0) {
+        EVP_PKEY_CTX_free(kdata->ctx);
+        OPENSSL_free(kdata);
+        return 0;
+    }
+    t->data = kdata;
+    return 1;
+}
+
+static void pkey_kdf_test_cleanup(EVP_TEST *t)
+{
+    PKEY_KDF_DATA *kdata = t->data;
+    OPENSSL_free(kdata->output);
+    EVP_PKEY_CTX_free(kdata->ctx);
+}
+
+static int pkey_kdf_test_parse(EVP_TEST *t,
+                               const char *keyword, const char *value)
+{
+    PKEY_KDF_DATA *kdata = t->data;
+
+    if (strcmp(keyword, "Output") == 0)
+        return parse_bin(value, &kdata->output, &kdata->output_len);
+    if (strncmp(keyword, "Ctrl", 4) == 0)
+        return pkey_test_ctrl(t, kdata->ctx, value);
+    return 0;
+}
+
+static int pkey_kdf_test_run(EVP_TEST *t)
+{
+    PKEY_KDF_DATA *expected = t->data;
+    unsigned char *got = NULL;
+    size_t got_len = expected->output_len;
+
+    if (!TEST_ptr(got = OPENSSL_malloc(got_len))) {
+        t->err = "INTERNAL_ERROR";
+        goto err;
+    }
+    if (EVP_PKEY_derive(expected->ctx, got, &got_len) <= 0) {
+        t->err = "KDF_DERIVE_ERROR";
+        goto err;
+    }
+    if (!TEST_mem_eq(expected->output, expected->output_len, got, got_len)) {
+        t->err = "KDF_MISMATCH";
+        goto err;
+    }
+    t->err = NULL;
+
+ err:
+    OPENSSL_free(got);
+    return 1;
+}
+
+static const EVP_TEST_METHOD pkey_kdf_test_method = {
+    "PKEYKDF",
+    pkey_kdf_test_init,
+    pkey_kdf_test_cleanup,
+    pkey_kdf_test_parse,
+    pkey_kdf_test_run
+};
+
+
 /**
 ***  KEYPAIR TESTS
 **/
@@ -2497,6 +2666,7 @@ static const EVP_TEST_METHOD *evp_test_list[] = {
     &digestverify_test_method,
     &encode_test_method,
     &kdf_test_method,
+    &pkey_kdf_test_method,
     &keypair_test_method,
     &keygen_test_method,
     &mac_test_method,