int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
{
- int ok;
- OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
- size_t len = keylen;
+ if (c->cipher->prov != NULL) {
+ int ok;
+ OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ size_t len = keylen;
+
+ if (EVP_CIPHER_CTX_key_length(c) == keylen)
+ return 1;
+
+ /* Check the cipher actually understands this parameter */
+ if (OSSL_PARAM_locate_const(EVP_CIPHER_settable_ctx_params(c->cipher),
+ OSSL_CIPHER_PARAM_KEYLEN) == NULL)
+ return 0;
- params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len);
- ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params);
+ params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len);
+ ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params);
- if (ok != EVP_CTRL_RET_UNSUPPORTED)
- return ok;
+ return ok > 0 ? 1 : 0;
+ }
/* TODO(3.0) legacy code follows */
+
+ /*
+ * Note there have never been any built-in ciphers that define this flag
+ * since it was first introduced.
+ */
if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
if (EVP_CIPHER_CTX_key_length(c) == keylen)
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_generic)
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_generic)
+/*
+ * Variable key length cipher functions for OSSL_PARAM settables
+ */
+
+int cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+ PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+ const OSSL_PARAM *p;
+
+ if (!cipher_generic_set_ctx_params(vctx, params))
+ return 0;
+ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
+ if (p != NULL) {
+ size_t keylen;
+
+ if (!OSSL_PARAM_get_size_t(p, &keylen)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+ return 0;
+ }
+ ctx->keylen = keylen;
+ }
+ return 1;
+}
+
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_var_keylen)
+OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_var_keylen)
+
/*-
* AEAD cipher functions for OSSL_PARAM gettables and settables
*/
}
static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
- OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
}
ctx->num = num;
}
- p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
- if (p != NULL) {
- size_t keylen;
-
- if (!OSSL_PARAM_get_size_t(p, &keylen)) {
- ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
- return 0;
- }
- ctx->keylen = keylen;
- }
return 1;
}
}
}
- /*
- * TODO(3.0) Temporary solution to address fuzz test crash, which will be
- * reworked once the discussion in PR #9510 is resolved. i.e- We need a
- * general solution for handling missing parameters inside set_params and
- * get_params methods.
- */
- p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
- if (p != NULL) {
- size_t keylen;
-
- if (!OSSL_PARAM_get_size_t(p, &keylen)) {
- ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
- return 0;
- }
- /* The key length can not be modified for gcm mode */
- if (keylen != ctx->keylen)
- return 0;
- }
-
return 1;
}
OSSL_OP_cipher_gettable_params_fn cipher_generic_gettable_params;
OSSL_OP_cipher_gettable_ctx_params_fn cipher_generic_gettable_ctx_params;
OSSL_OP_cipher_settable_ctx_params_fn cipher_generic_settable_ctx_params;
+OSSL_OP_cipher_set_ctx_params_fn cipher_var_keylen_set_ctx_params;
+OSSL_OP_cipher_settable_ctx_params_fn cipher_var_keylen_settable_ctx_params;
OSSL_OP_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params;
OSSL_OP_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params;
int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
{ 0, NULL } \
};
-#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \
- blkbits, ivbits, typ) \
+#define IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, \
+ kbits, blkbits, ivbits, typ) \
+const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \
+ { OSSL_FUNC_CIPHER_NEWCTX, \
+ (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \
+ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \
+ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \
+ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \
+ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \
+ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\
+ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \
+ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \
+ { OSSL_FUNC_CIPHER_GET_PARAMS, \
+ (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \
+ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \
+ (void (*)(void))cipher_generic_get_ctx_params }, \
+ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
+ (void (*)(void))cipher_var_keylen_set_ctx_params }, \
+ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
+ (void (*)(void))cipher_generic_gettable_params }, \
+ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
+ (void (*)(void))cipher_generic_gettable_ctx_params }, \
+ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
+ (void (*)(void))cipher_var_keylen_settable_ctx_params }, \
+ { 0, NULL } \
+};
+
+
+#define IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, \
+ kbits, blkbits, ivbits, typ) \
static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \
static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \
{ \
} \
return ctx; \
} \
+
+#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \
+ blkbits, ivbits, typ) \
+IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \
+ blkbits, ivbits, typ) \
IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \
blkbits, ivbits, typ)
+#define IMPLEMENT_var_keylen_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \
+ blkbits, ivbits, typ) \
+IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \
+ blkbits, ivbits, typ) \
+IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \
+ blkbits, ivbits, typ)
+
PROV_CIPHER_HW_FN cipher_hw_generic_cbc;
PROV_CIPHER_HW_FN cipher_hw_generic_ecb;
PROV_CIPHER_HW_FN cipher_hw_generic_ofb128;
#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name) \
static const OSSL_PARAM name##_known_settable_ctx_params[] = { \
- OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),
#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \
}
/* bf_ecb_functions */
-IMPLEMENT_generic_cipher(blowfish, BLOWFISH, ecb, ECB, BF_FLAGS, 128, 64, 0, block)
+IMPLEMENT_var_keylen_cipher(blowfish, BLOWFISH, ecb, ECB, BF_FLAGS, 128, 64, 0, block)
/* bf_cbc_functions */
-IMPLEMENT_generic_cipher(blowfish, BLOWFISH, cbc, CBC, BF_FLAGS, 128, 64, 64, block)
+IMPLEMENT_var_keylen_cipher(blowfish, BLOWFISH, cbc, CBC, BF_FLAGS, 128, 64, 64, block)
/* bf_ofb_functions */
-IMPLEMENT_generic_cipher(blowfish, BLOWFISH, ofb64, OFB, BF_FLAGS, 64, 8, 64, stream)
+IMPLEMENT_var_keylen_cipher(blowfish, BLOWFISH, ofb64, OFB, BF_FLAGS, 64, 8, 64, stream)
/* bf_cfb_functions */
-IMPLEMENT_generic_cipher(blowfish, BLOWFISH, cfb64, CFB, BF_FLAGS, 64, 8, 64, stream)
+IMPLEMENT_var_keylen_cipher(blowfish, BLOWFISH, cfb64, CFB, BF_FLAGS, 64, 8, 64, stream)
#include "cipher_cast.h"
#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
#define CAST5_FLAGS (EVP_CIPH_VARIABLE_LENGTH)
}
/* cast5128ecb_functions */
-IMPLEMENT_generic_cipher(cast5, CAST, ecb, ECB, CAST5_FLAGS, 128, 64, 0, block)
+IMPLEMENT_var_keylen_cipher(cast5, CAST, ecb, ECB, CAST5_FLAGS, 128, 64, 0, block)
/* cast5128cbc_functions */
-IMPLEMENT_generic_cipher(cast5, CAST, cbc, CBC, CAST5_FLAGS, 128, 64, 64, block)
+IMPLEMENT_var_keylen_cipher(cast5, CAST, cbc, CBC, CAST5_FLAGS, 128, 64, 64, block)
/* cast564ofb64_functions */
-IMPLEMENT_generic_cipher(cast5, CAST, ofb64, OFB, CAST5_FLAGS, 64, 8, 64, stream)
+IMPLEMENT_var_keylen_cipher(cast5, CAST, ofb64, OFB, CAST5_FLAGS, 64, 8, 64, stream)
/* cast564cfb64_functions */
-IMPLEMENT_generic_cipher(cast5, CAST, cfb64, CFB, CAST5_FLAGS, 64, 8, 64, stream)
+IMPLEMENT_var_keylen_cipher(cast5, CAST, cfb64, CFB, CAST5_FLAGS, 64, 8, 64, stream)
PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx;
const OSSL_PARAM *p;
- if (!cipher_generic_set_ctx_params(vctx, params))
+ if (!cipher_var_keylen_set_ctx_params(vctx, params))
return 0;
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_RC2_KEYBITS);
if (p != NULL) {
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc2)
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc2)
+OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL),
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc2)
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \
(void (*)(void))cipher_generic_get_ctx_params }, \
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
- (void (*)(void))cipher_generic_set_ctx_params }, \
+ (void (*)(void))cipher_var_keylen_set_ctx_params }, \
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
(void (*)(void))cipher_generic_gettable_params }, \
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
(void (*)(void))cipher_generic_gettable_ctx_params }, \
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
- (void (*)(void))cipher_generic_settable_ctx_params }, \
+ (void (*)(void))cipher_var_keylen_settable_ctx_params }, \
{ 0, NULL } \
};
PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
const OSSL_PARAM *p;
- if (!cipher_generic_set_ctx_params(vctx, params))
+ if (!cipher_var_keylen_set_ctx_params(vctx, params))
return 0;
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ROUNDS);
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc5)
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc5)
+ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL),
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc5)