Implement static dispatch with SINGLE_PK_TYPE
For optional functions, we introduce an extra macro to tell if the function is
omitted. As the C preprocessor doesn't directly support comparing strings,
testing if the _FUNC macro is defined to NULL isn't obvious. One could
probably play tricks to avoid the need for _OMIT macros, but the small amount
of (entirely local) duplication here is probably a lesser evil than extra
preprocessor complexity.
diff --git a/library/pk.c b/library/pk.c
index ef08eb7..9f85718 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -1001,8 +1001,9 @@
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
/*
- * Access to members of the pk_info structure. These are meant to be replaced
- * by zero-runtime-cost accessors when a single PK type is hardcoded.
+ * Access to members of the pk_info structure. When a single PK type is
+ * hardcoded, these should have zero runtime cost; otherwise, the usual
+ * dynamic dispatch based on pk_info is used.
*
* For function members, don't make a getter, but a function that directly
* calls the method, so that we can entirely get rid of function pointers
@@ -1012,6 +1013,171 @@
* MBEDTLS_ECP_RESTARTABLE for now, as the main target for hardcoded is builds
* with MBEDTLS_USE_TINYCRYPT, which don't have MBEDTLS_ECP_RESTARTABLE.
*/
+#if defined(MBEDTLS_PK_SINGLE_TYPE)
+
+MBEDTLS_ALWAYS_INLINE static inline mbedtls_pk_type_t pk_info_type(
+ const mbedtls_pk_info_t *info )
+{
+ (void) info;
+ return( MBEDTLS_PK_INFO_TYPE( MBEDTLS_PK_SINGLE_TYPE ) );
+}
+
+MBEDTLS_ALWAYS_INLINE static inline const char * pk_info_name(
+ const mbedtls_pk_info_t *info )
+{
+ (void) info;
+ return( MBEDTLS_PK_INFO_NAME( MBEDTLS_PK_SINGLE_TYPE ) );
+}
+
+MBEDTLS_ALWAYS_INLINE static inline size_t pk_info_get_bitlen(
+ const mbedtls_pk_info_t *info, const void *ctx )
+{
+ (void) info;
+ return( MBEDTLS_PK_INFO_GET_BITLEN( MBEDTLS_PK_SINGLE_TYPE )( ctx ) );
+}
+
+MBEDTLS_ALWAYS_INLINE static inline int pk_info_can_do(
+ const mbedtls_pk_info_t *info, mbedtls_pk_type_t type )
+{
+ (void) info;
+ return( MBEDTLS_PK_INFO_CAN_DO( MBEDTLS_PK_SINGLE_TYPE )( type ) );
+}
+
+MBEDTLS_ALWAYS_INLINE static inline int pk_info_verify_func(
+ const mbedtls_pk_info_t *info, void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ (void) info;
+#if MBEDTLS_PK_INFO_VERIFY_OMIT( MBEDTLS_PK_SINGLE_TYPE )
+ (void) ctx;
+ (void) md_alg;
+ (void) hash;
+ (void) hash_len;
+ (void) sig;
+ (void) sig_len;
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+#else
+ return( MBEDTLS_PK_INFO_VERIFY_FUNC( MBEDTLS_PK_SINGLE_TYPE )(
+ ctx, md_alg, hash, hash_len, sig, sig_len ) );
+#endif
+}
+
+MBEDTLS_ALWAYS_INLINE static inline int pk_info_sign_func(
+ const mbedtls_pk_info_t *info, void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ unsigned char *sig, size_t *sig_len,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ (void) info;
+#if MBEDTLS_PK_INFO_SIGN_OMIT( MBEDTLS_PK_SINGLE_TYPE )
+ (void) ctx;
+ (void) md_alg;
+ (void) hash;
+ (void) hash_len;
+ (void) sig;
+ (void) sig_len;
+ (void) f_rng;
+ (void) p_rng;
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+#else
+ return( MBEDTLS_PK_INFO_SIGN_FUNC( MBEDTLS_PK_SINGLE_TYPE )(
+ ctx, md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
+#endif
+}
+
+MBEDTLS_ALWAYS_INLINE static inline int pk_info_decrypt_func(
+ const mbedtls_pk_info_t *info, void *ctx,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen, size_t osize,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ (void) info;
+#if MBEDTLS_PK_INFO_DECRYPT_OMIT( MBEDTLS_PK_SINGLE_TYPE )
+ (void) ctx;
+ (void) input;
+ (void) ilen;
+ (void) output;
+ (void) olen;
+ (void) osize;
+ (void) f_rng;
+ (void) p_rng;
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+#else
+ return( MBEDTLS_PK_INFO_DECRYPT_FUNC( MBEDTLS_PK_SINGLE_TYPE )(
+ ctx, input, ilen, output, olen, osize, f_rng, p_rng ) );
+#endif
+}
+
+MBEDTLS_ALWAYS_INLINE static inline int pk_info_encrypt_func(
+ const mbedtls_pk_info_t *info, void *ctx,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen, size_t osize,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ (void) info;
+#if MBEDTLS_PK_INFO_ENCRYPT_OMIT( MBEDTLS_PK_SINGLE_TYPE )
+ (void) ctx;
+ (void) input;
+ (void) ilen;
+ (void) output;
+ (void) olen;
+ (void) osize;
+ (void) f_rng;
+ (void) p_rng;
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+#else
+ return( MBEDTLS_PK_INFO_ENCRYPT_FUNC( MBEDTLS_PK_SINGLE_TYPE )(
+ ctx, input, ilen, output, olen, osize, f_rng, p_rng ) );
+#endif
+}
+
+MBEDTLS_ALWAYS_INLINE static inline int pk_info_check_pair_func(
+ const mbedtls_pk_info_t *info, const void *pub, const void *prv )
+{
+ (void) info;
+#if MBEDTLS_PK_INFO_CHECK_PAIR_OMIT( MBEDTLS_PK_SINGLE_TYPE )
+ (void) pub;
+ (void) prv;
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+#else
+ return( MBEDTLS_PK_INFO_CHECK_PAIR_FUNC( MBEDTLS_PK_SINGLE_TYPE )(
+ pub, prv ) );
+#endif
+}
+
+MBEDTLS_ALWAYS_INLINE static inline void *pk_info_ctx_alloc_func(
+ const mbedtls_pk_info_t *info )
+{
+ (void) info;
+ return( MBEDTLS_PK_INFO_CTX_ALLOC_FUNC( MBEDTLS_PK_SINGLE_TYPE )( ) );
+}
+
+MBEDTLS_ALWAYS_INLINE static inline void pk_info_ctx_free_func(
+ const mbedtls_pk_info_t *info, void *ctx )
+{
+ (void) info;
+ MBEDTLS_PK_INFO_CTX_FREE_FUNC( MBEDTLS_PK_SINGLE_TYPE )( ctx );
+}
+
+MBEDTLS_ALWAYS_INLINE static inline int pk_info_debug_func(
+ const mbedtls_pk_info_t *info,
+ const void *ctx, mbedtls_pk_debug_item *items )
+{
+ (void) info;
+#if MBEDTLS_PK_INFO_DEBUG_OMIT( MBEDTLS_PK_SINGLE_TYPE )
+ (void) ctx;
+ (void) items;
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+#else
+ return( MBEDTLS_PK_INFO_DEBUG_FUNC( MBEDTLS_PK_SINGLE_TYPE )( ctx, items ) );
+#endif
+}
+
+#else /* MBEDTLS_PK_SINGLE_TYPE */
MBEDTLS_ALWAYS_INLINE static inline mbedtls_pk_type_t pk_info_type(
const mbedtls_pk_info_t *info )
@@ -1122,6 +1288,8 @@
return( 0 );
}
+#endif /* MBEDTLS_PK_SINGLE_TYPE */
+
/*
* Initialise a mbedtls_pk_context
*/