typedef struct digest_data_st {
/* Digest this test is for */
const EVP_MD *digest;
+ EVP_MD *fetched_digest;
/* Input to digest */
STACK_OF(EVP_TEST_BUFFER) *input;
/* Expected output */
unsigned char *output;
size_t output_len;
+ /* Padding type */
+ int pad_type;
} DIGEST_DATA;
static int digest_test_init(EVP_TEST *t, const char *alg)
{
DIGEST_DATA *mdat;
const EVP_MD *digest;
+ EVP_MD *fetched_digest;
- if ((digest = EVP_get_digestbyname(alg)) == NULL) {
+ if ((digest = fetched_digest = EVP_MD_fetch(NULL, alg, NULL)) == NULL
+ && (digest = EVP_get_digestbyname(alg)) == NULL) {
/* If alg has an OID assume disabled algorithm */
if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
t->skip = 1;
return 0;
t->data = mdat;
mdat->digest = digest;
+ mdat->fetched_digest = fetched_digest;
+ mdat->pad_type = 0;
+ if (fetched_digest != NULL)
+ TEST_info("%s is fetched", alg);
return 1;
}
sk_EVP_TEST_BUFFER_pop_free(mdat->input, evp_test_buffer_free);
OPENSSL_free(mdat->output);
+ EVP_MD_meth_free(mdat->fetched_digest);
}
static int digest_test_parse(EVP_TEST *t,
return evp_test_buffer_set_count(value, mdata->input);
if (strcmp(keyword, "Ncopy") == 0)
return evp_test_buffer_ncopy(value, mdata->input);
+ if (strcmp(keyword, "Padding") == 0)
+ return (mdata->pad_type = atoi(value)) > 0;
return 0;
}
EVP_MD_CTX *mctx;
unsigned char *got = NULL;
unsigned int got_len;
+ OSSL_PARAM params[2];
t->err = "TEST_FAILURE";
if (!TEST_ptr(mctx = EVP_MD_CTX_new()))
t->err = "DIGESTINIT_ERROR";
goto err;
}
+ if (expected->pad_type > 0) {
+ params[0] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_PAD_TYPE,
+ &expected->pad_type);
+ params[1] = OSSL_PARAM_construct_end();
+ if (!TEST_int_gt(EVP_MD_CTX_set_params(mctx, params), 0)) {
+ t->err = "PARAMS_ERROR";
+ goto err;
+ }
+ }
if (!evp_test_buffer_do(expected->input, digest_update_fn, mctx)) {
t->err = "DIGESTUPDATE_ERROR";
goto err;
typedef struct cipher_data_st {
const EVP_CIPHER *cipher;
+ EVP_CIPHER *fetched_cipher;
int enc;
/* EVP_CIPH_GCM_MODE, EVP_CIPH_CCM_MODE or EVP_CIPH_OCB_MODE if AEAD */
int aead;
unsigned char *key;
size_t key_len;
+ size_t key_bits; /* Used by RC2 */
unsigned char *iv;
+ unsigned int rounds;
size_t iv_len;
unsigned char *plaintext;
size_t plaintext_len;
static int cipher_test_init(EVP_TEST *t, const char *alg)
{
const EVP_CIPHER *cipher;
+ EVP_CIPHER *fetched_cipher;
CIPHER_DATA *cdat;
int m;
- if ((cipher = EVP_get_cipherbyname(alg)) == NULL) {
+ if ((cipher = fetched_cipher = EVP_CIPHER_fetch(NULL, alg, NULL)) == NULL
+ && (cipher = EVP_get_cipherbyname(alg)) == NULL) {
/* If alg has an OID assume disabled algorithm */
if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
t->skip = 1;
}
cdat = OPENSSL_zalloc(sizeof(*cdat));
cdat->cipher = cipher;
+ cdat->fetched_cipher = fetched_cipher;
cdat->enc = -1;
m = EVP_CIPHER_mode(cipher);
if (m == EVP_CIPH_GCM_MODE
cdat->aead = 0;
t->data = cdat;
+ if (fetched_cipher != NULL)
+ TEST_info("%s is fetched", alg);
return 1;
}
for (i = 0; i < AAD_NUM; i++)
OPENSSL_free(cdat->aad[i]);
OPENSSL_free(cdat->tag);
+ EVP_CIPHER_meth_free(cdat->fetched_cipher);
}
static int cipher_test_parse(EVP_TEST *t, const char *keyword,
if (strcmp(keyword, "Key") == 0)
return parse_bin(value, &cdat->key, &cdat->key_len);
+ if (strcmp(keyword, "Rounds") == 0) {
+ i = atoi(value);
+ if (i < 0)
+ return -1;
+ cdat->rounds = (unsigned int)i;
+ return 1;
+ }
if (strcmp(keyword, "IV") == 0)
return parse_bin(value, &cdat->iv, &cdat->iv_len);
if (strcmp(keyword, "Plaintext") == 0)
return parse_bin(value, &cdat->plaintext, &cdat->plaintext_len);
if (strcmp(keyword, "Ciphertext") == 0)
return parse_bin(value, &cdat->ciphertext, &cdat->ciphertext_len);
+ if (strcmp(keyword, "KeyBits") == 0) {
+ i = atoi(value);
+ if (i < 0)
+ return -1;
+ cdat->key_bits = (size_t)i;
+ return 1;
+ }
if (cdat->aead) {
if (strcmp(keyword, "AAD") == 0) {
for (i = 0; i < AAD_NUM; i++) {
unsigned char *in, *expected_out, *tmp = NULL;
size_t in_len, out_len, donelen = 0;
int ok = 0, tmplen, chunklen, tmpflen, i;
+ EVP_CIPHER_CTX *ctx_base = NULL;
EVP_CIPHER_CTX *ctx = NULL;
t->err = "TEST_FAILURE";
+ if (!TEST_ptr(ctx_base = EVP_CIPHER_CTX_new()))
+ goto err;
if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()))
goto err;
- EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+ EVP_CIPHER_CTX_set_flags(ctx_base, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
if (enc) {
in = expected->plaintext;
in_len = expected->plaintext_len;
in = memcpy(tmp + out_misalign + in_len + 2 * EVP_MAX_BLOCK_LENGTH +
inp_misalign, in, in_len);
}
- if (!EVP_CipherInit_ex(ctx, expected->cipher, NULL, NULL, NULL, enc)) {
+ if (!EVP_CipherInit_ex(ctx_base, expected->cipher, NULL, NULL, NULL, enc)) {
t->err = "CIPHERINIT_ERROR";
goto err;
}
if (expected->iv) {
if (expected->aead) {
- if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
+ if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_AEAD_SET_IVLEN,
expected->iv_len, 0)) {
t->err = "INVALID_IV_LENGTH";
goto err;
}
- } else if (expected->iv_len != (size_t)EVP_CIPHER_CTX_iv_length(ctx)) {
+ } else if (expected->iv_len != (size_t)EVP_CIPHER_CTX_iv_length(ctx_base)) {
t->err = "INVALID_IV_LENGTH";
goto err;
}
tag = expected->tag;
}
if (tag || expected->aead != EVP_CIPH_GCM_MODE) {
- if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
+ if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_AEAD_SET_TAG,
expected->tag_len, tag))
goto err;
}
}
- if (!EVP_CIPHER_CTX_set_key_length(ctx, expected->key_len)) {
+ if (expected->rounds > 0) {
+ int rounds = (int)expected->rounds;
+
+ if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_SET_RC5_ROUNDS, rounds, NULL)) {
+ t->err = "INVALID_ROUNDS";
+ goto err;
+ }
+ }
+
+ if (!EVP_CIPHER_CTX_set_key_length(ctx_base, expected->key_len)) {
t->err = "INVALID_KEY_LENGTH";
goto err;
}
- if (!EVP_CipherInit_ex(ctx, NULL, NULL, expected->key, expected->iv, -1)) {
+ if (expected->key_bits > 0) {
+ int bits = (int)expected->key_bits;
+
+ if (!EVP_CIPHER_CTX_ctrl(ctx_base, EVP_CTRL_SET_RC2_KEY_BITS, bits, NULL)) {
+ t->err = "INVALID KEY BITS";
+ goto err;
+ }
+ }
+ if (!EVP_CipherInit_ex(ctx_base, NULL, NULL, expected->key, expected->iv, -1)) {
t->err = "KEY_SET_ERROR";
goto err;
}
+
/* Check that we get the same IV back */
if (expected->iv != NULL
&& (EVP_CIPHER_flags(expected->cipher) & EVP_CIPH_CUSTOM_IV) == 0
&& !TEST_mem_eq(expected->iv, expected->iv_len,
- EVP_CIPHER_CTX_iv(ctx), expected->iv_len)) {
+ EVP_CIPHER_CTX_iv(ctx_base), expected->iv_len)) {
t->err = "INVALID_IV";
goto err;
}
+ /* Test that the cipher dup functions correctly if it is supported */
+ if (EVP_CIPHER_CTX_copy(ctx, ctx_base)) {
+ EVP_CIPHER_CTX_free(ctx_base);
+ ctx_base = NULL;
+ } else {
+ EVP_CIPHER_CTX_free(ctx);
+ ctx = ctx_base;
+ }
+
if (expected->aead == EVP_CIPH_CCM_MODE) {
if (!EVP_CipherUpdate(ctx, NULL, &tmplen, NULL, out_len)) {
t->err = "CCM_PLAINTEXT_LENGTH_SET_ERROR";
ok = 1;
err:
OPENSSL_free(tmp);
+ if (ctx != ctx_base)
+ EVP_CIPHER_CTX_free(ctx_base);
EVP_CIPHER_CTX_free(ctx);
return ok;
}
typedef struct mac_data_st {
/* MAC type in one form or another */
+ char *mac_name;
EVP_MAC *mac; /* for mac_test_run_mac */
int type; /* for mac_test_run_pkey */
/* Algorithm string for this MAC */
mdat = OPENSSL_zalloc(sizeof(*mdat));
mdat->type = type;
+ mdat->mac_name = OPENSSL_strdup(alg);
mdat->mac = mac;
mdat->controls = sk_OPENSSL_STRING_new_null();
t->data = mdat;
MAC_DATA *mdat = t->data;
EVP_MAC_free(mdat->mac);
+ OPENSSL_free(mdat->mac_name);
sk_OPENSSL_STRING_pop_free(mdat->controls, openssl_free);
OPENSSL_free(mdat->alg);
OPENSSL_free(mdat->key);
size_t params_n = 0;
size_t params_n_allocstart = 0;
const OSSL_PARAM *defined_params =
- EVP_MAC_CTX_settable_params(expected->mac);
+ EVP_MAC_settable_ctx_params(expected->mac);
if (expected->alg == NULL)
- TEST_info("Trying the EVP_MAC %s test", EVP_MAC_name(expected->mac));
+ TEST_info("Trying the EVP_MAC %s test", expected->mac_name);
else
TEST_info("Trying the EVP_MAC %s test with %s",
- EVP_MAC_name(expected->mac), expected->alg);
+ expected->mac_name, expected->alg);
#ifdef OPENSSL_NO_DES
if (expected->alg != NULL && strstr(expected->alg, "DES") != NULL) {
EVP_KDF *kdf;
#ifdef OPENSSL_NO_SCRYPT
- if (strcmp(name, "scrypt") == 0) {
+ /* TODO(3.0) Replace with "scrypt" once aliases are supported */
+ if (strcmp(name, "id-scrypt") == 0) {
t->skip = 1;
return 1;
}
KDF_DATA *kdata = t->data;
int rv;
char *p, *name;
- const OSSL_PARAM *defs = EVP_KDF_CTX_settable_params(EVP_KDF_CTX_kdf(kctx));
+ const OSSL_PARAM *defs = EVP_KDF_settable_ctx_params(EVP_KDF_CTX_kdf(kctx));
if (!TEST_ptr(name = OPENSSL_strdup(value)))
return 0;
if (p != NULL)
*p++ = '\0';
- rv = OSSL_PARAM_allocate_from_text(kdata->p, defs, name, p, strlen(p));
+ rv = OSSL_PARAM_allocate_from_text(kdata->p, defs, name, p,
+ p != NULL ? strlen(p) : 0);
*++kdata->p = OSSL_PARAM_construct_end();
if (!rv) {
t->err = "KDF_PARAM_ERROR";
OPENSSL_free(name);
return 0;
}
- if (strcmp(name, "digest") == 0 && p != NULL) {
+ if (p != NULL && strcmp(name, "digest") == 0) {
/* If p has an OID and lookup fails assume disabled algorithm */
int nid = OBJ_sn2nid(p);
if (nid != NID_undef && EVP_get_digestbynid(nid) == NULL)
t->skip = 1;
}
+ if (p != NULL && strcmp(name, "cipher") == 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_cipherbynid(nid) == NULL)
+ t->skip = 1;
+ }
OPENSSL_free(name);
return 1;
}
static int check_test_error(EVP_TEST *t)
{
unsigned long err;
- const char *func;
const char *reason;
if (t->err == NULL && t->expected_err == NULL)
return 0;
}
- func = ERR_func_error_string(err);
reason = ERR_reason_error_string(err);
- if (func == NULL && reason == NULL) {
+ if (reason == NULL) {
TEST_info("%s:%d: Expected error \"%s\", no strings available."
" Assuming ok.",
t->s.test_file, t->s.start, t->reason);
if (!TEST_ptr(key = OPENSSL_malloc(sizeof(*key))))
return 0;
key->name = take_value(pp);
-
- /* Hack to detect SM2 keys */
- if(pkey != NULL && strstr(key->name, "SM2") != NULL) {
-#ifdef OPENSSL_NO_SM2
- EVP_PKEY_free(pkey);
- pkey = NULL;
-#else
- EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
-#endif
- }
-
key->key = pkey;
key->next = *klist;
*klist = key;
int setup_tests(void)
{
- size_t n = test_get_argument_count();
+ size_t n;
+
+ if (!test_skip_common_options()) {
+ TEST_error("Error parsing test options\n");
+ return 0;
+ }
+ n = test_get_argument_count();
if (n == 0)
return 0;