+ if (ctx->cipher->prov == NULL)
+ goto legacy;
+
+ switch (type) {
+ case EVP_CTRL_SET_KEY_LENGTH:
+ params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &sz);
+ break;
+ case EVP_CTRL_RAND_KEY: /* Used by DES */
+ set_params = 0;
+ params[0] =
+ OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY,
+ ptr, sz);
+ break;
+
+ case EVP_CTRL_INIT:
+ /*
+ * TODO(3.0) EVP_CTRL_INIT is purely legacy, no provider counterpart
+ * As a matter of fact, this should be dead code, but some caller
+ * might still do a direct control call with this command, so...
+ * Legacy methods return 1 except for exceptional circumstances, so
+ * we do the same here to not be disruptive.
+ */
+ return 1;
+ case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */
+ default:
+ goto end;
+ case EVP_CTRL_GET_IV:
+ set_params = 0;
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV,
+ ptr, sz);
+ break;
+ case EVP_CTRL_AEAD_SET_IVLEN:
+ if (arg < 0)
+ return 0;
+ params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz);
+ break;
+ case EVP_CTRL_GCM_SET_IV_FIXED:
+ params[0] =
+ OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED,
+ ptr, sz);
+ break;
+ case EVP_CTRL_GET_RC5_ROUNDS:
+ set_params = 0; /* Fall thru */
+ case EVP_CTRL_SET_RC5_ROUNDS:
+ if (arg < 0)
+ return 0;
+ i = (unsigned int)arg;
+ params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_ROUNDS, &i);
+ break;
+ case EVP_CTRL_AEAD_GET_TAG:
+ set_params = 0; /* Fall thru */
+ case EVP_CTRL_AEAD_SET_TAG:
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
+ ptr, sz);
+ break;
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ params[0] =
+ OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_MAC_KEY,
+ ptr, sz);
+ break;
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ /* This one does a set and a get - since it returns a padding size */
+ params[0] =
+ OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD,
+ ptr, sz);
+ ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
+ if (ret <= 0)
+ goto end;
+ params[0] =
+ OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, &sz);
+ ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
+ if (ret <= 0)
+ goto end;
+ return sz;
+#ifndef OPENSSL_NO_RC2
+ case EVP_CTRL_GET_RC2_KEY_BITS:
+ set_params = 0; /* Fall thru */
+ case EVP_CTRL_SET_RC2_KEY_BITS:
+ params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, &sz);
+ break;
+#endif /* OPENSSL_NO_RC2 */
+ }
+
+ if (set_params)
+ ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
+ else
+ ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
+ goto end;
+
+/* TODO(3.0): Remove legacy code below */
+legacy:
+ if (ctx->cipher->ctrl == NULL) {