-/* evp_locl.h */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
- * project 2000.
- */
-/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
+/*
+ * Copyright 2000-2019 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
-/* Macros to code block cipher wrappers */
-
-/* Wrapper functions for each cipher mode */
-
-#define BLOCK_CIPHER_ecb_loop() \
- unsigned int i, bl; \
- bl = ctx->cipher->block_size;\
- if(inl < bl) return 1;\
- inl -= bl; \
- for(i=0; i <= inl; i+=bl) \
-
-#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
-static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
-{\
- BLOCK_CIPHER_ecb_loop() \
- cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
- return 1;\
-}
-
-#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
-static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
-{\
- cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
- return 1;\
-}
-
-#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
-static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
-{\
- cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
- return 1;\
-}
-
-#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
-static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
-{\
- cprefix##_cfb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
- return 1;\
-}
-
-#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
- BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
- BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
- BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
- BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
-
-#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
- key_len, iv_len, flags, init_key, cleanup, \
- set_asn1, get_asn1, ctrl) \
-static const EVP_CIPHER cname##_##mode = { \
- nid##_##nmode, block_size, key_len, iv_len, \
- flags | EVP_CIPH_##MODE##_MODE, \
- init_key, \
- cname##_##mode##_cipher, \
- cleanup, \
- sizeof(kstruct), \
- set_asn1, get_asn1,\
- ctrl, \
- NULL \
-}; \
-const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
-
-#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
- iv_len, flags, init_key, cleanup, set_asn1, \
- get_asn1, ctrl) \
-BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
- iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
-
-#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
- iv_len, cbits, flags, init_key, cleanup, \
- set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
- key_len, iv_len, flags, init_key, cleanup, set_asn1, \
- get_asn1, ctrl)
-
-#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
- iv_len, cbits, flags, init_key, cleanup, \
- set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
- key_len, iv_len, flags, init_key, cleanup, set_asn1, \
- get_asn1, ctrl)
-
-#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
- iv_len, flags, init_key, cleanup, set_asn1, \
- get_asn1, ctrl) \
-BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
- iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
-
-#define BLOCK_CIPHER_defs(cname, kstruct, \
- nid, block_size, key_len, iv_len, cbits, flags, \
- init_key, cleanup, set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
- init_key, cleanup, set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
- flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
- flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
- init_key, cleanup, set_asn1, get_asn1, ctrl)
-
+/* EVP_MD_CTX related stuff */
+
+#include <openssl/core_numbers.h>
+
+#define EVP_CTRL_RET_UNSUPPORTED -1
+
+
+struct evp_md_ctx_st {
+ const EVP_MD *reqdigest; /* The original requested digest */
+ const EVP_MD *digest;
+ ENGINE *engine; /* functional reference if 'digest' is
+ * ENGINE-provided */
+ unsigned long flags;
+ void *md_data;
+ /* Public key context for sign/verify */
+ EVP_PKEY_CTX *pctx;
+ /* Update function: usually copied from EVP_MD */
+ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+
+ /* Provider ctx */
+ void *provctx;
+ EVP_MD *fetched_digest;
+} /* EVP_MD_CTX */ ;
+
+struct evp_cipher_ctx_st {
+ const EVP_CIPHER *cipher;
+ ENGINE *engine; /* functional reference if 'cipher' is
+ * ENGINE-provided */
+ int encrypt; /* encrypt or decrypt */
+ int buf_len; /* number we have left */
+ unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
+ unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
+ unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
+ int num; /* used by cfb/ofb/ctr mode */
+ /* FIXME: Should this even exist? It appears unused */
+ void *app_data; /* application stuff */
+ int key_len; /* May change for variable length cipher */
+ unsigned long flags; /* Various flags */
+ void *cipher_data; /* per EVP data */
+ int final_used;
+ int block_mask;
+ unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
+
+ /* Provider ctx */
+ void *provctx;
+ EVP_CIPHER *fetched_cipher;
+} /* EVP_CIPHER_CTX */ ;
+
+struct evp_mac_ctx_st {
+ EVP_MAC *meth; /* Method structure */
+ void *data; /* Individual method data */
+} /* EVP_MAC_CTX */;
+
+struct evp_kdf_ctx_st {
+ EVP_KDF *meth; /* Method structure */
+ void *data; /* Algorithm-specific data */
+} /* EVP_KDF_CTX */ ;
+
+struct evp_keymgmt_st {
+ int id; /* libcrypto internal */
+
+ char *name;
+ OSSL_PROVIDER *prov;
+ CRYPTO_REF_COUNT refcnt;
+ CRYPTO_RWLOCK *lock;
+
+ /* Domain parameter routines */
+ OSSL_OP_keymgmt_importdomparams_fn *importdomparams;
+ OSSL_OP_keymgmt_gendomparams_fn *gendomparams;
+ OSSL_OP_keymgmt_freedomparams_fn *freedomparams;
+ OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams;
+ OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types;
+ OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types;
+
+ /* Key routines */
+ OSSL_OP_keymgmt_importkey_fn *importkey;
+ OSSL_OP_keymgmt_genkey_fn *genkey;
+ OSSL_OP_keymgmt_loadkey_fn *loadkey;
+ OSSL_OP_keymgmt_freekey_fn *freekey;
+ OSSL_OP_keymgmt_exportkey_fn *exportkey;
+ OSSL_OP_keymgmt_importkey_types_fn *importkey_types;
+ OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types;
+} /* EVP_KEYMGMT */ ;
+
+struct keymgmt_data_st {
+ OPENSSL_CTX *ctx;
+ const char *properties;
+};
+
+struct evp_keyexch_st {
+ char *name;
+ OSSL_PROVIDER *prov;
+ CRYPTO_REF_COUNT refcnt;
+ CRYPTO_RWLOCK *lock;
+
+ EVP_KEYMGMT *keymgmt;
+
+ OSSL_OP_keyexch_newctx_fn *newctx;
+ OSSL_OP_keyexch_init_fn *init;
+ OSSL_OP_keyexch_set_peer_fn *set_peer;
+ OSSL_OP_keyexch_derive_fn *derive;
+ OSSL_OP_keyexch_freectx_fn *freectx;
+ OSSL_OP_keyexch_dupctx_fn *dupctx;
+ OSSL_OP_keyexch_set_params_fn *set_params;
+} /* EVP_KEYEXCH */;
+
+struct evp_signature_st {
+ char *name;
+ OSSL_PROVIDER *prov;
+ CRYPTO_REF_COUNT refcnt;
+ CRYPTO_RWLOCK *lock;
+
+ EVP_KEYMGMT *keymgmt;
+
+ OSSL_OP_signature_newctx_fn *newctx;
+ OSSL_OP_signature_sign_init_fn *sign_init;
+ OSSL_OP_signature_sign_fn *sign;
+ OSSL_OP_signature_verify_init_fn *verify_init;
+ OSSL_OP_signature_verify_fn *verify;
+ OSSL_OP_signature_verify_recover_init_fn *verify_recover_init;
+ OSSL_OP_signature_verify_recover_fn *verify_recover;
+ OSSL_OP_signature_freectx_fn *freectx;
+ OSSL_OP_signature_dupctx_fn *dupctx;
+ OSSL_OP_signature_set_params_fn *set_params;
+} /* EVP_SIGNATURE */;
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+ int passlen, ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md,
+ int en_de);
+
+struct evp_Encode_Ctx_st {
+ /* number saved in a partial encode/decode */
+ int num;
+ /*
+ * The length is either the output line length (in input bytes) or the
+ * shortest input line length that is ok. Once decoding begins, the
+ * length is adjusted up each time a longer line is decoded
+ */
+ int length;
+ /* data to encode */
+ unsigned char enc_data[80];
+ /* number read on current line */
+ int line_num;
+ unsigned int flags;
+};
+
+typedef struct evp_pbe_st EVP_PBE_CTL;
+DEFINE_STACK_OF(EVP_PBE_CTL)
+
+int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
+
+#include <openssl/ossl_typ.h>
+#include <openssl/core.h>
+
+void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
+ const char *algorithm, const char *properties,
+ void *(*new_method)(const char *name,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov,
+ void *method_data),
+ void *method_data,
+ int (*up_ref_method)(void *),
+ void (*free_method)(void *));
+void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
+ void (*user_fn)(void *method, void *arg),
+ void *user_arg,
+ void *(*new_method)(const char *name,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov,
+ void *method_data),
+ void *method_data,
+ void (*free_method)(void *));
+
+/* Internal structure constructors for fetched methods */
+EVP_MD *evp_md_new(void);
+EVP_CIPHER *evp_cipher_new(void);
+
+/* Helper functions to avoid duplicating code */
/*
-#define BLOCK_CIPHER_defs(cname, kstruct, \
- nid, block_size, key_len, iv_len, flags,\
- init_key, cleanup, set_asn1, get_asn1, ctrl)\
-static const EVP_CIPHER cname##_cbc = {\
- nid##_cbc, block_size, key_len, iv_len, \
- flags | EVP_CIPH_CBC_MODE,\
- init_key,\
- cname##_cbc_cipher,\
- cleanup,\
- sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
- sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
- set_asn1, get_asn1,\
- ctrl, \
- NULL \
-};\
-const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
-static const EVP_CIPHER cname##_cfb = {\
- nid##_cfb64, 1, key_len, iv_len, \
- flags | EVP_CIPH_CFB_MODE,\
- init_key,\
- cname##_cfb_cipher,\
- cleanup,\
- sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
- sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
- set_asn1, get_asn1,\
- ctrl,\
- NULL \
-};\
-const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
-static const EVP_CIPHER cname##_ofb = {\
- nid##_ofb64, 1, key_len, iv_len, \
- flags | EVP_CIPH_OFB_MODE,\
- init_key,\
- cname##_ofb_cipher,\
- cleanup,\
- sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
- sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
- set_asn1, get_asn1,\
- ctrl,\
- NULL \
-};\
-const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
-static const EVP_CIPHER cname##_ecb = {\
- nid##_ecb, block_size, key_len, iv_len, \
- flags | EVP_CIPH_ECB_MODE,\
- init_key,\
- cname##_ecb_cipher,\
- cleanup,\
- sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
- sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
- set_asn1, get_asn1,\
- ctrl,\
- NULL \
-};\
-const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
-*/
-
-#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
- block_size, key_len, iv_len, cbits, \
- flags, init_key, \
- cleanup, set_asn1, get_asn1, ctrl) \
- BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
- BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
- cbits, flags, init_key, cleanup, set_asn1, \
- get_asn1, ctrl)
-
-#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data)
-
-#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
- BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
- BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
- NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
- 0, cipher##_init_key, NULL, \
- EVP_CIPHER_set_asn1_iv, \
- EVP_CIPHER_get_asn1_iv, \
- NULL)
-
-
-struct evp_pkey_ctx_st
- {
- /* Method associated with this operation */
- const EVP_PKEY_METHOD *pmeth;
- /* Key: may be NULL */
- EVP_PKEY *pkey;
- /* Actual operation */
- int operation;
- /* Algorithm specific data */
- void *data;
- } /* EVP_PKEY_CTX */;
-
-struct evp_pkey_method_st
- {
- int pkey_id;
- int flags;
-
- int (*init)(EVP_PKEY_CTX *ctx);
- void (*cleanup)(EVP_PKEY_CTX *ctx);
-
- int (*paramgen_init)(EVP_PKEY_CTX *ctx);
- int (*paramgen)(EVP_PKEY_CTX *ctx);
-
- int (*keygen_init)(EVP_PKEY_CTX *ctx);
- int (*keygen)(EVP_PKEY_CTX *ctx);
-
- int (*sign_init)(EVP_PKEY_CTX *ctx);
- int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
- unsigned char *tbs, int tbslen);
-
- int (*verify_init)(EVP_PKEY_CTX *ctx);
- int (*verify)(EVP_PKEY_CTX *ctx, unsigned char *sig, int siglen,
- unsigned char *tbs, int tbslen);
-
- int (*verify_recover_init)(EVP_PKEY_CTX *ctx);
- int (*verify_recover)(EVP_PKEY_CTX *ctx,
- unsigned char *rout, int *routlen,
- unsigned char *sig, int siglen);
-
- int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
- int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
- EVP_MD_CTX *mctx);
-
- int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
- int (*verifyctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, int siglen,
- EVP_MD_CTX *mctx);
-
- int (*encrypt_init)(EVP_PKEY_CTX *ctx);
- int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
- unsigned char *in, int inlen);
-
- int (*decrypt_init)(EVP_PKEY_CTX *ctx);
- int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
- unsigned char *in, int inlen);
-
- int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
- int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
-
-
- } /* EVP_PKEY_METHOD */;
+ * These methods implement different ways to pass a params array to the
+ * provider. They will return one of these values:
+ *
+ * -2 if the method doesn't come from a provider
+ * (evp_do_param will return this to the called)
+ * -1 if the provider doesn't offer the desired function
+ * (evp_do_param will raise an error and return 0)
+ * or the return value from the desired function
+ * (evp_do_param will return it to the caller)
+ */
+int evp_do_ciph_getparams(const EVP_CIPHER *ciph, OSSL_PARAM params[]);
+int evp_do_ciph_ctx_getparams(const EVP_CIPHER *ciph, void *provctx,
+ OSSL_PARAM params[]);
+int evp_do_ciph_ctx_setparams(const EVP_CIPHER *ciph, void *provctx,
+ OSSL_PARAM params[]);
+int evp_do_md_getparams(const EVP_MD *md, OSSL_PARAM params[]);
+int evp_do_md_ctx_getparams(const EVP_MD *md, void *provctx,
+ OSSL_PARAM params[]);
+int evp_do_md_ctx_setparams(const EVP_MD *md, void *provctx,
+ OSSL_PARAM params[]);
+
+OSSL_PARAM *evp_pkey_to_param(EVP_PKEY *pkey, size_t *sz);
+
+#define M_check_autoarg(ctx, arg, arglen, err) \
+ if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \
+ size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
+ \
+ if (pksize == 0) { \
+ EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \
+ return 0; \
+ } \
+ if (arg == NULL) { \
+ *arglen = pksize; \
+ return 1; \
+ } \
+ if (*arglen < pksize) { \
+ EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
+ return 0; \
+ } \
+ }