if (params == NULL)
return NULL;
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
- digest, 0);
+ if (digest != NULL)
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ digest, 0);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
salt, strlen(salt));
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
(unsigned char *)key, keylen);
- *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
- info, strlen(info));
+ if (info != NULL)
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
+ info, strlen(info));
+ else
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
+ "EXTRACT_ONLY", 0);
*p = OSSL_PARAM_construct_end();
return params;
return ret;
}
+static int do_kdf_hkdf_gettables(int expand_only, int has_digest)
+{
+ int ret = 0;
+ size_t sz = 0;
+ OSSL_PARAM *params;
+ OSSL_PARAM params_get[2];
+ const OSSL_PARAM *gettables, *p;
+ EVP_KDF_CTX *kctx = NULL;
+
+ if (!TEST_ptr(params = construct_hkdf_params(
+ has_digest ? "sha256" : NULL,
+ "secret", 6, "salt",
+ expand_only ? NULL : "label"))
+ || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
+ || !TEST_true(EVP_KDF_CTX_set_params(kctx, params)))
+ goto err;
+
+ /* Check OSSL_KDF_PARAM_SIZE is gettable */
+ if (!TEST_ptr(gettables = EVP_KDF_CTX_gettable_params(kctx))
+ || !TEST_ptr(p = OSSL_PARAM_locate_const(gettables, OSSL_KDF_PARAM_SIZE)))
+ goto err;
+
+ /* Get OSSL_KDF_PARAM_SIZE as a size_t */
+ params_get[0] = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &sz);
+ params_get[1] = OSSL_PARAM_construct_end();
+ if (has_digest) {
+ if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), 1)
+ || !TEST_size_t_eq(sz, expand_only ? SHA256_DIGEST_LENGTH : SIZE_MAX))
+ goto err;
+ } else {
+ if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), 0))
+ goto err;
+ }
+
+ /* Get params returns -2 if an unsupported parameter is requested */
+ params_get[0] = OSSL_PARAM_construct_end();
+ if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), -2))
+ goto err;
+ ret = 1;
+err:
+ EVP_KDF_CTX_free(kctx);
+ OPENSSL_free(params);
+ return ret;
+}
+
+static int test_kdf_hkdf_gettables(void)
+{
+ return do_kdf_hkdf_gettables(0, 1);
+}
+
+static int test_kdf_hkdf_gettables_expandonly(void)
+{
+ return do_kdf_hkdf_gettables(1, 1);
+}
+
+static int test_kdf_hkdf_gettables_no_digest(void)
+{
+ return do_kdf_hkdf_gettables(1, 0);
+}
+
static int test_kdf_hkdf_invalid_digest(void)
{
int ret;
return ret;
}
+static int test_kdf_hkdf_derive_set_params_fail(void)
+{
+ int ret = 0, i = 0;
+ EVP_KDF_CTX *kctx = NULL;
+ OSSL_PARAM params[2];
+ unsigned char out[10];
+
+ if (!TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF)))
+ goto end;
+ /*
+ * Set the wrong type for the digest so that it causes a failure
+ * inside kdf_hkdf_derive() when kdf_hkdf_set_ctx_params() is called
+ */
+ params[0] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_DIGEST, &i);
+ params[1] = OSSL_PARAM_construct_end();
+ if (!TEST_int_eq(EVP_KDF_derive(kctx, out, sizeof(out), params), 0))
+ goto end;
+ ret = 1;
+end:
+ EVP_KDF_CTX_free(kctx);
+ return ret;
+}
+
+static int test_kdf_hkdf_set_invalid_mode(void)
+{
+ int ret = 0, bad_mode = 100;
+ EVP_KDF_CTX *kctx = NULL;
+ OSSL_PARAM params[2];
+
+ if (!TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF)))
+ goto end;
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
+ "BADMODE", 0);
+ params[1] = OSSL_PARAM_construct_end();
+ if (!TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 0))
+ goto end;
+
+ params[0] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &bad_mode);
+ if (!TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 0))
+ goto end;
+
+ ret = 1;
+end:
+ EVP_KDF_CTX_free(kctx);
+ return ret;
+}
+
+static int do_kdf_hkdf_set_invalid_param(const char *key, int type)
+{
+ int ret = 0;
+ EVP_KDF_CTX *kctx = NULL;
+ OSSL_PARAM params[2];
+ unsigned char buf[2];
+
+ if (!TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF)))
+ goto end;
+ /* Set the wrong type for the key so that it causes a failure */
+ if (type == OSSL_PARAM_UTF8_STRING)
+ params[0] = OSSL_PARAM_construct_utf8_string(key, "BAD", 0);
+ else
+ params[0] = OSSL_PARAM_construct_octet_string(key, buf, sizeof(buf));
+ params[1] = OSSL_PARAM_construct_end();
+ if (!TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 0))
+ goto end;
+
+ ret = 1;
+end:
+ EVP_KDF_CTX_free(kctx);
+ return ret;
+}
+
+static int test_kdf_hkdf_set_ctx_param_fail(void)
+{
+ return do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_MODE,
+ OSSL_PARAM_OCTET_STRING)
+ && do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_KEY,
+ OSSL_PARAM_UTF8_STRING)
+ && do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_SALT,
+ OSSL_PARAM_UTF8_STRING)
+ && do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_INFO,
+ OSSL_PARAM_UTF8_STRING);
+}
+
static int test_kdf_hkdf_zero_output_size(void)
{
int ret;
/* PBKDF1 only available in the legacy provider */
prov = OSSL_PROVIDER_load(libctx, "legacy");
- if (prov == NULL)
+ if (prov == NULL) {
+ OSSL_LIB_CTX_free(libctx);
return TEST_skip("PBKDF1 only available in legacy provider");
+ }
params = construct_pbkdf1_params("passwordPASSWORDpassword", "sha256",
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
ADD_TEST(test_kdf_hkdf_empty_key);
ADD_TEST(test_kdf_hkdf_1byte_key);
ADD_TEST(test_kdf_hkdf_empty_salt);
+ ADD_TEST(test_kdf_hkdf_gettables);
+ ADD_TEST(test_kdf_hkdf_gettables_expandonly);
+ ADD_TEST(test_kdf_hkdf_gettables_no_digest);
+ ADD_TEST(test_kdf_hkdf_derive_set_params_fail);
+ ADD_TEST(test_kdf_hkdf_set_invalid_mode);
+ ADD_TEST(test_kdf_hkdf_set_ctx_param_fail);
ADD_TEST(test_kdf_pbkdf2);
ADD_TEST(test_kdf_pbkdf2_small_output);
ADD_TEST(test_kdf_pbkdf2_large_output);