X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=test%2Fevp_test.c;h=83b92a4166efc1394838ffbe4463af720231a64d;hb=9e5f344a87f08ee2f3886fbccba1957bca86e7ef;hp=67a818d98d6d6230a7c0a4fc88f605d5c119ea18;hpb=64da55a64f141bb068f034ab0df34ec2a044e482;p=openssl.git diff --git a/test/evp_test.c b/test/evp_test.c index 67a818d98d..83b92a4166 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,6 +25,8 @@ #include "testutil.h" #include "evp_test.h" +DEFINE_STACK_OF_STRING() + #define AAD_NUM 4 typedef struct evp_test_method_st EVP_TEST_METHOD; @@ -325,19 +327,24 @@ static int parse_bin(const char *value, unsigned char **buf, size_t *buflen) 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; @@ -349,6 +356,10 @@ static int digest_test_init(EVP_TEST *t, const char *alg) 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; } @@ -358,6 +369,7 @@ static void digest_test_cleanup(EVP_TEST *t) sk_EVP_TEST_BUFFER_pop_free(mdat->input, evp_test_buffer_free); OPENSSL_free(mdat->output); + EVP_MD_free(mdat->fetched_digest); } static int digest_test_parse(EVP_TEST *t, @@ -373,6 +385,8 @@ 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; } @@ -387,6 +401,7 @@ static int digest_test_run(EVP_TEST *t) 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())) @@ -401,6 +416,15 @@ static int digest_test_run(EVP_TEST *t) 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; @@ -472,12 +496,15 @@ static const EVP_TEST_METHOD digest_test_method = { 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; @@ -487,6 +514,7 @@ typedef struct cipher_data_st { unsigned char *aad[AAD_NUM]; size_t aad_len[AAD_NUM]; unsigned char *tag; + const char *cts_mode; size_t tag_len; int tag_late; } CIPHER_DATA; @@ -494,10 +522,12 @@ typedef struct cipher_data_st { 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; @@ -507,6 +537,7 @@ static int cipher_test_init(EVP_TEST *t, const char *alg) } 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 @@ -520,6 +551,8 @@ static int cipher_test_init(EVP_TEST *t, const char *alg) cdat->aead = 0; t->data = cdat; + if (fetched_cipher != NULL) + TEST_info("%s is fetched", alg); return 1; } @@ -535,6 +568,7 @@ static void cipher_test_cleanup(EVP_TEST *t) for (i = 0; i < AAD_NUM; i++) OPENSSL_free(cdat->aad[i]); OPENSSL_free(cdat->tag); + EVP_CIPHER_free(cdat->fetched_cipher); } static int cipher_test_parse(EVP_TEST *t, const char *keyword, @@ -545,12 +579,26 @@ 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++) { @@ -581,6 +629,10 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword, return -1; return 1; } + if (strcmp(keyword, "CTSMode") == 0) { + cdat->cts_mode = value; + return 1; + } return 0; } @@ -591,12 +643,15 @@ static int cipher_test_enc(EVP_TEST *t, int enc, 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; @@ -633,18 +688,30 @@ static int cipher_test_enc(EVP_TEST *t, int enc, 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->cts_mode != NULL) { + OSSL_PARAM params[2]; + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, + (char *)expected->cts_mode, + 0); + params[1] = OSSL_PARAM_construct_end(); + if (!EVP_CIPHER_CTX_set_params(ctx_base, params)) { + t->err = "INVALID_CTS_MODE"; + 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; } @@ -663,29 +730,56 @@ static int cipher_test_enc(EVP_TEST *t, int enc, 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"; @@ -792,6 +886,8 @@ static int cipher_test_enc(EVP_TEST *t, int enc, ok = 1; err: OPENSSL_free(tmp); + if (ctx != ctx_base) + EVP_CIPHER_CTX_free(ctx_base); EVP_CIPHER_CTX_free(ctx); return ok; } @@ -860,6 +956,7 @@ static int cipher_test_run(EVP_TEST *t) * lengths so we don't fragment for those */ if (cdat->aead == EVP_CIPH_CCM_MODE + || ((EVP_CIPHER_flags(cdat->cipher) & EVP_CIPH_FLAG_CTS) != 0) || EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_SIV_MODE || EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_XTS_MODE || EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE) @@ -890,6 +987,7 @@ static const EVP_TEST_METHOD cipher_test_method = { 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 */ @@ -973,6 +1071,7 @@ static int mac_test_init(EVP_TEST *t, const char *alg) 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; @@ -990,6 +1089,7 @@ static void mac_test_cleanup(EVP_TEST *t) 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); @@ -1147,13 +1247,13 @@ static int mac_test_run_mac(EVP_TEST *t) 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) { @@ -1230,7 +1330,7 @@ static int mac_test_run_mac(EVP_TEST *t) || !OSSL_PARAM_allocate_from_text(¶ms[params_n], defined_params, tmpkey, tmpval, - strlen(tmpval))) { + strlen(tmpval), NULL)) { OPENSSL_free(tmpkey); t->err = "MAC_PARAM_ERROR"; goto err; @@ -1965,6 +2065,291 @@ static const EVP_TEST_METHOD encode_test_method = { }; +/** +*** RAND TESTS +**/ + +#define MAX_RAND_REPEATS 15 + +typedef struct rand_data_pass_st { + unsigned char *entropy; + unsigned char *reseed_entropy; + unsigned char *nonce; + unsigned char *pers; + unsigned char *reseed_addin; + unsigned char *addinA; + unsigned char *addinB; + unsigned char *pr_entropyA; + unsigned char *pr_entropyB; + unsigned char *output; + size_t entropy_len, nonce_len, pers_len, addinA_len, addinB_len, + pr_entropyA_len, pr_entropyB_len, output_len, reseed_entropy_len, + reseed_addin_len; +} RAND_DATA_PASS; + +typedef struct rand_data_st { + /* Context for this operation */ + EVP_RAND_CTX *ctx; + EVP_RAND_CTX *parent; + int n; + int prediction_resistance; + int use_df; + unsigned int generate_bits; + char *cipher; + char *digest; + + /* Expected output */ + RAND_DATA_PASS data[MAX_RAND_REPEATS]; +} RAND_DATA; + +static int rand_test_init(EVP_TEST *t, const char *name) +{ + RAND_DATA *rdata; + EVP_RAND *rand; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + unsigned int strength = 256; + + if (!TEST_ptr(rdata = OPENSSL_zalloc(sizeof(*rdata)))) + return 0; + + rand = EVP_RAND_fetch(NULL, "TEST-RAND", NULL); + if (rand == NULL) + goto err; + rdata->parent = EVP_RAND_CTX_new(rand, NULL); + EVP_RAND_free(rand); + if (rdata->parent == NULL) + goto err; + + *params = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength); + if (!EVP_RAND_set_ctx_params(rdata->parent, params)) + goto err; + + rand = EVP_RAND_fetch(NULL, name, NULL); + if (rand == NULL) + goto err; + rdata->ctx = EVP_RAND_CTX_new(rand, rdata->parent); + EVP_RAND_free(rand); + if (rdata->ctx == NULL) + goto err; + + rdata->n = -1; + t->data = rdata; + return 1; + err: + EVP_RAND_CTX_free(rdata->parent); + OPENSSL_free(rdata); + return 0; +} + +static void rand_test_cleanup(EVP_TEST *t) +{ + RAND_DATA *rdata = t->data; + int i; + + OPENSSL_free(rdata->cipher); + OPENSSL_free(rdata->digest); + + for (i = 0; i <= rdata->n; i++) { + OPENSSL_free(rdata->data[i].entropy); + OPENSSL_free(rdata->data[i].reseed_entropy); + OPENSSL_free(rdata->data[i].nonce); + OPENSSL_free(rdata->data[i].pers); + OPENSSL_free(rdata->data[i].reseed_addin); + OPENSSL_free(rdata->data[i].addinA); + OPENSSL_free(rdata->data[i].addinB); + OPENSSL_free(rdata->data[i].pr_entropyA); + OPENSSL_free(rdata->data[i].pr_entropyB); + OPENSSL_free(rdata->data[i].output); + } + EVP_RAND_CTX_free(rdata->ctx); + EVP_RAND_CTX_free(rdata->parent); +} + +static int rand_test_parse(EVP_TEST *t, + const char *keyword, const char *value) +{ + RAND_DATA *rdata = t->data; + RAND_DATA_PASS *item; + const char *p; + int n; + + if ((p = strchr(keyword, '.')) != NULL) { + n = atoi(++p); + if (n >= MAX_RAND_REPEATS) + return 0; + if (n > rdata->n) + rdata->n = n; + item = rdata->data + n; + if (strncmp(keyword, "Entropy.", sizeof("Entropy")) == 0) + return parse_bin(value, &item->entropy, &item->entropy_len); + if (strncmp(keyword, "ReseedEntropy.", sizeof("ReseedEntropy")) == 0) + return parse_bin(value, &item->reseed_entropy, + &item->reseed_entropy_len); + if (strncmp(keyword, "Nonce.", sizeof("Nonce")) == 0) + return parse_bin(value, &item->nonce, &item->nonce_len); + if (strncmp(keyword, "PersonalisationString.", + sizeof("PersonalisationString")) == 0) + return parse_bin(value, &item->pers, &item->pers_len); + if (strncmp(keyword, "ReseedAdditionalInput.", + sizeof("ReseedAdditionalInput")) == 0) + return parse_bin(value, &item->reseed_addin, + &item->reseed_addin_len); + if (strncmp(keyword, "AdditionalInputA.", + sizeof("AdditionalInputA")) == 0) + return parse_bin(value, &item->addinA, &item->addinA_len); + if (strncmp(keyword, "AdditionalInputB.", + sizeof("AdditionalInputB")) == 0) + return parse_bin(value, &item->addinB, &item->addinB_len); + if (strncmp(keyword, "EntropyPredictionResistanceA.", + sizeof("EntropyPredictionResistanceA")) == 0) + return parse_bin(value, &item->pr_entropyA, &item->pr_entropyA_len); + if (strncmp(keyword, "EntropyPredictionResistanceB.", + sizeof("EntropyPredictionResistanceB")) == 0) + return parse_bin(value, &item->pr_entropyB, &item->pr_entropyB_len); + if (strncmp(keyword, "Output.", sizeof("Output")) == 0) + return parse_bin(value, &item->output, &item->output_len); + } else { + if (strcmp(keyword, "Cipher") == 0) + return TEST_ptr(rdata->cipher = OPENSSL_strdup(value)); + if (strcmp(keyword, "Digest") == 0) + return TEST_ptr(rdata->digest = OPENSSL_strdup(value)); + if (strcmp(keyword, "DerivationFunction") == 0) { + rdata->use_df = atoi(value) != 0; + return 1; + } + if (strcmp(keyword, "GenerateBits") == 0) { + if ((n = atoi(value)) <= 0 || n % 8 != 0) + return 0; + rdata->generate_bits = (unsigned int)n; + return 1; + } + if (strcmp(keyword, "PredictionResistance") == 0) { + rdata->prediction_resistance = atoi(value) != 0; + return 1; + } + } + return 0; +} + +static int rand_test_run(EVP_TEST *t) +{ + RAND_DATA *expected = t->data; + RAND_DATA_PASS *item; + unsigned char *got; + size_t got_len = expected->generate_bits / 8; + OSSL_PARAM params[5], *p = params; + int i = -1, ret = 0; + unsigned int strength; + unsigned char *z; + + if (!TEST_ptr(got = OPENSSL_malloc(got_len))) + return 0; + + *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF, &expected->use_df); + if (expected->cipher != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, + expected->cipher, 0); + if (expected->digest != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, + expected->digest, 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_MAC, "HMAC", 0); + *p = OSSL_PARAM_construct_end(); + if (!TEST_true(EVP_RAND_set_ctx_params(expected->ctx, params))) + goto err; + + strength = EVP_RAND_strength(expected->ctx); + for (i = 0; i <= expected->n; i++) { + item = expected->data + i; + + p = params; + z = item->entropy != NULL ? item->entropy : (unsigned char *)""; + *p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, + z, item->entropy_len); + z = item->nonce != NULL ? item->nonce : (unsigned char *)""; + *p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE, + z, item->nonce_len); + *p = OSSL_PARAM_construct_end(); + if (!TEST_true(EVP_RAND_set_ctx_params(expected->parent, params)) + || !TEST_true(EVP_RAND_instantiate(expected->parent, strength, + 0, NULL, 0))) + goto err; + + z = item->pers != NULL ? item->pers : (unsigned char *)""; + if (!TEST_true(EVP_RAND_instantiate + (expected->ctx, strength, + expected->prediction_resistance, z, + item->pers_len))) + goto err; + + if (item->reseed_entropy != NULL) { + params[0] = OSSL_PARAM_construct_octet_string + (OSSL_RAND_PARAM_TEST_ENTROPY, item->reseed_entropy, + item->reseed_entropy_len); + params[1] = OSSL_PARAM_construct_end(); + if (!TEST_true(EVP_RAND_set_ctx_params(expected->parent, params))) + goto err; + + if (!TEST_true(EVP_RAND_reseed + (expected->ctx, expected->prediction_resistance, + NULL, 0, item->reseed_addin, + item->reseed_addin_len))) + goto err; + } + if (item->pr_entropyA != NULL) { + params[0] = OSSL_PARAM_construct_octet_string + (OSSL_RAND_PARAM_TEST_ENTROPY, item->pr_entropyA, + item->pr_entropyA_len); + params[1] = OSSL_PARAM_construct_end(); + if (!TEST_true(EVP_RAND_set_ctx_params(expected->parent, params))) + goto err; + } + if (!TEST_true(EVP_RAND_generate + (expected->ctx, got, got_len, + strength, expected->prediction_resistance, + item->addinA, item->addinA_len))) + goto err; + + if (item->pr_entropyB != NULL) { + params[0] = OSSL_PARAM_construct_octet_string + (OSSL_RAND_PARAM_TEST_ENTROPY, item->pr_entropyB, + item->pr_entropyB_len); + params[1] = OSSL_PARAM_construct_end(); + if (!TEST_true(EVP_RAND_set_ctx_params(expected->parent, params))) + return 0; + } + if (!TEST_true(EVP_RAND_generate + (expected->ctx, got, got_len, + strength, expected->prediction_resistance, + item->addinB, item->addinB_len))) + goto err; + if (!TEST_mem_eq(got, got_len, item->output, item->output_len)) + goto err; + if (!TEST_true(EVP_RAND_uninstantiate(expected->ctx)) + || !TEST_true(EVP_RAND_uninstantiate(expected->parent)) + || !TEST_true(EVP_RAND_verify_zeroization(expected->ctx)) + || !TEST_int_eq(EVP_RAND_state(expected->ctx), + EVP_RAND_STATE_UNINITIALISED)) + goto err; + } + t->err = NULL; + ret = 1; + + err: + if (ret == 0 && i >= 0) + TEST_info("Error in test case %d of %d\n", i, expected->n + 1); + OPENSSL_free(got); + return ret; +} + +static const EVP_TEST_METHOD rand_test_method = { + "RAND", + rand_test_init, + rand_test_cleanup, + rand_test_parse, + rand_test_run +}; + + /** *** KDF TESTS **/ @@ -1989,7 +2374,8 @@ static int kdf_test_init(EVP_TEST *t, const char *name) 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; } @@ -2039,7 +2425,7 @@ static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx, 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; @@ -2048,7 +2434,7 @@ static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx, *p++ = '\0'; rv = OSSL_PARAM_allocate_from_text(kdata->p, defs, name, p, - p != NULL ? strlen(p) : 0); + p != NULL ? strlen(p) : 0, NULL); *++kdata->p = OSSL_PARAM_construct_end(); if (!rv) { t->err = "KDF_PARAM_ERROR"; @@ -2064,6 +2450,15 @@ static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx, 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; } @@ -2312,7 +2707,7 @@ static int keypair_test_run(EVP_TEST *t) goto end; } - if ((rv = EVP_PKEY_cmp(pair->privk, pair->pubk)) != 1 ) { + if ((rv = EVP_PKEY_eq(pair->privk, pair->pubk)) != 1 ) { if ( 0 == rv ) { t->err = "KEYPAIR_MISMATCH"; } else if ( -1 == rv ) { @@ -2414,8 +2809,8 @@ static int keygen_test_run(EVP_TEST *t) { KEYGEN_TEST_DATA *keygen = t->data; EVP_PKEY *pkey = NULL; + int rv = 1; - t->err = NULL; if (EVP_PKEY_keygen(keygen->genctx, &pkey) <= 0) { t->err = "KEYGEN_GENERATE_ERROR"; goto err; @@ -2424,6 +2819,7 @@ static int keygen_test_run(EVP_TEST *t) if (keygen->keyname != NULL) { KEY_LIST *key; + rv = 0; if (find_key(NULL, keygen->keyname, private_keys)) { TEST_info("Duplicate key %s", keygen->keyname); goto err; @@ -2436,15 +2832,15 @@ static int keygen_test_run(EVP_TEST *t) key->key = pkey; key->next = private_keys; private_keys = key; + rv = 1; } else { EVP_PKEY_free(pkey); } - return 1; + t->err = NULL; err: - EVP_PKEY_free(pkey); - return 0; + return rv; } static const EVP_TEST_METHOD keygen_test_method = { @@ -2725,6 +3121,7 @@ static const EVP_TEST_METHOD oneshot_digestverify_test_method = { **/ static const EVP_TEST_METHOD *evp_test_list[] = { + &rand_test_method, &cipher_test_method, &digest_test_method, &digestsign_test_method, @@ -2784,7 +3181,6 @@ static void clear_test(EVP_TEST *t) 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) @@ -2827,9 +3223,8 @@ static int check_test_error(EVP_TEST *t) 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); @@ -2904,7 +3299,8 @@ static int key_unsupported(void) long err = ERR_peek_error(); if (ERR_GET_LIB(err) == ERR_LIB_EVP - && ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM) { + && (ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM + || ERR_GET_REASON(err) == EVP_R_FETCH_FAILED)) { ERR_clear_error(); return 1; } @@ -3057,17 +3453,6 @@ top: 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; @@ -3170,8 +3555,14 @@ OPT_TEST_DECLARE_USAGE("file...\n") 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;