+
+/* PBE tests */
+
+#define PBE_TYPE_SCRYPT 1
+
+struct pbe_data {
+
+ int pbe_type;
+
+ /* scrypt parameters */
+ uint64_t N, r, p, maxmem;
+
+ /* password */
+ unsigned char *pass;
+ size_t pass_len;
+
+ /* salt */
+ unsigned char *salt;
+ size_t salt_len;
+
+ /* Expected output */
+ unsigned char *key;
+ size_t key_len;
+};
+
+static int scrypt_test_parse(struct evp_test *t,
+ const char *keyword, const char *value)
+{
+ struct pbe_data *pdata = t->data;
+ if (strcmp(keyword, "N") == 0)
+ return test_uint64(value, &pdata->N);
+ if (strcmp(keyword, "p") == 0)
+ return test_uint64(value, &pdata->p);
+ if (strcmp(keyword, "r") == 0)
+ return test_uint64(value, &pdata->r);
+ if (strcmp(keyword, "maxmem") == 0)
+ return test_uint64(value, &pdata->maxmem);
+ return 0;
+}
+
+static int scrypt_test_run(struct evp_test *t)
+{
+ struct pbe_data *pdata = t->data;
+ const char *err = "INTERNAL_ERROR";
+ unsigned char *key;
+ key = OPENSSL_malloc(pdata->key_len);
+ if (!key)
+ goto err;
+ err = "SCRYPT_ERROR";
+ if (EVP_PBE_scrypt((const char *)pdata->pass, pdata->pass_len,
+ pdata->salt, pdata->salt_len,
+ pdata->N, pdata->r, pdata->p, pdata->maxmem,
+ key, pdata->key_len) == 0)
+ goto err;
+ err = "KEY_MISMATCH";
+ if (check_output(t, pdata->key, key, pdata->key_len))
+ goto err;
+ err = NULL;
+ err:
+ OPENSSL_free(key);
+ t->err = err;
+ return 1;
+}
+
+static int pbe_test_init(struct evp_test *t, const char *alg)
+{
+ struct pbe_data *pdat;
+ int pbe_type = 0;
+ if (strcmp(alg, "scrypt") == 0)
+ pbe_type = PBE_TYPE_SCRYPT;
+ else
+ fprintf(stderr, "Unknown pbe algorithm %s\n", alg);
+ pdat = OPENSSL_malloc(sizeof(*pdat));
+ pdat->pbe_type = pbe_type;
+ pdat->pass = NULL;
+ pdat->salt = NULL;
+ pdat->N = 0;
+ pdat->r = 0;
+ pdat->p = 0;
+ pdat->maxmem = 0;
+ t->data = pdat;
+ return 1;
+}
+
+static void pbe_test_cleanup(struct evp_test *t)
+{
+ struct pbe_data *pdat = t->data;
+ test_free(pdat->pass);
+ test_free(pdat->salt);
+ test_free(pdat->key);
+}
+
+static int pbe_test_parse(struct evp_test *t,
+ const char *keyword, const char *value)
+{
+ struct pbe_data *pdata = t->data;
+ if (strcmp(keyword, "Password") == 0)
+ return test_bin(value, &pdata->pass, &pdata->pass_len);
+ if (strcmp(keyword, "Salt") == 0)
+ return test_bin(value, &pdata->salt, &pdata->salt_len);
+ if (strcmp(keyword, "Key") == 0)
+ return test_bin(value, &pdata->key, &pdata->key_len);
+ if (pdata->pbe_type == PBE_TYPE_SCRYPT)
+ return scrypt_test_parse(t, keyword, value);
+ return 0;
+}
+
+static int pbe_test_run(struct evp_test *t)
+{
+ struct pbe_data *pdata = t->data;
+ if (pdata->pbe_type == PBE_TYPE_SCRYPT)
+ return scrypt_test_run(t);
+ return 0;
+}
+
+static const struct evp_test_method pbe_test_method = {
+ "PBE",
+ pbe_test_init,
+ pbe_test_cleanup,
+ pbe_test_parse,
+ pbe_test_run
+};