diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h index 4029c1cd8..ba7aba1e3 100644 --- a/include/mbedtls/ecdsa.h +++ b/include/mbedtls/ecdsa.h @@ -83,8 +83,8 @@ static inline size_t mbedtls_ecdsa_max_sig_len( size_t bits ) } /** The maximal size of an ECDSA signature in Bytes. */ -#define MBEDTLS_ECDSA_MAX_LEN (MBEDTLS_ECDSA_MAX_SIG_LEN( \ - 8 * MBEDTLS_ECP_MAX_BYTES ) ) +#define MBEDTLS_ECDSA_MAX_LEN \ + ( MBEDTLS_ECDSA_MAX_SIG_LEN( 8 * MBEDTLS_ECP_MAX_BYTES ) ) /** * \brief The ECDSA context structure. @@ -97,7 +97,10 @@ extern "C" { /** * \brief This function computes the ECDSA signature of a - * previously-hashed message. + * previously-hashed message. The signature is in + * ASN.1 SEQUENCE format, as described in Standards + * for Efficient Cryptography Group (SECG): SEC1 Elliptic + * Curve Cryptography, section C.5. * * \note The deterministic version is usually preferred. * @@ -210,10 +213,13 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, * \param f_rng The RNG function. * \param p_rng The RNG parameter. * - * \note The \p sig buffer must be at least twice as large as the - * size of the curve used, plus 9. For example, 73 Bytes if - * a 256-bit curve is used. A buffer length of - * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \note The signature \p sig is expected to be ASN.1 SEQUENCE + * format, as described in Standards for Efficient + * Cryptography Group (SECG): SEC1 Elliptic Curve + * Cryptography, section C.5. + * + * \note A \p sig buffer length of #MBEDTLS_ECDSA_MAX_LEN is + * always safe. * * \note If the bitlength of the message hash is larger than the * bitlength of the group order, then the hash is truncated as @@ -297,14 +303,16 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, * \param ssize Size of the sig buffer * * \note The size of the buffer \c ssize should be at least - * `MBEDTLS_ECDSA_MAX_SIG_LEN(grp->pbits)` bytes long if - * the signature was produced from curve \c grp, - * otherwise this function will return an error. + * `MBEDTLS_ECDSA_MAX_SIG_LEN(grp->pbits)` bytes long if the + * signature was produced from curve \c grp, otherwise + * this function may fail with the error + * MBEDTLS_ERR_ASN1_BUF_TOO_SMALL. * The output ASN.1 SEQUENCE format is as follows: * Ecdsa-Sig-Value ::= SEQUENCE { * r INTEGER, * s INTEGER * } + * This format is expected by \c mbedtls_ecdsa_verify. * * \return 0 if successful, * or a MBEDTLS_ERR_MPI_XXX or MBEDTLS_ERR_ASN1_XXX error code diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 6bcda1769..9e2755f5a 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -542,7 +542,8 @@ int mbedtls_ecp_ansi_write_group( const mbedtls_ecp_group *grp, * \param format Point format, should be a MBEDTLS_ECP_PF_XXX macro * \param p Buffer to write to * \param size Buffer size - * \param olen Number of bytes written to \c buf + * \param olen Number of bytes written to \c buf on success, + * unspecified on failure. * * \return 0 on success * or \c MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index edce48c9b..d712e7750 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -2,7 +2,8 @@ * \file pk.h * * \brief Public Key cryptography abstraction layer - * + */ +/* * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * @@ -89,9 +90,9 @@ extern "C" { typedef enum { MBEDTLS_PK_NONE=0, /**< Unused context object */ MBEDTLS_PK_RSA, /**< RSA key pair (normal software implementation) with PKCS#1 v1.5 or PSS context */ - MBEDTLS_PK_ECKEY, /**< ECC key pair with ECDSA context */ - MBEDTLS_PK_ECKEY_DH, /**< ECC key pair with ECDH context */ - MBEDTLS_PK_ECDSA, /**< ECC key pair with ECDSA context */ + MBEDTLS_PK_ECKEY, /**< Generic ECC key pair */ + MBEDTLS_PK_ECKEY_DH, /**< ECC key pair restricted to key exchanges */ + MBEDTLS_PK_ECDSA, /**< ECC key pair restricted to signature/verification */ MBEDTLS_PK_RSA_ALT, /**< RSA (alternative implementation) */ MBEDTLS_PK_RSASSA_PSS, /**< RSA key pair; same context as MBEDTLS_PK_RSA, but used to represent keys with the algorithm identifier id-RSASSA-PSS */ MBEDTLS_PK_OPAQUE, /**< Opaque key pair (cryptographic material held in an external module).*/ @@ -137,7 +138,14 @@ typedef struct typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; /** - * \brief Key pair container + * \brief Context structure for public-key cryptographic operations. + * + * \note This structure contains all the information needed for + * performing a public-key cryptography operation. Depending + * on the operation and the cryptographic algorithm it can + * represent either the public key or a pair of matching + * public and private keys. Also it may contain other + * implementation specific data. */ typedef struct { @@ -256,12 +264,9 @@ typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx ); * * \param pk_type PK type to search for. * - * \note Different PK objects with the same type may have different - * information. This function returns the information needed - * to create a object with the default implementation - * for the given PK operation type (rsa module for an RSA - * context, ecdh module for an ECDH context, ecdsa module for - * an ECDSA context). + * \note This function returns NULL if pk_type indicates an opaque + * key, since the type does not provide enough information to + * build an opaque key. * * \return The PK info associated with the type or NULL if not found. */ @@ -290,13 +295,13 @@ void mbedtls_pk_free( mbedtls_pk_context *ctx ); * * \note Engines that implement opaque keys may offer an * alternative setup function that take engine-dependent - * parameters. If such a function exists, call it - * instead of mbedtls_pk_setup. A standard way of providing - * such function is by first calling the generic - * mbedtls_pk_setup function (in particular taking care of - * context allocation through ctx_alloc) and afterwards - * proceeding to initialize the implementation-specific - * context structure. + * parameters. If the documentation of the engine lists such a + * function, call it instead of mbedtls_pk_setup. A standard + * way of providing such function is by first calling the + * generic mbedtls_pk_setup function (in particular taking + * care of context allocation through ctx_alloc) and + * afterwards proceeding to initialize the + * implementation-specific context structure. * * \note For contexts holding an RSA-alt key pair, use * \c mbedtls_pk_setup_rsa_alt() instead. @@ -539,7 +544,7 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, * * \note Opaque key types may omit implementing this function * by providing a NULL pointer in the mbedtls_pk_info_t structure. - * An opaque \c pub never matches a transparent \c prv. + * Currently, an opaque \c pub never matches a transparent \c prv. */ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ); diff --git a/include/mbedtls/pk_info.h b/include/mbedtls/pk_info.h index 2ad5b3b98..846502b9c 100644 --- a/include/mbedtls/pk_info.h +++ b/include/mbedtls/pk_info.h @@ -1,12 +1,19 @@ /** * \file pk_info.h * - * \brief Public Key cryptography abstraction layer: object interface - * - * This file contains the info structure interface used by developers to - * provide target-specific implementations of opaque key handling functions - * (called engines in the following). + * \brief Public Key cryptography abstraction layer: engine interface * + * This file defines the interface the public-key cryptography engines + * (PK engines) must implement. A PK engine defines how a public-private + * key pair is represented and how to perform cryptographic operations + * with it. Mbed TLS contains built-in PK engines implemented either + * purely in software or with hardware acceleration support, depending + * on the target platform. In addition, it is possible to define custom + * opaque key engines that forward operation requests to cryptographic + * modules outside Mbed TLS, such as external cryptoprocessors or general + * PKCS#11 tokens. + */ +/* * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * @@ -76,11 +83,11 @@ extern "C" { * Some methods are optional; this is clearly indicated in their description. * If a method is optional, then an opaque key implementation may put NULL * in the corresponding field. The corresponding function in pk.h will - * return MBEDTLS_ERR_PK_TYPE_MISMATCH in this case. + * return #MBEDTLS_ERR_PK_TYPE_MISMATCH in this case. * * * \warning: Do not declare this structure directly! It may be extended in - * future* versions of Mbed TLS. Call the macro + * future versions of Mbed TLS. Call the macro * MBEDTLS_PK_OPAQUE_INFO_1() instead. * This macro is guaranteed to take parameters with the same type * and semantics as previous versions and fill any new field of the @@ -93,7 +100,7 @@ struct mbedtls_pk_info_t * mbedtls_pk_get_type() returns this value. * * For transparent keys, this contains an indication of supported - * algorithms. For opaque keys, this is \c MBEDTLS_PK_OPAQUE. */ + * algorithms. For opaque keys, this is #MBEDTLS_PK_OPAQUE. */ mbedtls_pk_type_t type; /** Type name. @@ -155,7 +162,8 @@ struct mbedtls_pk_info_t * return #MBEDTLS_ERR_PK_BAD_INPUT_DATA otherwise. * * Opaque implementations may omit this method if they do not support - * signing. */ + * signing. If this method is provided, so must be + * \ref mbedtls_pk_info_t.signature_size_func. */ int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, @@ -200,9 +208,39 @@ struct mbedtls_pk_info_t * * mbedtls_pk_check_pair() calls this function on the private key pair * object \c prv. The other argument \c pub may be of any type, but it - * is guaranteed to be initialized. + * is guaranteed to be initialized. The implementation is allowed to do + * a probabilistic and computationally expensive check. * - * Opaque implementations may omit this method. */ + * If \c prv is an RSA key and \c pub is a transparent RSA key + * (i.e. \c pub has the type #MBEDTLS_PK_RSA or #MBEDTLS_PK_RSASSA_PSS), + * then \c check_pair_func must return 0 if the public key is + * mathematically equivalent to the public part of \c prv, and + * #MBEDTLS_ERR_RSA_KEY_CHECK_FAILED otherwise. + * + * If \c pub is an ECC key and \c pub is a transparent ECC key that can + * be used for ECDSA (i.e. \c pub has the type #MBEDTLS_PK_ECKEY or + * #MBEDTLS_PK_ECDSA), then check_pair_func must return 0 if the public + * key is mathematically equivalent to the public part of prv, and + * #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise. + * + * If \c pub is a transparent key (key of type #MBEDTLS_PK_RSA, + * #MBEDTLS_PK_RSASSA_PSS, #MBEDTLS_PK_ECKEY or #MBEDTLS_PK_ECDSA) whose + * type does not match the semantic type of \c prv (RSA, ECC or other), + * then check_pair_func must return #MBEDTLS_ERR_PK_TYPE_MISMATCH. + * + * If \c pub and \c prv are opaque keys from the same engines (i.e. ``), + * then check_pair_func must return 0, `#MBEDTLS_ERR_PK_TYPE_MISMATCH`, or + * `#MBEDTLS_ERR_RSA_KEY_CHECK_FAILED` or `#MBEDTLS_ERR_ECP_BAD_INPUT_DATA` + * as in the case of transparent keys. + * + * If \c pub is an opaque key which is not from the same engine as \c prv, + * then check_pair_func may either return a semantically correct status as + * in the case of transparent keys, or it may return + * #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE. + * + * Alternatively, check_pair_func may return another PK, RSA or ECP error + * code if applicable. + * */ int (*check_pair_func)( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ); /** Allocate a new context @@ -213,11 +251,11 @@ struct mbedtls_pk_info_t * have failed and the the object remains uninitialized. * * Opaque implementations may omit this method. In this case, - * mbedtls_pk_setup will set the \c pk_ctx field of the mbedtls_pk_context - * object to NULL, and it is up to an engine-specific setup function to - * initialize the \c pk_ctx field. This is useful if the size of the - * memory depends on extra parameters passed to the engine-specific setup - * function. */ + * mbedtls_pk_setup() will set the \c pk_ctx field of the + * mbedtls_pk_context object to NULL, and it is up to an engine-specific + * setup function to initialize the \c pk_ctx field. This is useful if + * the size of the memory depends on extra parameters passed to the + * engine-specific setup function. */ void * (*ctx_alloc_func)( void ); /** Free the given context @@ -237,6 +275,36 @@ struct mbedtls_pk_info_t }; +/** + * Methods that opaque key pair objects must implement. + * + * \brief Initializer for opaque key engines + * + * The value of this macro is a suitable initializer for an object of type + * mbedtls_pk_info_t. It is guaranteed to remain so in future versions of the + * library, even if the type mbedtls_pk_info_t changes. + * + * This macro is suitable for static initializers provided that all of its + * parameters are constant. + * + * \param name For transparent keys, this reflects the key type. For opaque + * keys, this reflects the cryptographic module driver. + * \param get_bitlen \ref mbedtls_pk_info_t.get_bitlen method + * \param can_do \ref mbedtls_pk_info_t.can_do method + * \param signature_size_func \ref mbedtls_pk_info_t.signature_size_func method + * \param verify_func \ref mbedtls_pk_info_t.verify_func method + * \param sign_func \ref mbedtls_pk_info_t.sign_func method + * \param decrypt_func \ref mbedtls_pk_info_t.decrypt_func method + * \param encrypt_func \ref mbedtls_pk_info_t.encrypt_func method + * \param check_pair_func \ref mbedtls_pk_info_t.check_pair_func method + * \param ctx_alloc_func \ref mbedtls_pk_info_t.ctx_alloc_func method + * \param ctx_free_func \ref mbedtls_pk_info_t.ctx_free_func method + * \param debug_func \ref mbedtls_pk_info_t.debug_func method + * + * \return Initializer for an object of type mbedtls_pk_info_t with the + * specified field values + * + * */ #define MBEDTLS_PK_OPAQUE_INFO_1( \ name \ , get_bitlen \ diff --git a/include/mbedtls/pk_internal.h b/include/mbedtls/pk_internal.h index 0a330876e..42d6bc0b6 100644 --- a/include/mbedtls/pk_internal.h +++ b/include/mbedtls/pk_internal.h @@ -1,11 +1,16 @@ /** * \file pk_internal.h * - * \brief Public Key cryptography abstraction layer: built-in key types + * \brief Public Key cryptography abstraction layer: internal definitions * - * This file contains built-in types for handling various key types using - * the interface defined in pk_info.h. + * This file contains built-in types for handling natively supported key types + * using the interface defined in pk_info.h. * + * \warning This file contains internal definitions for the library. + * The interfaces in this file may change in future versions of the + * library without notice. + */ +/* * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * diff --git a/library/ecdsa.c b/library/ecdsa.c index d57c0c33b..afe95587b 100644 --- a/library/ecdsa.c +++ b/library/ecdsa.c @@ -311,7 +311,7 @@ int mbedtls_ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, } /* - * Compute and write signature + * Compute and write signature. This function assumes that sig is large enough. */ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hlen, diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 11b5f108e..67b44194c 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -138,14 +138,14 @@ Check pair #2 (EC, bad) depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED mbedtls_pk_check_pair:"data_files/ec_256_pub.pem":"data_files/server5.key":MBEDTLS_ERR_ECP_BAD_INPUT_DATA -#Check pair #3 (RSA, OK) -#depends_on:MBEDTLS_RSA_C -#mbedtls_pk_check_pair:"data_files/server1.pubkey":"data_files/server1.key":0 -# -#Check pair #4 (RSA, bad) -#depends_on:MBEDTLS_RSA_C -#mbedtls_pk_check_pair:"data_files/server1.pubkey":"data_files/server2.key":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -# +Check pair #3 (RSA, OK) +depends_on:MBEDTLS_RSA_C +mbedtls_pk_check_pair:"data_files/server1.pubkey":"data_files/server1.key":0 + +Check pair #4 (RSA, bad) +depends_on:MBEDTLS_RSA_C +mbedtls_pk_check_pair:"data_files/server1.pubkey":"data_files/server2.key":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + Check pair #5 (RSA vs EC) depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C mbedtls_pk_check_pair:"data_files/ec_256_pub.pem":"data_files/server1.key":MBEDTLS_ERR_PK_TYPE_MISMATCH