diff --git a/ChangeLog b/ChangeLog index 8322b0e92..0061fe87d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,19 @@ Features New deprecations * Deprecate usage of RSA primitives with non-matching key-type (e.g., signing with a public key). + * Direct manipulation of structure fields of RSA contexts is deprecated. + Users are advised to use the extended RSA API instead. + +API Changes + * Extend RSA interface by multiple functions allowing structure- + independent setup and export of RSA contexts. Most notably, + mbedtls_rsa_import and mbedtls_rsa_complete are introduced for setting + up RSA contexts from partial key material and having them completed to the + needs of the implementation automatically. This allows to setup private RSA + contexts from keys consisting of N,D,E only, even if P,Q are needed for the + purpose or CRT and/or blinding. + * The configuration option MBEDTLS_RSA_ALT can be used to define alternative + implementations of the RSA interface declared in rsa.h. Bugfix * Fix ssl_parse_record_header() to silently discard invalid DTLS records @@ -89,6 +102,10 @@ Changes * Extend cert_write example program by options to set the CRT version and the message digest. Further, allow enabling/disabling of authority identifier, subject identifier and basic constraints extensions. + * Only check for necessary RSA structure fields in `mbedtls_rsa_private`. In + particular, don't require P,Q if neither CRT nor blinding are + used. Reported and fix proposed independently by satur9nine and sliai + on GitHub. * Only run AES-192 self-test if AES-192 is available. Fixes #963. = mbed TLS 2.6.0 branch released 2017-08-10 diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 456a80420..0b4001542 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -70,7 +70,7 @@ * Maximum size of MPIs allowed in bits and bytes for user-MPIs. * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) * - * Note: Calculations can results temporarily in larger MPIs. So the number + * Note: Calculations can temporarily result in larger MPIs. So the number * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. */ #define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 74e9f80e4..493310882 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -270,14 +270,15 @@ //#define MBEDTLS_CMAC_ALT //#define MBEDTLS_DES_ALT //#define MBEDTLS_GCM_ALT -//#define MBEDTLS_XTEA_ALT //#define MBEDTLS_MD2_ALT //#define MBEDTLS_MD4_ALT //#define MBEDTLS_MD5_ALT //#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT //#define MBEDTLS_SHA1_ALT //#define MBEDTLS_SHA256_ALT //#define MBEDTLS_SHA512_ALT +//#define MBEDTLS_XTEA_ALT /* * When replacing the elliptic curve module, pleace consider, that it is * implemented with two .c files: @@ -1664,6 +1665,7 @@ * library/ecp.c * library/ecdsa.c * library/rsa.c + * library/rsa_internal.c * library/ssl_tls.c * * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. @@ -2277,6 +2279,7 @@ * Enable the RSA public-key cryptosystem. * * Module: library/rsa.c + * library/rsa_internal.c * Caller: library/ssl_cli.c * library/ssl_srv.c * library/ssl_tls.c diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h index d04e71d58..d7503ac83 100644 --- a/include/mbedtls/rsa.h +++ b/include/mbedtls/rsa.h @@ -68,14 +68,23 @@ * The above constants may be used even if the RSA module is compile out, * eg for alternative (PKCS#11) RSA implemenations in the PK layers. */ -#if defined(MBEDTLS_RSA_C) + +#if !defined(MBEDTLS_RSA_ALT) +// Regular implementation +// #ifdef __cplusplus extern "C" { #endif /** - * \brief RSA context structure + * \brief RSA context structure + * + * \note Direct manipulation of the members of this structure + * is deprecated and will no longer be supported starting + * from the next major release. All manipulation should instead + * be done through the public interface functions. + * */ typedef struct { @@ -88,19 +97,21 @@ typedef struct mbedtls_mpi D; /*!< private exponent */ mbedtls_mpi P; /*!< 1st prime factor */ mbedtls_mpi Q; /*!< 2nd prime factor */ + mbedtls_mpi DP; /*!< D % (P - 1) */ mbedtls_mpi DQ; /*!< D % (Q - 1) */ mbedtls_mpi QP; /*!< 1 / (Q % P) */ mbedtls_mpi RN; /*!< cached R^2 mod N */ + mbedtls_mpi RP; /*!< cached R^2 mod P */ mbedtls_mpi RQ; /*!< cached R^2 mod Q */ mbedtls_mpi Vi; /*!< cached blinding value */ mbedtls_mpi Vf; /*!< cached un-blinding value */ - int padding; /*!< MBEDTLS_RSA_PKCS_V15 for 1.5 padding and - MBEDTLS_RSA_PKCS_v21 for OAEP/PSS */ + int padding; /*!< \c MBEDTLS_RSA_PKCS_V15 for 1.5 padding and + \c MBEDTLS_RSA_PKCS_v21 for OAEP/PSS */ int hash_id; /*!< Hash identifier of mbedtls_md_type_t as specified in the mbedtls_md.h header file for the EME-OAEP and EMSA-PSS @@ -114,15 +125,15 @@ mbedtls_rsa_context; /** * \brief Initialize an RSA context * - * Note: Set padding to MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP + * Note: Set padding to \c MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP * encryption scheme and the RSASSA-PSS signature scheme. * * \param ctx RSA context to be initialized - * \param padding MBEDTLS_RSA_PKCS_V15 or MBEDTLS_RSA_PKCS_V21 - * \param hash_id MBEDTLS_RSA_PKCS_V21 hash identifier + * \param padding \c MBEDTLS_RSA_PKCS_V15 or \c MBEDTLS_RSA_PKCS_V21 + * \param hash_id \c MBEDTLS_RSA_PKCS_V21 hash identifier * * \note The hash_id parameter is actually ignored - * when using MBEDTLS_RSA_PKCS_V15 padding. + * when using \c MBEDTLS_RSA_PKCS_V15 padding. * * \note Choice of padding mode is strictly enforced for private key * operations, since there might be security concerns in @@ -133,21 +144,241 @@ mbedtls_rsa_context; * \note The chosen hash is always used for OEAP encryption. * For PSS signatures, it's always used for making signatures, * but can be overriden (and always is, if set to - * MBEDTLS_MD_NONE) for verifying them. + * \c MBEDTLS_MD_NONE) for verifying them. */ void mbedtls_rsa_init( mbedtls_rsa_context *ctx, - int padding, - int hash_id); + int padding, + int hash_id); + +/** + * \brief Import a set of core parameters into an RSA context + * + * \param ctx Initialized RSA context to store parameters + * \param N RSA modulus, or NULL + * \param P First prime factor of N, or NULL + * \param Q Second prime factor of N, or NULL + * \param D Private exponent, or NULL + * \param E Public exponent, or NULL + * + * \note This function can be called multiple times for successive + * imports if the parameters are not simultaneously present. + * Any sequence of calls to this function should be followed + * by a call to \c mbedtls_rsa_complete which will check + * and complete the provided information to a ready-for-use + * public or private RSA key. + * + * \note See the documentation of \c mbedtls_rsa_complete for more + * information on which parameters are necessary to setup + * a private or public RSA key. + * + * \note The imported parameters are copied and need not be preserved + * for the lifetime of the RSA context being set up. + * + * \return 0 if successful, non-zero error code on failure. + */ +int mbedtls_rsa_import( mbedtls_rsa_context *ctx, + const mbedtls_mpi *N, + const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, const mbedtls_mpi *E ); + +/** + * \brief Import core RSA parameters in raw big-endian + * binary format into an RSA context + * + * \param ctx Initialized RSA context to store parameters + * \param N RSA modulus, or NULL + * \param N_len Byte length of N, ignored if N == NULL + * \param P First prime factor of N, or NULL + * \param P_len Byte length of P, ignored if P == NULL + * \param Q Second prime factor of N, or NULL + * \param Q_len Byte length of Q, ignored if Q == NULL + * \param D Private exponent, or NULL + * \param D_len Byte length of D, ignored if D == NULL + * \param E Public exponent, or NULL + * \param E_len Byte length of E, ignored if E == NULL + * + * \note This function can be called multiple times for successive + * imports if the parameters are not simultaneously present. + * Any sequence of calls to this function should be followed + * by a call to \c mbedtls_rsa_complete which will check + * and complete the provided information to a ready-for-use + * public or private RSA key. + * + * \note See the documentation of \c mbedtls_rsa_complete for more + * information on which parameters are necessary to setup + * a private or public RSA key. + * + * \note The imported parameters are copied and need not be preserved + * for the lifetime of the RSA context being set up. + * + * \return 0 if successful, non-zero error code on failure. + */ +int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, + unsigned char const *N, size_t N_len, + unsigned char const *P, size_t P_len, + unsigned char const *Q, size_t Q_len, + unsigned char const *D, size_t D_len, + unsigned char const *E, size_t E_len ); + +/** + * \brief Attempt to complete an RSA context from + * a set of imported core parameters. + * + * \param ctx Initialized RSA context to store parameters + * + * \note + * - To setup an RSA public key, precisely N and E + * must have been imported. + * + * - To setup an RSA private key, enough information must be + * present for the other parameters to be derivable. + * + * The default implementation supports the following: + * - Derive P, Q from N, D, E + * - Derive N, D from P, Q, E. + * + * - Alternative implementations need not support these + * and may return \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA instead. + * + * \return + * - 0 if successful. In this case, it is guaranteed + * that the RSA context can be used for RSA operations + * without the risk of failure or crash. + * - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted + * derivations failed. + * + * \warning This function need not perform consistency checks + * for the imported parameters! In particular, parameters that + * are not needed by the implementation may be silently discarded + * and left unchecked. For the purpose of checking the consistency + * of the key material, see \c mbedtls_rsa_check_privkey. + * + */ +int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ); + +/** + * \brief Export core parameters of an RSA key + * + * \param ctx Initialized RSA context + * \param N MPI to hold the RSA modulus, or NULL + * \param P MPI to hold the first prime factor of N, or NULL + * \param Q MPI to hold the second prime factor of N, or NULL + * \param D MPI to hold the private exponent, or NULL + * \param E MPI to hold the public exponent, or NULL + * + * \return + * - 0 if successful. In this case, the non-NULL buffers + * pointed to by N, P, Q, D, E are fully written, with + * additional unused space filled leading by 0-bytes. + * - Non-zero return code otherwise. In particular, if + * exporting the requested parameters + * cannot be done because of a lack of functionality + * or because of security policies, the error code + * \c MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is returned. + * In this case, the RSA context stays intact and can + * be continued to be used. + * + * \note Reasons for returning \c MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION + * would be the following: Firstly, it might be that an + * alternative RSA implementation is in use which stores + * the key externally, and which either cannot or should not + * export it into RAM. Alternatively, an implementation + * (regardless of SW or HW) might not support deducing e.g. + * P, Q from N, D, E if the former are not part of the + * implementation. + * + */ +int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, + mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, + mbedtls_mpi *D, mbedtls_mpi *E ); + +/** + * \brief Export core parameters of an RSA key + * in raw big-endian binary format + * + * \param ctx Initialized RSA context + * \param N Byte array to store the RSA modulus, or NULL + * \param N_len Size of buffer for modulus + * \param P Byte array to hold the first prime factor of N, or NULL + * \param P_len Size of buffer for first prime factor + * \param Q Byte array to hold the second prime factor of N, or NULL + * \param Q_len Size of buffer for second prime factor + * \param D Byte array to hold the private exponent, or NULL + * \param D_len Size of buffer for private exponent + * \param E Byte array to hold the public exponent, or NULL + * \param E_len Size of buffer for public exponent + * + * \note The length fields are ignored if the corresponding + * buffer pointers are NULL. + * + * \return + * - 0 if successful. In this case, the non-NULL buffers + * pointed to by N, P, Q, D, E are fully written, with + * additional unused space filled leading by 0-bytes. + * - Non-zero return code otherwise. In particular, if + * exporting the requested parameters + * cannot be done because of a lack of functionality + * or because of security policies, the error code + * \c MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is returned. + * In this case, the RSA context stays intact and can + * be continued to be used. + * + * \note Reasons for returning \c MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION + * would be the following: Firstly, it might be that an + * alternative RSA implementation is in use which stores + * the key externally, and which either cannot or should not + * export it into RAM. Alternatively, an implementation + * (regardless of SW or HW) might not support deducing e.g. + * P, Q from N, D, E if the former are not part of the + * implementation. + * + * + */ +int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, + unsigned char *N, size_t N_len, + unsigned char *P, size_t P_len, + unsigned char *Q, size_t Q_len, + unsigned char *D, size_t D_len, + unsigned char *E, size_t E_len ); + +/** + * \brief Export CRT parameters of a private RSA key + * + * \param ctx Initialized RSA context + * \param DP MPI to hold D modulo P-1, or NULL + * \param DQ MPI to hold D modulo Q-1, or NULL + * \param QP MPI to hold modular inverse of Q modulo P, or NULL + * + * \return 0 if successful, non-zero error code otherwise. + * + * \note Alternative RSA implementations not using CRT-parameters + * internally can implement this function using based on + * \c mbedtls_rsa_deduce_opt. + * + */ +int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, + mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ); /** * \brief Set padding for an already initialized RSA context * See \c mbedtls_rsa_init() for details. * * \param ctx RSA context to be set - * \param padding MBEDTLS_RSA_PKCS_V15 or MBEDTLS_RSA_PKCS_V21 - * \param hash_id MBEDTLS_RSA_PKCS_V21 hash identifier + * \param padding \c MBEDTLS_RSA_PKCS_V15 or \c MBEDTLS_RSA_PKCS_V21 + * \param hash_id \c MBEDTLS_RSA_PKCS_V21 hash identifier */ -void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id); +void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, + int hash_id); + +/** + * \brief Get length of RSA modulus in bytes + * + * \param ctx Initialized RSA context + * + * \return Length of RSA modulus, in bytes. + * + */ +size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ); /** * \brief Generate an RSA keypair @@ -161,28 +392,61 @@ void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id * \note mbedtls_rsa_init() must be called beforehand to setup * the RSA context. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code */ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - unsigned int nbits, int exponent ); + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent ); /** - * \brief Check a public RSA key + * \brief Check if a context contains (at least) an RSA public key * * \param ctx RSA context to be checked * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code. + * On success, it is guaranteed that enough information is + * present to perform an RSA public key operation + * \c mbedtls_rsa_public. + * */ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); /** - * \brief Check a private RSA key + * \brief Check if a context contains an RSA private key + * and perform basic consistency checks. * - * \param ctx RSA context to be checked + * \param ctx RSA context to be checked + * + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code. + * + * \note The consistency checks performed by this function not only + * ensure that \c mbedtls_rsa_private can be called successfully + * on the given context, but that the various parameters are + * mutually consistent with high probability, in the sense that + * \c mbedtls_rsa_public and \c mbedtls_rsa_private are inverses. + * + * \warning This function should catch accidental misconfigurations + * like swapping of parameters, but it cannot establish full + * trust in neither the quality nor the consistency of the key + * material that was used to setup the given RSA context: + * - Regarding consistency, note (see \c mbedtls_rsa_complete) + * that imported parameters irrelevant for the implementation + * might be silently dropped, in which case the present + * function doesn't have access to and hence cannot check them. + * If you want to check the consistency of the entire + * content of, say, an PKCS1-encoded RSA private key, you + * should use \c mbedtls_rsa_validate_params before setting + * up the RSA context. + * Further, if the implementation performs empirical checks, + * these checks will substantiate but not guarantee consistency. + * - Regarding quality, this function is not expected to perform + * extended quality assessments like checking that the prime + * factors are safe. Further, it is the user's responsibility to + * ensure trustworthiness of the source of his RSA parameters, + * a question going beyond what's effectively checkable + * by the library. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code */ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ); @@ -193,9 +457,10 @@ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ); * \param pub RSA context holding the public key * \param prv RSA context holding the private key * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code */ -int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv ); +int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, + const mbedtls_rsa_context *prv ); /** * \brief Do an RSA public key operation @@ -204,7 +469,7 @@ int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rs * \param input input buffer * \param output output buffer * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note This function does NOT take care of message * padding. Also, be sure to set input[0] = 0 or ensure that @@ -226,7 +491,7 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, * \param input input buffer * \param output output buffer * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note The input and output buffers must be large * enough (eg. 128 bytes if RSA-1024 is used). @@ -244,9 +509,9 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, * * \param ctx RSA context * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding - * and MBEDTLS_RSA_PRIVATE) + * and \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE * \param ilen contains the plaintext length * \param input buffer holding the data to be encrypted * \param output buffer that will hold the ciphertext @@ -260,7 +525,7 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, * mode being set to MBEDTLS_RSA_PRIVATE and may instead * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note The output buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). @@ -276,9 +541,9 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, * \brief Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT) * * \param ctx RSA context - * \param f_rng RNG function (Needed for padding and MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Needed for padding and \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE * \param ilen contains the plaintext length * \param input buffer holding the data to be encrypted * \param output buffer that will hold the ciphertext @@ -292,7 +557,7 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, * mode being set to MBEDTLS_RSA_PRIVATE and may instead * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note The output buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). @@ -309,9 +574,9 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, * * \param ctx RSA context * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding - * and MBEDTLS_RSA_PRIVATE) + * and \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE * \param label buffer holding the custom label to use * \param label_len contains the label length * \param ilen contains the plaintext length @@ -327,7 +592,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, * mode being set to MBEDTLS_RSA_PRIVATE and may instead * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note The output buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). @@ -347,9 +612,9 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, * the message padding * * \param ctx RSA context - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE * \param olen will contain the plaintext length * \param input buffer holding the encrypted data * \param output buffer that will hold the plaintext @@ -364,17 +629,17 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, * mode being set to MBEDTLS_RSA_PUBLIC and may instead * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note The output buffer length \c output_max_len should be - * as large as the size ctx->len of ctx->N (eg. 128 bytes + * as large as the size \c ctx->len of \c ctx->N (eg. 128 bytes * if RSA-1024 is used) to be able to hold an arbitrary * decrypted message. If it is not large enough to hold * the decryption of the particular ciphertext provided, - * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * the function will return \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. * * \note The input buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -388,9 +653,9 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, * \brief Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT) * * \param ctx RSA context - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE * \param olen will contain the plaintext length * \param input buffer holding the encrypted data * \param output buffer that will hold the plaintext @@ -405,17 +670,17 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, * mode being set to MBEDTLS_RSA_PUBLIC and may instead * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note The output buffer length \c output_max_len should be - * as large as the size ctx->len of ctx->N (eg. 128 bytes + * as large as the size \c ctx->len of \c ctx->N (eg. 128 bytes * if RSA-1024 is used) to be able to hold an arbitrary * decrypted message. If it is not large enough to hold * the decryption of the particular ciphertext provided, - * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * the function will return \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. * * \note The input buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -429,9 +694,9 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, * \brief Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT) * * \param ctx RSA context - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE * \param label buffer holding the custom label to use * \param label_len contains the label length * \param olen will contain the plaintext length @@ -448,17 +713,18 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, * mode being set to MBEDTLS_RSA_PUBLIC and may instead * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code + * \return 0 if successful, or an \c MBEDTLS_ERR_RSA_XXX error code * * \note The output buffer length \c output_max_len should be - * as large as the size ctx->len of ctx->N (eg. 128 bytes + * as large as the size \c ctx->len of \c ctx->N (eg. 128 bytes * if RSA-1024 is used) to be able to hold an arbitrary * decrypted message. If it is not large enough to hold * the decryption of the particular ciphertext provided, - * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * the function will return \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. * * \note The input buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). + * */ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -477,11 +743,12 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, * * \param ctx RSA context * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding and for - * MBEDTLS_RSA_PRIVATE) + * \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE + * \param md_alg a \c MBEDTLS_MD_XXX (use \c MBEDTLS_MD_NONE for + * signing raw data) + * \param hashlen message digest length (for \c MBEDTLS_MD_NONE only) * \param hash buffer holding the message digest * \param sig buffer that will hold the ciphertext * @@ -495,13 +762,14 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * * \return 0 if the signing operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code + * or an \c MBEDTLS_ERR_RSA_XXX error code * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * \note The \c sig buffer must be as large as the size + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). * * \note In case of PKCS#1 v2.1 encoding, see comments on - * \note \c mbedtls_rsa_rsassa_pss_sign() for details on md_alg and hash_id. + * \c mbedtls_rsa_rsassa_pss_sign() for details on + * \c md_alg and \c hash_id. */ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -516,11 +784,12 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, * \brief Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN) * * \param ctx RSA context - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE + * \param md_alg a \c MBEDTLS_MD_XXX (use \c MBEDTLS_MD_NONE + * for signing raw data) + * \param hashlen message digest length (for \c MBEDTLS_MD_NONE only) * \param hash buffer holding the message digest * \param sig buffer that will hold the ciphertext * @@ -534,10 +803,10 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * * \return 0 if the signing operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code + * or an \c MBEDTLS_ERR_RSA_XXX error code * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * \note The \c sig buffer must be as large as the size + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -553,11 +822,12 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, * * \param ctx RSA context * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding and for - * MBEDTLS_RSA_PRIVATE) + * \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE + * \param md_alg a \c MBEDTLS_MD_XXX (use \c MBEDTLS_MD_NONE + * for signing raw data) + * \param hashlen message digest length (for \c MBEDTLS_MD_NONE only) * \param hash buffer holding the message digest * \param sig buffer that will hold the ciphertext * @@ -571,13 +841,13 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * * \return 0 if the signing operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code + * or an \c MBEDTLS_ERR_RSA_XXX error code * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * \note The \c sig buffer must be as large as the size + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). * - * \note The hash_id in the RSA context is the one used for the - * encoding. md_alg in the function call is the type of hash + * \note The \c hash_id in the RSA context is the one used for the + * encoding. \c md_alg in the function call is the type of hash * that is encoded. According to RFC 3447 it is advised to * keep both hashes the same. */ @@ -596,11 +866,11 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, * the message digest * * \param ctx points to an RSA public key - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE + * \param md_alg a \c MBEDTLS_MD_XXX (use \c MBEDTLS_MD_NONE for signing raw data) + * \param hashlen message digest length (for \c MBEDTLS_MD_NONE only) * \param hash buffer holding the message digest * \param sig buffer holding the ciphertext * @@ -614,10 +884,10 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * * \return 0 if the verify operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code + * or an \c MBEDTLS_ERR_RSA_XXX error code * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * \note The \c sig buffer must be as large as the size + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). * * \note In case of PKCS#1 v2.1 encoding, see comments on * \c mbedtls_rsa_rsassa_pss_verify() about md_alg and hash_id. @@ -635,11 +905,12 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, * \brief Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY) * * \param ctx points to an RSA public key - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE + * \param md_alg a \c MBEDTLS_MD_XXX (use \c MBEDTLS_MD_NONE + * for signing raw data) + * \param hashlen message digest length (for \c MBEDTLS_MD_NONE only) * \param hash buffer holding the message digest * \param sig buffer holding the ciphertext * @@ -653,10 +924,10 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * * \return 0 if the verify operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code + * or an \c MBEDTLS_ERR_RSA_XXX error code * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * \note The \c sig buffer must be as large as the size + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -672,11 +943,11 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, * (This is the "simple" version.) * * \param ctx points to an RSA public key - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE + * \param md_alg a \c MBEDTLS_MD_XXX (use \c MBEDTLS_MD_NONE for signing raw data) + * \param hashlen message digest length (for \c MBEDTLS_MD_NONE only) * \param hash buffer holding the message digest * \param sig buffer holding the ciphertext * @@ -690,16 +961,16 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, * return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION. * * \return 0 if the verify operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code + * or an \c MBEDTLS_ERR_RSA_XXX error code * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * \note The \c sig buffer must be as large as the size + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). * - * \note The hash_id in the RSA context is the one used for the - * verification. md_alg in the function call is the type of + * \note The \c hash_id in the RSA context is the one used for the + * verification. \c md_alg in the function call is the type of * hash that is verified. According to RFC 3447 it is advised to - * keep both hashes the same. If hash_id in the RSA context is - * unset, the md_alg from the function call is used. + * keep both hashes the same. If \c hash_id in the RSA context is + * unset, the \c md_alg from the function call is used. */ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -715,24 +986,24 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, * (This is the version with "full" options.) * * \param ctx points to an RSA public key - * \param f_rng RNG function (Only needed for MBEDTLS_RSA_PRIVATE) + * \param f_rng RNG function (Only needed for \c MBEDTLS_RSA_PRIVATE) * \param p_rng RNG parameter - * \param mode MBEDTLS_RSA_PUBLIC or MBEDTLS_RSA_PRIVATE - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) + * \param mode \c MBEDTLS_RSA_PUBLIC or \c MBEDTLS_RSA_PRIVATE + * \param md_alg a \c MBEDTLS_MD_XXX (use \c MBEDTLS_MD_NONE for signing raw data) + * \param hashlen message digest length (for \c MBEDTLS_MD_NONE only) * \param hash buffer holding the message digest * \param mgf1_hash_id message digest used for mask generation * \param expected_salt_len Length of the salt used in padding, use - * MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length + * \c MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length * \param sig buffer holding the ciphertext * * \return 0 if the verify operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code + * or an \c MBEDTLS_ERR_RSA_XXX error code * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * \note The \c sig buffer must be as large as the size + * of \c ctx->N (eg. 128 bytes if RSA-1024 is used). * - * \note The hash_id in the RSA context is ignored. + * \note The \c hash_id in the RSA context is ignored. */ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -752,7 +1023,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, * \param src Source context * * \return 0 on success, - * MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure + * \c MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure */ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ); @@ -763,6 +1034,18 @@ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) */ void mbedtls_rsa_free( mbedtls_rsa_context *ctx ); +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_RSA_ALT */ +#include "rsa_alt.h" +#endif /* MBEDTLS_RSA_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + /** * \brief Checkup routine * @@ -774,6 +1057,4 @@ int mbedtls_rsa_self_test( int verbose ); } #endif -#endif /* MBEDTLS_RSA_C */ - #endif /* rsa.h */ diff --git a/include/mbedtls/rsa_internal.h b/include/mbedtls/rsa_internal.h new file mode 100644 index 000000000..7e6a2ecd9 --- /dev/null +++ b/include/mbedtls/rsa_internal.h @@ -0,0 +1,215 @@ +/** + * \file rsa_internal.h + * + * \brief Context-independent RSA helper functions + * + * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + * + * + * This file declares some RSA-related helper functions useful when + * implementing the RSA interface. They are public and provided in a + * separate compilation unit in order to make it easy for designers of + * alternative RSA implementations to use them in their code, as it is + * conceived that the functionality they provide will be necessary + * for most complete implementations. + * + * End-users of Mbed TLS not intending to re-implement the RSA functionality + * are not expected to get into the need of making use of these functions directly, + * but instead should be able to use the functions declared in rsa.h. + * + * There are two classes of helper functions: + * (1) Parameter-generating helpers. These are: + * - mbedtls_rsa_deduce_primes + * - mbedtls_rsa_deduce_private_exponent + * - mbedtls_rsa_deduce_crt + * Each of these functions takes a set of core RSA parameters + * and generates some other, or CRT related parameters. + * (2) Parameter-checking helpers. These are: + * - mbedtls_rsa_validate_params + * - mbedtls_rsa_validate_crt + * They take a set of core or CRT related RSA parameters + * and check their validity. + * + */ + +#ifndef MBEDTLS_RSA_INTERNAL_H +#define MBEDTLS_RSA_INTERNAL_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief Compute RSA prime moduli P, Q from public modulus N=PQ + * and a pair of private and public key. + * + * \note This is a 'static' helper function not operating on + * an RSA context. Alternative implementations need not + * overwrite it. + * + * \param N RSA modulus N = PQ, with P, Q to be found + * \param E RSA public exponent + * \param D RSA private exponent + * \param P Pointer to MPI holding first prime factor of N on success + * \param Q Pointer to MPI holding second prime factor of N on success + * + * \return + * - 0 if successful. In this case, P and Q constitute a + * factorization of N. + * - A non-zero error code otherwise. + * + * \note It is neither checked that P, Q are prime nor that + * D, E are modular inverses wrt. P-1 and Q-1. For that, + * use the helper function \c mbedtls_rsa_validate_params. + * + */ +int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, mbedtls_mpi const *E, + mbedtls_mpi const *D, + mbedtls_mpi *P, mbedtls_mpi *Q ); + +/** + * \brief Compute RSA private exponent from + * prime moduli and public key. + * + * \note This is a 'static' helper function not operating on + * an RSA context. Alternative implementations need not + * overwrite it. + * + * \param P First prime factor of RSA modulus + * \param Q Second prime factor of RSA modulus + * \param E RSA public exponent + * \param D Pointer to MPI holding the private exponent on success. + * + * \return + * - 0 if successful. In this case, D is set to a simultaneous + * modular inverse of E modulo both P-1 and Q-1. + * - A non-zero error code otherwise. + * + * \note This function does not check whether P and Q are primes. + * + */ +int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P, + mbedtls_mpi const *Q, + mbedtls_mpi const *E, + mbedtls_mpi *D ); + + +/** + * \brief Generate RSA-CRT parameters + * + * \note This is a 'static' helper function not operating on + * an RSA context. Alternative implementations need not + * overwrite it. + * + * \param P First prime factor of N + * \param Q Second prime factor of N + * \param D RSA private exponent + * \param DP Output variable for D modulo P-1 + * \param DQ Output variable for D modulo Q-1 + * \param QP Output variable for the modular inverse of Q modulo P. + * + * \return 0 on success, non-zero error code otherwise. + * + * \note This function does not check whether P, Q are + * prime and whether D is a valid private exponent. + * + */ +int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, mbedtls_mpi *DP, + mbedtls_mpi *DQ, mbedtls_mpi *QP ); + + +/** + * \brief Check validity of core RSA parameters + * + * \note This is a 'static' helper function not operating on + * an RSA context. Alternative implementations need not + * overwrite it. + * + * \param N RSA modulus N = PQ + * \param P First prime factor of N + * \param Q Second prime factor of N + * \param D RSA private exponent + * \param E RSA public exponent + * \param f_rng PRNG to be used for primality check, or NULL + * \param p_rng PRNG context for f_rng, or NULL + * + * \return + * - 0 if the following conditions are satisfied + * if all relevant parameters are provided: + * - P prime if f_rng != NULL (%) + * - Q prime if f_rng != NULL (%) + * - 1 < N = P * Q + * - 1 < D, E < N + * - D and E are modular inverses modulo P-1 and Q-1 + * (%) This is only done if MBEDTLS_GENPRIME is defined. + * - A non-zero error code otherwise. + * + * \note The function can be used with a restricted set of arguments + * to perform specific checks only. E.g., calling it with + * (-,P,-,-,-) and a PRNG amounts to a primality check for P. + */ +int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, + const mbedtls_mpi *Q, const mbedtls_mpi *D, + const mbedtls_mpi *E, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Check validity of RSA CRT parameters + * + * \note This is a 'static' helper function not operating on + * an RSA context. Alternative implementations need not + * overwrite it. + * + * \param P First prime factor of RSA modulus + * \param Q Second prime factor of RSA modulus + * \param D RSA private exponent + * \param DP MPI to check for D modulo P-1 + * \param DQ MPI to check for D modulo P-1 + * \param QP MPI to check for the modular inverse of Q modulo P. + * + * \return + * - 0 if the following conditions are satisfied: + * - D = DP mod P-1 if P, D, DP != NULL + * - Q = DQ mod P-1 if P, D, DQ != NULL + * - QP = Q^-1 mod P if P, Q, QP != NULL + * - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed, + * potentially including \c MBEDTLS_ERR_MPI_XXX if some + * MPI calculations failed. + * - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient + * data was provided to check DP, DQ or QP. + * + * \note The function can be used with a restricted set of arguments + * to perform specific checks only. E.g., calling it with the + * parameters (P, -, D, DP, -, -) will check DP = D mod P-1. + */ +int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, const mbedtls_mpi *DP, + const mbedtls_mpi *DQ, const mbedtls_mpi *QP ); + +#endif /* rsa_internal.h */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index c332d4577..e02229d03 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -48,6 +48,7 @@ set(src_crypto platform.c ripemd160.c rsa.c + rsa_internal.c sha1.c sha256.c sha512.c diff --git a/library/Makefile b/library/Makefile index 28f92315a..541d47fe9 100644 --- a/library/Makefile +++ b/library/Makefile @@ -59,9 +59,9 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \ padlock.o pem.o pk.o \ pk_wrap.o pkcs12.o pkcs5.o \ pkparse.o pkwrite.o platform.o \ - ripemd160.o rsa.o sha1.o \ - sha256.o sha512.o threading.o \ - timing.o version.o \ + ripemd160.o rsa_internal.o rsa.o \ + sha1.o sha256.o sha512.o \ + threading.o timing.o version.o \ version_features.o xtea.o OBJS_X509= certs.o pkcs11.o x509.o \ diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 2c164b7df..a4bb35fc8 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -68,7 +68,8 @@ static int rsa_can_do( mbedtls_pk_type_t type ) static size_t rsa_get_bitlen( const void *ctx ) { - return( 8 * ((const mbedtls_rsa_context *) ctx)->len ); + const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx; + return( 8 * mbedtls_rsa_get_len( rsa ) ); } static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, @@ -76,21 +77,23 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, const unsigned char *sig, size_t sig_len ) { int ret; + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + size_t rsa_len = mbedtls_rsa_get_len( rsa ); #if SIZE_MAX > UINT_MAX if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); #endif /* SIZE_MAX > UINT_MAX */ - if( sig_len < ((mbedtls_rsa_context *) ctx)->len ) + if( sig_len < rsa_len ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL, + if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, md_alg, (unsigned int) hash_len, hash, sig ) ) != 0 ) return( ret ); - if( sig_len > ((mbedtls_rsa_context *) ctx)->len ) + if( sig_len > rsa_len ) return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); return( 0 ); @@ -101,14 +104,16 @@ static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + #if SIZE_MAX > UINT_MAX if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); #endif /* SIZE_MAX > UINT_MAX */ - *sig_len = ((mbedtls_rsa_context *) ctx)->len; + *sig_len = mbedtls_rsa_get_len( rsa ); - return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, + return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, md_alg, (unsigned int) hash_len, hash, sig ) ); } @@ -117,10 +122,12 @@ static int rsa_decrypt_wrap( void *ctx, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - if( ilen != ((mbedtls_rsa_context *) ctx)->len ) + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + + if( ilen != mbedtls_rsa_get_len( rsa ) ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng, + return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); } @@ -129,13 +136,14 @@ static int rsa_encrypt_wrap( void *ctx, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - *olen = ((mbedtls_rsa_context *) ctx)->len; + mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; + *olen = mbedtls_rsa_get_len( rsa ); if( *olen > osize ) return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); - return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx, - f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) ); + return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, + ilen, input, output ) ); } static int rsa_check_pair_wrap( const void *pub, const void *prv ) diff --git a/library/pkparse.c b/library/pkparse.c index 387111f09..f97d89ea1 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -523,19 +523,36 @@ static int pk_get_rsapubkey( unsigned char **p, return( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - if( ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->N ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->E ) ) != 0 ) + /* Import N */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); + if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0, + NULL, 0, NULL, 0 ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); + + *p += len; + + /* Import E */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); + + if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, + NULL, 0, *p, len ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); + + *p += len; + + if( mbedtls_rsa_complete( rsa ) != 0 || + mbedtls_rsa_check_pubkey( rsa ) != 0 ) + { + return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); + } + if( *p != end ) return( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - if( ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 ) - return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); - - rsa->len = mbedtls_mpi_size( &rsa->N ); - return( 0 ); } #endif /* MBEDTLS_RSA_C */ @@ -646,10 +663,13 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen ) { - int ret; + int ret, version; size_t len; unsigned char *p, *end; + mbedtls_mpi T; + mbedtls_mpi_init( &T ); + p = (unsigned char *) key; end = p + keylen; @@ -677,45 +697,88 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, end = p + len; - if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) + if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } - if( rsa->ver != 0 ) + if( version != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); } - if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || - ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 ) - { - mbedtls_rsa_free( rsa ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); - } + /* Import N */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_INTEGER ) ) != 0 || + ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0, + NULL, 0, NULL, 0 ) ) != 0 ) + goto cleanup; + p += len; - rsa->len = mbedtls_mpi_size( &rsa->N ); + /* Import E */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_INTEGER ) ) != 0 || + ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, + NULL, 0, p, len ) ) != 0 ) + goto cleanup; + p += len; + + /* Import D */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_INTEGER ) ) != 0 || + ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, + p, len, NULL, 0 ) ) != 0 ) + goto cleanup; + p += len; + + /* Import P */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_INTEGER ) ) != 0 || + ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0, + NULL, 0, NULL, 0 ) ) != 0 ) + goto cleanup; + p += len; + + /* Import Q */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_INTEGER ) ) != 0 || + ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len, + NULL, 0, NULL, 0 ) ) != 0 ) + goto cleanup; + p += len; + + /* Complete the RSA private key */ + if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 ) + goto cleanup; + + /* Check optional parameters */ + if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ) + goto cleanup; if( p != end ) { - mbedtls_rsa_free( rsa ); - return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ; } - if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 ) +cleanup: + + mbedtls_mpi_free( &T ); + + if( ret != 0 ) { + /* Wrap error code if it's coming from a lower level */ + if( ( ret & 0xff80 ) == 0 ) + ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret; + else + ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; + mbedtls_rsa_free( rsa ); - return( ret ); } - return( 0 ); + return( ret ); } #endif /* MBEDTLS_RSA_C */ diff --git a/library/pkwrite.c b/library/pkwrite.c index 83b798c11..8eabd889b 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -62,13 +62,31 @@ * } */ static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, - mbedtls_rsa_context *rsa ) + mbedtls_rsa_context *rsa ) { int ret; size_t len = 0; + mbedtls_mpi T; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) ); + mbedtls_mpi_init( &T ); + + /* Export E */ + if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export N */ + if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) + goto end_of_export; + len += ret; + +end_of_export: + + mbedtls_mpi_free( &T ); + if( ret < 0 ) + return( ret ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | @@ -83,7 +101,7 @@ static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, * EC public key is an EC point */ static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec ) + mbedtls_ecp_keypair *ec ) { int ret; size_t len = 0; @@ -111,7 +129,7 @@ static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, * } */ static int pk_write_ec_param( unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec ) + mbedtls_ecp_keypair *ec ) { int ret; size_t len = 0; @@ -128,7 +146,7 @@ static int pk_write_ec_param( unsigned char **p, unsigned char *start, #endif /* MBEDTLS_ECP_C */ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, - const mbedtls_pk_context *key ) + const mbedtls_pk_context *key ) { int ret; size_t len = 0; @@ -205,21 +223,79 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_ #if defined(MBEDTLS_RSA_C) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) { + mbedtls_mpi T; /* Temporary holding the exported parameters */ mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); + /* + * Export the parameters one after another to avoid simultaneous copies. + */ + mbedtls_mpi_init( &T ); + + /* Export QP */ + if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export DQ */ + if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export DP */ + if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export Q */ + if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, + &T, NULL, NULL ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export P */ + if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T, + NULL, NULL, NULL ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export D */ + if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, + NULL, &T, NULL ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export E */ + if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, + NULL, NULL, &T ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + /* Export N */ + if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, + NULL, NULL, NULL ) ) != 0 || + ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) + goto end_of_export; + len += ret; + + end_of_export: + + mbedtls_mpi_free( &T ); + if( ret < 0 ) + return( ret ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, + buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); } else #endif /* MBEDTLS_RSA_C */ diff --git a/library/rsa.c b/library/rsa.c index bdd2538c3..ad1ef6db2 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -18,6 +18,7 @@ * * This file is part of mbed TLS (https://tls.mbed.org) */ + /* * The following sources were referenced in the design of this implementation * of the RSA algorithm: @@ -45,6 +46,7 @@ #if defined(MBEDTLS_RSA_C) #include "mbedtls/rsa.h" +#include "mbedtls/rsa_internal.h" #include "mbedtls/oid.h" #include @@ -66,11 +68,378 @@ #define mbedtls_free free #endif +#if !defined(MBEDTLS_RSA_ALT) + /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } +int mbedtls_rsa_import( mbedtls_rsa_context *ctx, + const mbedtls_mpi *N, + const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, const mbedtls_mpi *E ) +{ + int ret; + + if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) || + ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) || + ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) || + ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) || + ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + } + + if( N != NULL ) + ctx->len = mbedtls_mpi_size( &ctx->N ); + + return( 0 ); +} + +int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, + unsigned char const *N, size_t N_len, + unsigned char const *P, size_t P_len, + unsigned char const *Q, size_t Q_len, + unsigned char const *D, size_t D_len, + unsigned char const *E, size_t E_len ) +{ + int ret; + + if( N != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) ); + ctx->len = mbedtls_mpi_size( &ctx->N ); + } + + if( P != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) ); + + if( Q != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) ); + + if( D != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) ); + + if( E != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) ); + +cleanup: + + if( ret != 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + + return( 0 ); +} + +/* + * Checks whether the context fields are set in such a way + * that the RSA primitives will be able to execute without error. + * It does *not* make guarantees for consistency of the parameters. + */ +static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv, + int blinding_needed ) +{ +#if !defined(MBEDTLS_RSA_NO_CRT) + /* blinding_needed is only used for NO_CRT to decide whether + * P,Q need to be present or not. */ + ((void) blinding_needed); +#endif + + if( ctx->len != mbedtls_mpi_size( &ctx->N ) || + ctx->len > MBEDTLS_MPI_MAX_SIZE ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + + /* + * 1. Modular exponentiation needs positive, odd moduli. + */ + + /* Modular exponentiation wrt. N is always used for + * RSA public key operations. */ + if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 || + mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + +#if !defined(MBEDTLS_RSA_NO_CRT) + /* Modular exponentiation for P and Q is only + * used for private key operations and if CRT + * is used. */ + if( is_priv && + ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || + mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 || + mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 || + mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } +#endif /* !MBEDTLS_RSA_NO_CRT */ + + /* + * 2. Exponents must be positive + */ + + /* Always need E for public key operations */ + if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_RSA_NO_CRT) + /* For private key operations, use D or DP & DQ + * as (unblinded) exponents. */ + if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#else + if( is_priv && + ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 || + mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } +#endif /* MBEDTLS_RSA_NO_CRT */ + + /* Blinding shouldn't make exponents negative either, + * so check that P, Q >= 1 if that hasn't yet been + * done as part of 1. */ +#if defined(MBEDTLS_RSA_NO_CRT) + if( is_priv && blinding_needed && + ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || + mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } +#endif + + /* It wouldn't lead to an error if it wasn't satisfied, + * but check for QP >= 1 nonetheless. */ +#if !defined(MBEDTLS_RSA_NO_CRT) + if( is_priv && + mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } +#endif + + return( 0 ); +} + +int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) +{ + int ret = 0; + + const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 ); + const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 ); + const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 ); + const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); + const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); + + /* + * Check whether provided parameters are enough + * to deduce all others. The following incomplete + * parameter sets for private keys are supported: + * + * (1) P, Q missing. + * (2) D and potentially N missing. + * + */ + + const int n_missing = have_P && have_Q && have_D && have_E; + const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E; + const int d_missing = have_P && have_Q && !have_D && have_E; + const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E; + + /* These three alternatives are mutually exclusive */ + const int is_priv = n_missing || pq_missing || d_missing; + + if( !is_priv && !is_pub ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + /* + * Step 1: Deduce N if P, Q are provided. + */ + + if( !have_N && have_P && have_Q ) + { + if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, + &ctx->Q ) ) != 0 ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + } + + ctx->len = mbedtls_mpi_size( &ctx->N ); + } + + /* + * Step 2: Deduce and verify all remaining core parameters. + */ + + if( pq_missing ) + { + ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D, + &ctx->P, &ctx->Q ); + if( ret != 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + + } + else if( d_missing ) + { + if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P, + &ctx->Q, + &ctx->E, + &ctx->D ) ) != 0 ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + } + } + + /* + * Step 3: Deduce all additional parameters specific + * to our current RSA implementation. + */ + +#if !defined(MBEDTLS_RSA_NO_CRT) + if( is_priv ) + { + ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, + &ctx->DP, &ctx->DQ, &ctx->QP ); + if( ret != 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + } +#endif /* MBEDTLS_RSA_NO_CRT */ + + /* + * Step 3: Basic sanity checks + */ + + return( rsa_check_context( ctx, is_priv, 1 ) ); +} + +int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, + unsigned char *N, size_t N_len, + unsigned char *P, size_t P_len, + unsigned char *Q, size_t Q_len, + unsigned char *D, size_t D_len, + unsigned char *E, size_t E_len ) +{ + int ret = 0; + + /* Check if key is private or public */ + const int is_priv = + mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; + + if( !is_priv ) + { + /* If we're trying to export private parameters for a public key, + * something must be wrong. */ + if( P != NULL || Q != NULL || D != NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + } + + if( N != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) ); + + if( P != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) ); + + if( Q != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) ); + + if( D != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) ); + + if( E != NULL ) + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) ); + +cleanup: + + return( ret ); +} + +int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, + mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, + mbedtls_mpi *D, mbedtls_mpi *E ) +{ + int ret; + + /* Check if key is private or public */ + int is_priv = + mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; + + if( !is_priv ) + { + /* If we're trying to export private parameters for a public key, + * something must be wrong. */ + if( P != NULL || Q != NULL || D != NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + } + + /* Export all requested core parameters. */ + + if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) || + ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) || + ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) || + ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) || + ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Export CRT parameters + * This must also be implemented if CRT is not used, for being able to + * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt + * can be used in this case. + */ +int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, + mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ) +{ + int ret; + + /* Check if key is private or public */ + int is_priv = + mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && + mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; + + if( !is_priv ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + +#if !defined(MBEDTLS_RSA_NO_CRT) + /* Export all requested blinding parameters. */ + if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) || + ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) || + ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + } +#else + if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, + DP, DQ, QP ) ) != 0 ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); + } +#endif + + return( 0 ); +} + /* * Initialize an RSA context */ @@ -96,6 +465,16 @@ void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id ctx->hash_id = hash_id; } +/* + * Get length in bytes of RSA modulus + */ + +size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ) +{ + return( ctx->len ); +} + + #if defined(MBEDTLS_GENPRIME) /* @@ -107,7 +486,7 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, unsigned int nbits, int exponent ) { int ret; - mbedtls_mpi P1, Q1, H, G; + mbedtls_mpi H, G; if( f_rng == NULL || nbits < 128 || exponent < 3 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -115,8 +494,8 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, if( nbits % 2 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); - mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &H ); + mbedtls_mpi_init( &G ); /* * find primes P and Q with Q < P so that: @@ -127,10 +506,10 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, do { MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0, - f_rng, p_rng ) ); + f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0, - f_rng, p_rng ) ); + f_rng, p_rng ) ); if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) continue; @@ -140,31 +519,43 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, continue; if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) - mbedtls_mpi_swap( &ctx->P, &ctx->Q ); + mbedtls_mpi_swap( &ctx->P, &ctx->Q ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) ); + /* Temporarily replace P,Q by P-1, Q-1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); } while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ); + /* Restore P,Q */ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) ); + + ctx->len = mbedtls_mpi_size( &ctx->N ); + /* * D = E^-1 mod ((P-1)*(Q-1)) * DP = D mod (P - 1) * DQ = D mod (Q - 1) * QP = Q^-1 mod P */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D , &ctx->E, &H ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) ); - ctx->len = ( mbedtls_mpi_bitlen( &ctx->N ) + 7 ) >> 3; + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) ); + +#if !defined(MBEDTLS_RSA_NO_CRT) + MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, + &ctx->DP, &ctx->DQ, &ctx->QP ) ); +#endif /* MBEDTLS_RSA_NO_CRT */ + + /* Double-check */ + MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) ); cleanup: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &H ); + mbedtls_mpi_free( &G ); if( ret != 0 ) { @@ -182,82 +573,48 @@ cleanup: */ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) { - if( !ctx->N.p || !ctx->E.p ) + if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 ) return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - if( ( ctx->N.p[0] & 1 ) == 0 || - ( ctx->E.p[0] & 1 ) == 0 ) + if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ) + { return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } - if( mbedtls_mpi_bitlen( &ctx->N ) < 128 || - mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - - if( mbedtls_mpi_bitlen( &ctx->E ) < 2 || + if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 || + mbedtls_mpi_bitlen( &ctx->E ) < 2 || mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) + { return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } return( 0 ); } /* - * Check a private RSA key + * Check for the consistency of all fields in an RSA private key context */ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) { - int ret; - mbedtls_mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP; - - if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 ) - return( ret ); - - if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); - - mbedtls_mpi_init( &PQ ); mbedtls_mpi_init( &DE ); mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); - mbedtls_mpi_init( &H ); mbedtls_mpi_init( &I ); mbedtls_mpi_init( &G ); mbedtls_mpi_init( &G2 ); - mbedtls_mpi_init( &L1 ); mbedtls_mpi_init( &L2 ); mbedtls_mpi_init( &DP ); mbedtls_mpi_init( &DQ ); - mbedtls_mpi_init( &QP ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G2, &P1, &Q1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L1, &L2, &H, &G2 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &I, &DE, &L1 ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DP, &ctx->D, &P1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) ); - /* - * Check for a valid PKCS1v2 private key - */ - if( mbedtls_mpi_cmp_mpi( &PQ, &ctx->N ) != 0 || - mbedtls_mpi_cmp_mpi( &DP, &ctx->DP ) != 0 || - mbedtls_mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 || - mbedtls_mpi_cmp_mpi( &QP, &ctx->QP ) != 0 || - mbedtls_mpi_cmp_int( &L2, 0 ) != 0 || - mbedtls_mpi_cmp_int( &I, 1 ) != 0 || - mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) + if( mbedtls_rsa_check_pubkey( ctx ) != 0 || + rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 ) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); } -cleanup: - mbedtls_mpi_free( &PQ ); mbedtls_mpi_free( &DE ); mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); - mbedtls_mpi_free( &H ); mbedtls_mpi_free( &I ); mbedtls_mpi_free( &G ); mbedtls_mpi_free( &G2 ); - mbedtls_mpi_free( &L1 ); mbedtls_mpi_free( &L2 ); mbedtls_mpi_free( &DP ); mbedtls_mpi_free( &DQ ); - mbedtls_mpi_free( &QP ); + if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q, + &ctx->D, &ctx->E, NULL, NULL ) != 0 ) + { + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } - if( ret == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ) - return( ret ); - - if( ret != 0 ) - return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + ret ); +#if !defined(MBEDTLS_RSA_NO_CRT) + else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D, + &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 ) + { + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } +#endif return( 0 ); } @@ -265,9 +622,10 @@ cleanup: /* * Check if contexts holding a public and private key match */ -int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv ) +int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, + const mbedtls_rsa_context *prv ) { - if( mbedtls_rsa_check_pubkey( pub ) != 0 || + if( mbedtls_rsa_check_pubkey( pub ) != 0 || mbedtls_rsa_check_privkey( prv ) != 0 ) { return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); @@ -293,6 +651,9 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, size_t olen; mbedtls_mpi T; + if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + mbedtls_mpi_init( &T ); #if defined(MBEDTLS_THREADING_C) @@ -409,14 +770,15 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, mbedtls_mpi *DQ = &ctx->DQ; #endif - /* Make sure we have private key info, prevent possible misuse */ - if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL ) + if( rsa_check_context( ctx, 1 /* private key checks */, + f_rng != NULL /* blinding y/n */ ) != 0 ) + { return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R ); - if( f_rng != NULL ) { #if defined(MBEDTLS_RSA_NO_CRT) @@ -1630,13 +1992,16 @@ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) ); + +#if !defined(MBEDTLS_RSA_NO_CRT) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) ); - - MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) ); +#endif + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) ); @@ -1657,16 +2022,23 @@ cleanup: void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) { mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf ); - mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->RN ); - mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); mbedtls_mpi_free( &ctx->DP ); - mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P ); mbedtls_mpi_free( &ctx->D ); + mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D ); + mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P ); mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N ); +#if !defined(MBEDTLS_RSA_NO_CRT) + mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); + mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); + mbedtls_mpi_free( &ctx->DP ); +#endif /* MBEDTLS_RSA_NO_CRT */ + #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_free( &ctx->mutex ); #endif } +#endif /* !MBEDTLS_RSA_ALT */ + #if defined(MBEDTLS_SELF_TEST) #include "mbedtls/sha1.h" @@ -1706,21 +2078,6 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) "910E4168387E3C30AA1E00C339A79508" \ "8452DD96A9A5EA5D9DCA68DA636032AF" -#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \ - "3C94D22288ACD763FD8E5600ED4A702D" \ - "F84198A5F06C2E72236AE490C93F07F8" \ - "3CC559CD27BC2D1CA488811730BB5725" - -#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \ - "D8AAEA56749EA28623272E4F7D0592AF" \ - "7C1F1313CAC9471B5C523BFE592F517B" \ - "407A1BD76C164B93DA2D32A383E58357" - -#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \ - "F38D18D2B2F0E2DD275AA977E2BF4411" \ - "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \ - "A74206CEC169D74BF5A8C50D6F48EA08" - #define PT_LEN 24 #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" @@ -1763,17 +2120,23 @@ int mbedtls_rsa_self_test( int verbose ) unsigned char sha1sum[20]; #endif + mbedtls_mpi K; + + mbedtls_mpi_init( &K ); mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); - rsa.len = KEY_LEN; - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.N , 16, RSA_N ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.E , 16, RSA_E ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.D , 16, RSA_D ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.P , 16, RSA_P ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.Q , 16, RSA_Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DP, 16, RSA_DP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.QP, 16, RSA_QP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) ); + MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) ); + MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) ); + MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) ); + MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) ); + MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) ); + + MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) ); if( verbose != 0 ) mbedtls_printf( " RSA key validation: " ); @@ -1792,8 +2155,9 @@ int mbedtls_rsa_self_test( int verbose ) memcpy( rsa_plaintext, RSA_PT, PT_LEN ); - if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, PT_LEN, - rsa_plaintext, rsa_ciphertext ) != 0 ) + if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, + PT_LEN, rsa_plaintext, + rsa_ciphertext ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); @@ -1804,9 +2168,9 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "passed\n PKCS#1 decryption : " ); - if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, &len, - rsa_ciphertext, rsa_decrypted, - sizeof(rsa_decrypted) ) != 0 ) + if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, + &len, rsa_ciphertext, rsa_decrypted, + sizeof(rsa_decrypted) ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); @@ -1831,8 +2195,9 @@ int mbedtls_rsa_self_test( int verbose ) mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum ); - if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0, - sha1sum, rsa_ciphertext ) != 0 ) + if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, + MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); @@ -1843,8 +2208,9 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "passed\n PKCS#1 sig. verify: " ); - if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, - sha1sum, rsa_ciphertext ) != 0 ) + if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, + MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); @@ -1860,6 +2226,7 @@ int mbedtls_rsa_self_test( int verbose ) mbedtls_printf( "\n" ); cleanup: + mbedtls_mpi_free( &K ); mbedtls_rsa_free( &rsa ); #else /* MBEDTLS_PKCS1_V15 */ ((void) verbose); diff --git a/library/rsa_internal.c b/library/rsa_internal.c new file mode 100644 index 000000000..507009f13 --- /dev/null +++ b/library/rsa_internal.c @@ -0,0 +1,487 @@ +/* + * Helper functions for the RSA module + * + * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_RSA_C) + +#include "mbedtls/rsa.h" +#include "mbedtls/bignum.h" +#include "mbedtls/rsa_internal.h" + +/* + * Compute RSA prime factors from public and private exponents + * + * Summary of algorithm: + * Setting F := lcm(P-1,Q-1), the idea is as follows: + * + * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2) + * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the + * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four + * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1) + * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime + * factors of N. + * + * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same + * construction still applies since (-)^K is the identity on the set of + * roots of 1 in Z/NZ. + * + * The public and private key primitives (-)^E and (-)^D are mutually inverse + * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e. + * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L. + * Splitting L = 2^t * K with K odd, we have + * + * DE - 1 = FL = (F/2) * (2^(t+1)) * K, + * + * so (F / 2) * K is among the numbers + * + * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord + * + * where ord is the order of 2 in (DE - 1). + * We can therefore iterate through these numbers apply the construction + * of (a) and (b) above to attempt to factor N. + * + */ +int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, + mbedtls_mpi const *E, mbedtls_mpi const *D, + mbedtls_mpi *P, mbedtls_mpi *Q ) +{ + int ret = 0; + + uint16_t attempt; /* Number of current attempt */ + uint16_t iter; /* Number of squares computed in the current attempt */ + + uint16_t order; /* Order of 2 in DE - 1 */ + + mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */ + mbedtls_mpi K; /* Temporary holding the current candidate */ + + const unsigned char primes[] = { 2, + 3, 5, 7, 11, 13, 17, 19, 23, + 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, + 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, + 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251 + }; + + const size_t num_primes = sizeof( primes ) / sizeof( *primes ); + + if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || + mbedtls_mpi_cmp_int( D, 1 ) <= 0 || + mbedtls_mpi_cmp_mpi( D, N ) >= 0 || + mbedtls_mpi_cmp_int( E, 1 ) <= 0 || + mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) + { + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + } + + /* + * Initializations and temporary changes + */ + + mbedtls_mpi_init( &K ); + mbedtls_mpi_init( &T ); + + /* T := DE - 1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, D, E ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &T, &T, 1 ) ); + + if( ( order = (uint16_t) mbedtls_mpi_lsb( &T ) ) == 0 ) + { + ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + goto cleanup; + } + + /* After this operation, T holds the largest odd divisor of DE - 1. */ + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &T, order ) ); + + /* + * Actual work + */ + + /* Skip trying 2 if N == 1 mod 8 */ + attempt = 0; + if( N->p[0] % 8 == 1 ) + attempt = 1; + + for( ; attempt < num_primes; ++attempt ) + { + mbedtls_mpi_lset( &K, primes[attempt] ); + + /* Check if gcd(K,N) = 1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); + if( mbedtls_mpi_cmp_int( P, 1 ) != 0 ) + continue; + + /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ... + * and check whether they have nontrivial GCD with N. */ + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, &T, N, + Q /* temporarily use Q for storing Montgomery + * multiplication helper values */ ) ); + + for( iter = 1; iter <= order; ++iter ) + { + /* If we reach 1 prematurely, there's no point + * in continuing to square K */ + if( mbedtls_mpi_cmp_int( &K, 1 ) == 0 ) + break; + + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); + + if( mbedtls_mpi_cmp_int( P, 1 ) == 1 && + mbedtls_mpi_cmp_mpi( P, N ) == -1 ) + { + /* + * Have found a nontrivial divisor P of N. + * Set Q := N / P. + */ + + MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, NULL, N, P ) ); + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) ); + } + + /* + * If we get here, then either we prematurely aborted the loop because + * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must + * be 1 if D,E,N were consistent. + * Check if that's the case and abort if not, to avoid very long, + * yet eventually failing, computations if N,D,E were not sane. + */ + if( mbedtls_mpi_cmp_int( &K, 1 ) != 0 ) + { + break; + } + } + + ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + +cleanup: + + mbedtls_mpi_free( &K ); + mbedtls_mpi_free( &T ); + return( ret ); +} + +/* + * Given P, Q and the public exponent E, deduce D. + * This is essentially a modular inversion. + */ +int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P, + mbedtls_mpi const *Q, + mbedtls_mpi const *E, + mbedtls_mpi *D ) +{ + int ret = 0; + mbedtls_mpi K, L; + + if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || + mbedtls_mpi_cmp_int( Q, 1 ) <= 0 || + mbedtls_mpi_cmp_int( E, 0 ) == 0 ) + { + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + } + + mbedtls_mpi_init( &K ); + mbedtls_mpi_init( &L ); + + /* Temporarily put K := P-1 and L := Q-1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); + + /* Temporarily put D := gcd(P-1, Q-1) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, &K, &L ) ); + + /* K := LCM(P-1, Q-1) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &L ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) ); + + /* Compute modular inverse of E in LCM(P-1, Q-1) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) ); + +cleanup: + + mbedtls_mpi_free( &K ); + mbedtls_mpi_free( &L ); + + return( ret ); +} + +/* + * Check that RSA CRT parameters are in accordance with core parameters. + */ +int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, const mbedtls_mpi *DP, + const mbedtls_mpi *DQ, const mbedtls_mpi *QP ) +{ + int ret = 0; + + mbedtls_mpi K, L; + mbedtls_mpi_init( &K ); + mbedtls_mpi_init( &L ); + + /* Check that DP - D == 0 mod P - 1 */ + if( DP != NULL ) + { + if( P == NULL ) + { + ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); + + if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + } + + /* Check that DQ - D == 0 mod Q - 1 */ + if( DQ != NULL ) + { + if( Q == NULL ) + { + ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); + + if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + } + + /* Check that QP * Q - 1 == 0 mod P */ + if( QP != NULL ) + { + if( P == NULL || Q == NULL ) + { + ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) ); + if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + } + +cleanup: + + /* Wrap MPI error codes by RSA check failure error code */ + if( ret != 0 && + ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED && + ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) + { + ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + } + + mbedtls_mpi_free( &K ); + mbedtls_mpi_free( &L ); + + return( ret ); +} + +/* + * Check that core RSA parameters are sane. + */ +int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, + const mbedtls_mpi *Q, const mbedtls_mpi *D, + const mbedtls_mpi *E, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret = 0; + mbedtls_mpi K, L; + + mbedtls_mpi_init( &K ); + mbedtls_mpi_init( &L ); + + /* + * Step 1: If PRNG provided, check that P and Q are prime + */ + +#if defined(MBEDTLS_GENPRIME) + if( f_rng != NULL && P != NULL && + ( ret = mbedtls_mpi_is_prime( P, f_rng, p_rng ) ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + + if( f_rng != NULL && Q != NULL && + ( ret = mbedtls_mpi_is_prime( Q, f_rng, p_rng ) ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } +#else + ((void) f_rng); + ((void) p_rng); +#endif /* MBEDTLS_GENPRIME */ + + /* + * Step 2: Check that 1 < N = P * Q + */ + + if( P != NULL && Q != NULL && N != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) ); + if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 || + mbedtls_mpi_cmp_mpi( &K, N ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + } + + /* + * Step 3: Check and 1 < D, E < N if present. + */ + + if( N != NULL && D != NULL && E != NULL ) + { + if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 || + mbedtls_mpi_cmp_int( E, 1 ) <= 0 || + mbedtls_mpi_cmp_mpi( D, N ) >= 0 || + mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + } + + /* + * Step 4: Check that D, E are inverse modulo P-1 and Q-1 + */ + + if( P != NULL && Q != NULL && D != NULL && E != NULL ) + { + if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || + mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + + /* Compute DE-1 mod P-1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); + if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + + /* Compute DE-1 mod Q-1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); + if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + goto cleanup; + } + } + +cleanup: + + mbedtls_mpi_free( &K ); + mbedtls_mpi_free( &L ); + + /* Wrap MPI error codes by RSA check failure error code */ + if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ) + { + ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + } + + return( ret ); +} + +int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, mbedtls_mpi *DP, + mbedtls_mpi *DQ, mbedtls_mpi *QP ) +{ + int ret = 0; + mbedtls_mpi K; + mbedtls_mpi_init( &K ); + + /* DP = D mod P-1 */ + if( DP != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) ); + } + + /* DQ = D mod Q-1 */ + if( DQ != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) ); + } + + /* QP = Q^{-1} mod P */ + if( QP != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) ); + } + +cleanup: + mbedtls_mpi_free( &K ); + + return( ret ); +} + +#endif /* MBEDTLS_RSA_C */ diff --git a/library/version_features.c b/library/version_features.c index ec4e67b5c..172cf1275 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -108,9 +108,6 @@ static const char *features[] = { #if defined(MBEDTLS_GCM_ALT) "MBEDTLS_GCM_ALT", #endif /* MBEDTLS_GCM_ALT */ -#if defined(MBEDTLS_XTEA_ALT) - "MBEDTLS_XTEA_ALT", -#endif /* MBEDTLS_XTEA_ALT */ #if defined(MBEDTLS_MD2_ALT) "MBEDTLS_MD2_ALT", #endif /* MBEDTLS_MD2_ALT */ @@ -123,6 +120,9 @@ static const char *features[] = { #if defined(MBEDTLS_RIPEMD160_ALT) "MBEDTLS_RIPEMD160_ALT", #endif /* MBEDTLS_RIPEMD160_ALT */ +#if defined(MBEDTLS_RSA_ALT) + "MBEDTLS_RSA_ALT", +#endif /* MBEDTLS_RSA_ALT */ #if defined(MBEDTLS_SHA1_ALT) "MBEDTLS_SHA1_ALT", #endif /* MBEDTLS_SHA1_ALT */ @@ -132,6 +132,9 @@ static const char *features[] = { #if defined(MBEDTLS_SHA512_ALT) "MBEDTLS_SHA512_ALT", #endif /* MBEDTLS_SHA512_ALT */ +#if defined(MBEDTLS_XTEA_ALT) + "MBEDTLS_XTEA_ALT", +#endif /* MBEDTLS_XTEA_ALT */ #if defined(MBEDTLS_ECP_ALT) "MBEDTLS_ECP_ALT", #endif /* MBEDTLS_ECP_ALT */ diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 8bf2b1b29..a8ee8fd3d 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -86,6 +86,8 @@ int main( void ) mbedtls_dhm_context dhm; mbedtls_aes_context aes; + mbedtls_mpi N, P, Q, D, E; + mbedtls_net_init( &listen_fd ); mbedtls_net_init( &client_fd ); mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256 ); @@ -93,6 +95,9 @@ int main( void ) mbedtls_aes_init( &aes ); mbedtls_ctr_drbg_init( &ctr_drbg ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); + /* * 1. Setup the RNG */ @@ -124,24 +129,33 @@ int main( void ) mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); - if( ( ret = mbedtls_mpi_read_file( &rsa.N , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.E , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.D , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.P , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.Q , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.DP, 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.DQ, 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 ) + if( ( ret = mbedtls_mpi_read_file( &N , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &E , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &D , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &P , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &Q , 16, f ) ) != 0 ) { - mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret ); + mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", + ret ); fclose( f ); goto exit; } - - rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3; - fclose( f ); + if( ( ret = mbedtls_rsa_import( &rsa, &N, &P, &Q, &D, &E ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_rsa_import returned %d\n\n", + ret ); + goto exit; + } + + if( ( ret = mbedtls_rsa_complete( &rsa ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_rsa_complete returned %d\n\n", + ret ); + goto exit; + } + /* * 2b. Get the DHM modulus and generator */ @@ -287,6 +301,9 @@ int main( void ) exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); + mbedtls_net_free( &client_fd ); mbedtls_net_free( &listen_fd ); diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index 48126948d..ed6ed308e 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -191,6 +191,7 @@ int main( int argc, char *argv[] ) char buf[1024]; int i; char *p, *q; + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; const char *pers = "gen_key"; @@ -201,6 +202,11 @@ int main( int argc, char *argv[] ) /* * Set to sane values */ + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); + mbedtls_pk_init( &key ); mbedtls_ctr_drbg_init( &ctr_drbg ); memset( buf, 0, sizeof( buf ) ); @@ -323,7 +329,7 @@ int main( int argc, char *argv[] ) if( opt.type == MBEDTLS_PK_RSA ) { ret = mbedtls_rsa_gen_key( mbedtls_pk_rsa( key ), mbedtls_ctr_drbg_random, &ctr_drbg, - opt.rsa_keysize, 65537 ); + opt.rsa_keysize, 65537 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_gen_key returned -0x%04x", -ret ); @@ -336,7 +342,7 @@ int main( int argc, char *argv[] ) if( opt.type == MBEDTLS_PK_ECKEY ) { ret = mbedtls_ecp_gen_key( opt.ec_curve, mbedtls_pk_ec( key ), - mbedtls_ctr_drbg_random, &ctr_drbg ); + mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_gen_key returned -0x%04x", -ret ); @@ -359,14 +365,22 @@ int main( int argc, char *argv[] ) if( mbedtls_pk_get_type( &key ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( key ); - mbedtls_mpi_write_file( "N: ", &rsa->N, 16, NULL ); - mbedtls_mpi_write_file( "E: ", &rsa->E, 16, NULL ); - mbedtls_mpi_write_file( "D: ", &rsa->D, 16, NULL ); - mbedtls_mpi_write_file( "P: ", &rsa->P, 16, NULL ); - mbedtls_mpi_write_file( "Q: ", &rsa->Q, 16, NULL ); - mbedtls_mpi_write_file( "DP: ", &rsa->DP, 16, NULL ); - mbedtls_mpi_write_file( "DQ: ", &rsa->DQ, 16, NULL ); - mbedtls_mpi_write_file( "QP: ", &rsa->QP, 16, NULL ); + + if( ( ret = mbedtls_rsa_export ( rsa, &N, &P, &Q, &D, &E ) ) != 0 || + ( ret = mbedtls_rsa_export_crt( rsa, &DP, &DQ, &QP ) ) != 0 ) + { + mbedtls_printf( " failed\n ! could not export RSA parameters\n\n" ); + goto exit; + } + + mbedtls_mpi_write_file( "N: ", &N, 16, NULL ); + mbedtls_mpi_write_file( "E: ", &E, 16, NULL ); + mbedtls_mpi_write_file( "D: ", &D, 16, NULL ); + mbedtls_mpi_write_file( "P: ", &P, 16, NULL ); + mbedtls_mpi_write_file( "Q: ", &Q, 16, NULL ); + mbedtls_mpi_write_file( "DP: ", &DP, 16, NULL ); + mbedtls_mpi_write_file( "DQ: ", &DQ, 16, NULL ); + mbedtls_mpi_write_file( "QP: ", &QP, 16, NULL ); } else #endif @@ -409,6 +423,10 @@ exit: #endif } + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); + mbedtls_pk_free( &key ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); @@ -422,4 +440,3 @@ exit: } #endif /* MBEDTLS_PK_WRITE_C && MBEDTLS_PEM_WRITE_C && MBEDTLS_FS_IO && * MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ - diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c index b6b84464d..f1b548d05 100644 --- a/programs/pkey/key_app.c +++ b/programs/pkey/key_app.c @@ -84,17 +84,23 @@ struct options int main( int argc, char *argv[] ) { int ret = 0; - mbedtls_pk_context pk; char buf[1024]; int i; char *p, *q; + mbedtls_pk_context pk; + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; + /* * Set to sane values */ mbedtls_pk_init( &pk ); memset( buf, 0, sizeof(buf) ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); + if( argc == 0 ) { usage: @@ -189,14 +195,22 @@ int main( int argc, char *argv[] ) if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk ); - mbedtls_mpi_write_file( "N: ", &rsa->N, 16, NULL ); - mbedtls_mpi_write_file( "E: ", &rsa->E, 16, NULL ); - mbedtls_mpi_write_file( "D: ", &rsa->D, 16, NULL ); - mbedtls_mpi_write_file( "P: ", &rsa->P, 16, NULL ); - mbedtls_mpi_write_file( "Q: ", &rsa->Q, 16, NULL ); - mbedtls_mpi_write_file( "DP: ", &rsa->DP, 16, NULL ); - mbedtls_mpi_write_file( "DQ: ", &rsa->DQ, 16, NULL ); - mbedtls_mpi_write_file( "QP: ", &rsa->QP, 16, NULL ); + + if( ( ret = mbedtls_rsa_export ( rsa, &N, &P, &Q, &D, &E ) ) != 0 || + ( ret = mbedtls_rsa_export_crt( rsa, &DP, &DQ, &QP ) ) != 0 ) + { + mbedtls_printf( " failed\n ! could not export RSA parameters\n\n" ); + goto exit; + } + + mbedtls_mpi_write_file( "N: ", &N, 16, NULL ); + mbedtls_mpi_write_file( "E: ", &E, 16, NULL ); + mbedtls_mpi_write_file( "D: ", &D, 16, NULL ); + mbedtls_mpi_write_file( "P: ", &P, 16, NULL ); + mbedtls_mpi_write_file( "Q: ", &Q, 16, NULL ); + mbedtls_mpi_write_file( "DP: ", &DP, 16, NULL ); + mbedtls_mpi_write_file( "DQ: ", &DQ, 16, NULL ); + mbedtls_mpi_write_file( "QP: ", &QP, 16, NULL ); } else #endif @@ -239,8 +253,15 @@ int main( int argc, char *argv[] ) if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk ); - mbedtls_mpi_write_file( "N: ", &rsa->N, 16, NULL ); - mbedtls_mpi_write_file( "E: ", &rsa->E, 16, NULL ); + + if( ( ret = mbedtls_rsa_export( rsa, &N, NULL, NULL, + NULL, &E ) ) != 0 ) + { + mbedtls_printf( " failed\n ! could not export RSA parameters\n\n" ); + goto exit; + } + mbedtls_mpi_write_file( "N: ", &N, 16, NULL ); + mbedtls_mpi_write_file( "E: ", &E, 16, NULL ); } else #endif @@ -265,11 +286,17 @@ int main( int argc, char *argv[] ) exit: #if defined(MBEDTLS_ERROR_C) - mbedtls_strerror( ret, buf, sizeof(buf) ); - mbedtls_printf( " ! Last error was: %s\n", buf ); + if( ret != 0 ) + { + mbedtls_strerror( ret, buf, sizeof(buf) ); + mbedtls_printf( " ! Last error was: %s\n", buf ); + } #endif mbedtls_pk_free( &pk ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c index 9d120772a..52b0f8e74 100644 --- a/programs/pkey/key_app_writer.c +++ b/programs/pkey/key_app_writer.c @@ -76,7 +76,7 @@ #define OUTPUT_FORMAT_DER 1 #define USAGE \ - "\n usage: key_app param=<>...\n" \ + "\n usage: key_app_writer param=<>...\n" \ "\n acceptable parameters:\n" \ " mode=private|public default: none\n" \ " filename=%%s default: keyfile.key\n" \ @@ -190,17 +190,23 @@ static int write_private_key( mbedtls_pk_context *key, const char *output_file ) int main( int argc, char *argv[] ) { int ret = 0; - mbedtls_pk_context key; char buf[1024]; int i; char *p, *q; + mbedtls_pk_context key; + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; + /* * Set to sane values */ mbedtls_pk_init( &key ); memset( buf, 0, sizeof( buf ) ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); + if( argc == 0 ) { usage: @@ -300,14 +306,22 @@ int main( int argc, char *argv[] ) if( mbedtls_pk_get_type( &key ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( key ); - mbedtls_mpi_write_file( "N: ", &rsa->N, 16, NULL ); - mbedtls_mpi_write_file( "E: ", &rsa->E, 16, NULL ); - mbedtls_mpi_write_file( "D: ", &rsa->D, 16, NULL ); - mbedtls_mpi_write_file( "P: ", &rsa->P, 16, NULL ); - mbedtls_mpi_write_file( "Q: ", &rsa->Q, 16, NULL ); - mbedtls_mpi_write_file( "DP: ", &rsa->DP, 16, NULL ); - mbedtls_mpi_write_file( "DQ: ", &rsa->DQ, 16, NULL ); - mbedtls_mpi_write_file( "QP: ", &rsa->QP, 16, NULL ); + + if( ( ret = mbedtls_rsa_export ( rsa, &N, &P, &Q, &D, &E ) ) != 0 || + ( ret = mbedtls_rsa_export_crt( rsa, &DP, &DQ, &QP ) ) != 0 ) + { + mbedtls_printf( " failed\n ! could not export RSA parameters\n\n" ); + goto exit; + } + + mbedtls_mpi_write_file( "N: ", &N, 16, NULL ); + mbedtls_mpi_write_file( "E: ", &E, 16, NULL ); + mbedtls_mpi_write_file( "D: ", &D, 16, NULL ); + mbedtls_mpi_write_file( "P: ", &P, 16, NULL ); + mbedtls_mpi_write_file( "Q: ", &Q, 16, NULL ); + mbedtls_mpi_write_file( "DP: ", &DP, 16, NULL ); + mbedtls_mpi_write_file( "DQ: ", &DQ, 16, NULL ); + mbedtls_mpi_write_file( "QP: ", &QP, 16, NULL ); } else #endif @@ -353,8 +367,15 @@ int main( int argc, char *argv[] ) if( mbedtls_pk_get_type( &key ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( key ); - mbedtls_mpi_write_file( "N: ", &rsa->N, 16, NULL ); - mbedtls_mpi_write_file( "E: ", &rsa->E, 16, NULL ); + + if( ( ret = mbedtls_rsa_export( rsa, &N, NULL, NULL, + NULL, &E ) ) != 0 ) + { + mbedtls_printf( " failed\n ! could not export RSA parameters\n\n" ); + goto exit; + } + mbedtls_mpi_write_file( "N: ", &N, 16, NULL ); + mbedtls_mpi_write_file( "E: ", &E, 16, NULL ); } else #endif @@ -394,6 +415,10 @@ exit: #endif } + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); + mbedtls_pk_free( &key ); #if defined(_WIN32) diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c index b64e1564a..2da3fbf11 100644 --- a/programs/pkey/rsa_decrypt.c +++ b/programs/pkey/rsa_decrypt.c @@ -64,6 +64,7 @@ int main( int argc, char *argv[] ) int return_val, exit_val, c; size_t i; mbedtls_rsa_context rsa; + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char result[1024]; @@ -91,6 +92,9 @@ int main( int argc, char *argv[] ) mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_entropy_init( &entropy ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); return_val = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, @@ -114,14 +118,14 @@ int main( int argc, char *argv[] ) goto exit; } - if( ( return_val = mbedtls_mpi_read_file( &rsa.N , 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.E , 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.D , 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.P , 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.Q , 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.DP, 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.DQ, 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 ) + if( ( return_val = mbedtls_mpi_read_file( &N , 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &E , 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &D , 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &P , 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &Q , 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &DP , 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &DQ , 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &QP , 16, f ) ) != 0 ) { exit_val = MBEDTLS_EXIT_FAILURE; mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", @@ -129,11 +133,22 @@ int main( int argc, char *argv[] ) fclose( f ); goto exit; } - - rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3; - fclose( f ); + if( ( return_val = mbedtls_rsa_import( &rsa, &N, &P, &Q, &D, &E ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_rsa_import returned %d\n\n", + return_val ); + goto exit; + } + + if( ( return_val = mbedtls_rsa_complete( &rsa ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_rsa_complete returned %d\n\n", + return_val ); + goto exit; + } + /* * Extract the RSA encrypted value from the text file */ @@ -184,6 +199,9 @@ exit: mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); mbedtls_rsa_free( &rsa ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); @@ -193,4 +211,3 @@ exit: return( exit_val ); } #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_FS_IO */ - diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c index b9cb18765..81c27d888 100644 --- a/programs/pkey/rsa_encrypt.c +++ b/programs/pkey/rsa_encrypt.c @@ -69,6 +69,7 @@ int main( int argc, char *argv[] ) unsigned char input[1024]; unsigned char buf[512]; const char *pers = "rsa_encrypt"; + mbedtls_mpi N, E; exit_val = MBEDTLS_EXIT_SUCCESS; @@ -86,6 +87,7 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_entropy_init( &entropy ); @@ -112,8 +114,8 @@ int main( int argc, char *argv[] ) goto exit; } - if( ( return_val = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 || - ( return_val = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 ) + if( ( return_val = mbedtls_mpi_read_file( &N, 16, f ) ) != 0 || + ( return_val = mbedtls_mpi_read_file( &E, 16, f ) ) != 0 ) { exit_val = MBEDTLS_EXIT_FAILURE; mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", @@ -121,11 +123,17 @@ int main( int argc, char *argv[] ) fclose( f ); goto exit; } - - rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3; - fclose( f ); + if( ( return_val = mbedtls_rsa_import( &rsa, &N, NULL, + NULL, NULL, &E ) ) != 0 ) + { + exit_val = MBEDTLS_EXIT_FAILURE; + mbedtls_printf( " failed\n ! mbedtls_rsa_import returned %d\n\n", + return_val ); + goto exit; + } + if( strlen( argv[1] ) > 100 ) { exit_val = MBEDTLS_EXIT_FAILURE; @@ -171,6 +179,7 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Done (created \"%s\")\n\n", "result-enc.txt" ); exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); mbedtls_rsa_free( &rsa ); diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c index e199ad247..3dae0a6c8 100644 --- a/programs/pkey/rsa_genkey.c +++ b/programs/pkey/rsa_genkey.c @@ -65,6 +65,7 @@ int main( void ) mbedtls_rsa_context rsa; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; FILE *fpub = NULL; FILE *fpriv = NULL; const char *pers = "rsa_genkey"; @@ -87,9 +88,12 @@ int main( void ) fflush( stdout ); mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); if( ( ret = mbedtls_rsa_gen_key( &rsa, mbedtls_ctr_drbg_random, &ctr_drbg, KEY_SIZE, - EXPONENT ) ) != 0 ) + EXPONENT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_gen_key returned %d\n\n", ret ); goto exit; @@ -98,6 +102,14 @@ int main( void ) mbedtls_printf( " ok\n . Exporting the public key in rsa_pub.txt...." ); fflush( stdout ); + if( ( ret = mbedtls_rsa_export ( &rsa, &N, &P, &Q, &D, &E ) ) != 0 || + ( ret = mbedtls_rsa_export_crt( &rsa, &DP, &DQ, &QP ) ) != 0 ) + { + mbedtls_printf( " failed\n ! could not export RSA parameters\n\n" ); + ret = 1; + goto exit; + } + if( ( fpub = fopen( "rsa_pub.txt", "wb+" ) ) == NULL ) { mbedtls_printf( " failed\n ! could not open rsa_pub.txt for writing\n\n" ); @@ -105,8 +117,8 @@ int main( void ) goto exit; } - if( ( ret = mbedtls_mpi_write_file( "N = ", &rsa.N, 16, fpub ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "E = ", &rsa.E, 16, fpub ) ) != 0 ) + if( ( ret = mbedtls_mpi_write_file( "N = ", &N, 16, fpub ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "E = ", &E, 16, fpub ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_write_file returned %d\n\n", ret ); goto exit; @@ -122,14 +134,14 @@ int main( void ) goto exit; } - if( ( ret = mbedtls_mpi_write_file( "N = " , &rsa.N , 16, fpriv ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "E = " , &rsa.E , 16, fpriv ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "D = " , &rsa.D , 16, fpriv ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "P = " , &rsa.P , 16, fpriv ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "Q = " , &rsa.Q , 16, fpriv ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "DP = ", &rsa.DP, 16, fpriv ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "DQ = ", &rsa.DQ, 16, fpriv ) ) != 0 || - ( ret = mbedtls_mpi_write_file( "QP = ", &rsa.QP, 16, fpriv ) ) != 0 ) + if( ( ret = mbedtls_mpi_write_file( "N = " , &N , 16, fpriv ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "E = " , &E , 16, fpriv ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "D = " , &D , 16, fpriv ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "P = " , &P , 16, fpriv ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "Q = " , &Q , 16, fpriv ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "DP = ", &DP, 16, fpriv ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "DQ = ", &DQ, 16, fpriv ) ) != 0 || + ( ret = mbedtls_mpi_write_file( "QP = ", &QP, 16, fpriv ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_write_file returned %d\n\n", ret ); goto exit; @@ -157,6 +169,9 @@ exit: if( fpriv != NULL ) fclose( fpriv ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); mbedtls_rsa_free( &rsa ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c index affbf7afc..89018cb76 100644 --- a/programs/pkey/rsa_sign.c +++ b/programs/pkey/rsa_sign.c @@ -61,8 +61,14 @@ int main( int argc, char *argv[] ) unsigned char hash[32]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; char filename[512]; + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); + ret = 1; if( argc != 2 ) @@ -87,24 +93,35 @@ int main( int argc, char *argv[] ) goto exit; } - if( ( ret = mbedtls_mpi_read_file( &rsa.N , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.E , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.D , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.P , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.Q , 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.DP, 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.DQ, 16, f ) ) != 0 || - ( ret = mbedtls_mpi_read_file( &rsa.QP, 16, f ) ) != 0 ) + if( ( ret = mbedtls_mpi_read_file( &N , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &E , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &D , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &P , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &Q , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &DP , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &DQ , 16, f ) ) != 0 || + ( ret = mbedtls_mpi_read_file( &QP , 16, f ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret ); fclose( f ); goto exit; } - - rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3; - fclose( f ); + if( ( ret = mbedtls_rsa_import( &rsa, &N, &P, &Q, &D, &E ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_rsa_import returned %d\n\n", + ret ); + goto exit; + } + + if( ( ret = mbedtls_rsa_complete( &rsa ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_rsa_complete returned %d\n\n", + ret ); + goto exit; + } + mbedtls_printf( "\n . Checking the private key" ); fflush( stdout ); if( ( ret = mbedtls_rsa_check_privkey( &rsa ) ) != 0 ) @@ -158,6 +175,9 @@ int main( int argc, char *argv[] ) exit: mbedtls_rsa_free( &rsa ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 2ea31dbc2..b559af8e1 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -605,7 +605,7 @@ cleanup cp "$CONFIG_H" "$CONFIG_BAK" scripts/config.pl full scripts/config.pl unset MBEDTLS_SSL_CLI_C -make CC=gcc CFLAGS='-Werror -Wall -Werror -O0' +make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' # Note, C99 compliance can also be tested with the sockets support disabled, # as that requires a POSIX platform (which isn't the same as C99). @@ -767,6 +767,16 @@ msg "test: allow SHA1 in certificates by default" make test if_build_succeeded tests/ssl-opt.sh -f SHA-1 +msg "build: Default + MBEDTLS_RSA_NO_CRT (ASan build)" # ~ 6 min +cleanup +cp "$CONFIG_H" "$CONFIG_BAK" +scripts/config.pl set MBEDTLS_RSA_NO_CRT +CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . +make + +msg "test: MBEDTLS_RSA_NO_CRT - main suites (inc. selftests) (ASan build)" +make test + msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s cleanup make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 5fa8a693a..e84783667 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -333,18 +333,19 @@ void pk_rsa_decrypt_test_vec( char *cipher_hex, int mod, unsigned char cipher[1000]; size_t clear_len, olen, cipher_len; rnd_pseudo_info rnd_info; - mbedtls_mpi P1, Q1, H, G; + mbedtls_mpi N, P, Q, E; mbedtls_rsa_context *rsa; mbedtls_pk_context pk; mbedtls_pk_init( &pk ); - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); memset( clear, 0, sizeof( clear ) ); memset( cipher, 0, sizeof( cipher ) ); - clear_len = unhexify( clear, clear_hex ); + clear_len = unhexify( clear, clear_hex ); cipher_len = unhexify( cipher, cipher_hex ); /* init pk-rsa context */ @@ -352,21 +353,15 @@ void pk_rsa_decrypt_test_vec( char *cipher_hex, int mod, rsa = mbedtls_pk_rsa( pk ); /* load public key */ - rsa->len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); /* load private key */ - TEST_ASSERT( mbedtls_mpi_read_string( &rsa->P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &rsa->Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &rsa->P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &rsa->Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &rsa->E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &rsa->D , &rsa->E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &rsa->DP, &rsa->D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &rsa->DQ, &rsa->D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &rsa->QP, &rsa->Q, &rsa->P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( rsa, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( rsa ) == (size_t) ( mod / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( rsa ) == 0 ); /* decryption test */ memset( output, 0, sizeof( output ) ); @@ -381,7 +376,8 @@ void pk_rsa_decrypt_test_vec( char *cipher_hex, int mod, } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); mbedtls_pk_free( &pk ); } /* END_CASE */ diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function index 09fe05bb3..7f8b1c82e 100644 --- a/tests/suites/test_suite_pkcs1_v15.function +++ b/tests/suites/test_suite_pkcs1_v15.function @@ -21,19 +21,21 @@ void pkcs1_rsaes_v15_encrypt( int mod, int radix_N, char *input_N, int radix_E, mbedtls_rsa_context ctx; size_t msg_len; rnd_buf_info info; + mbedtls_mpi N, E; info.length = unhexify( rnd_buf, seed ); info.buf = rnd_buf; + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash ); memset( message_str, 0x00, 1000 ); memset( output, 0x00, 1000 ); memset( output_str, 0x00, 1000 ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -47,6 +49,7 @@ void pkcs1_rsaes_v15_encrypt( int mod, int radix_N, char *input_N, int radix_E, } exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -62,12 +65,13 @@ void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char *input_P, unsigned char output[1000]; unsigned char output_str[1000]; mbedtls_rsa_context ctx; - mbedtls_mpi P1, Q1, H, G; size_t output_len; rnd_pseudo_info rnd_info; + mbedtls_mpi N, P, Q, E; ((void) seed); - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash ); memset( message_str, 0x00, 1000 ); @@ -75,21 +79,14 @@ void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char *input_P, memset( output_str, 0x00, 1000 ); memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); unhexify( message_str, message_hex_string ); @@ -103,7 +100,8 @@ void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char *input_P, } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -121,14 +119,15 @@ void pkcs1_rsassa_v15_sign( int mod, int radix_P, char *input_P, int radix_Q, unsigned char output_str[1000]; unsigned char rnd_buf[1000]; mbedtls_rsa_context ctx; - mbedtls_mpi P1, Q1, H, G; + mbedtls_mpi N, P, Q, E; size_t msg_len; rnd_buf_info info; info.length = unhexify( rnd_buf, salt ); info.buf = rnd_buf; - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash ); memset( message_str, 0x00, 1000 ); @@ -136,21 +135,14 @@ void pkcs1_rsassa_v15_sign( int mod, int radix_P, char *input_P, int radix_Q, memset( output, 0x00, 1000 ); memset( output_str, 0x00, 1000 ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -167,7 +159,8 @@ void pkcs1_rsassa_v15_sign( int mod, int radix_P, char *input_P, int radix_Q, } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -183,28 +176,34 @@ void pkcs1_rsassa_v15_verify( int mod, int radix_N, char *input_N, int radix_E, unsigned char result_str[1000]; mbedtls_rsa_context ctx; size_t msg_len; + mbedtls_mpi N, E; ((void) salt); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash ); memset( message_str, 0x00, 1000 ); memset( hash_result, 0x00, 1000 ); memset( result_str, 0x00, 1000 ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); unhexify( result_str, result_hex_str ); if( mbedtls_md_info_from_type( digest ) != NULL ) - TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 ); + TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), + message_str, msg_len, hash_result ) == 0 ); - TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, digest, 0, hash_result, result_str ) == result ); + TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, + digest, 0, hash_result, + result_str ) == result ); exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ diff --git a/tests/suites/test_suite_pkcs1_v21.function b/tests/suites/test_suite_pkcs1_v21.function index 4f1ff4509..50da2ff1b 100644 --- a/tests/suites/test_suite_pkcs1_v21.function +++ b/tests/suites/test_suite_pkcs1_v21.function @@ -21,19 +21,21 @@ void pkcs1_rsaes_oaep_encrypt( int mod, int radix_N, char *input_N, int radix_E, mbedtls_rsa_context ctx; size_t msg_len; rnd_buf_info info; + mbedtls_mpi N, E; info.length = unhexify( rnd_buf, seed ); info.buf = rnd_buf; + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash ); memset( message_str, 0x00, 1000 ); memset( output, 0x00, 1000 ); memset( output_str, 0x00, 1000 ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -47,6 +49,7 @@ void pkcs1_rsaes_oaep_encrypt( int mod, int radix_N, char *input_N, int radix_E, } exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -62,12 +65,14 @@ void pkcs1_rsaes_oaep_decrypt( int mod, int radix_P, char *input_P, unsigned char output[1000]; unsigned char output_str[1000]; mbedtls_rsa_context ctx; - mbedtls_mpi P1, Q1, H, G; size_t output_len; rnd_pseudo_info rnd_info; + mbedtls_mpi N, P, Q, E; ((void) seed); - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); + mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash ); memset( message_str, 0x00, 1000 ); @@ -75,21 +80,14 @@ void pkcs1_rsaes_oaep_decrypt( int mod, int radix_P, char *input_P, memset( output_str, 0x00, 1000 ); memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); unhexify( message_str, message_hex_string ); @@ -103,7 +101,8 @@ void pkcs1_rsaes_oaep_decrypt( int mod, int radix_P, char *input_P, } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -121,14 +120,15 @@ void pkcs1_rsassa_pss_sign( int mod, int radix_P, char *input_P, int radix_Q, unsigned char output_str[1000]; unsigned char rnd_buf[1000]; mbedtls_rsa_context ctx; - mbedtls_mpi P1, Q1, H, G; size_t msg_len; rnd_buf_info info; + mbedtls_mpi N, P, Q, E; info.length = unhexify( rnd_buf, salt ); info.buf = rnd_buf; - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash ); memset( message_str, 0x00, 1000 ); @@ -136,29 +136,24 @@ void pkcs1_rsassa_pss_sign( int mod, int radix_P, char *input_P, int radix_Q, memset( output, 0x00, 1000 ); memset( output_str, 0x00, 1000 ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); if( mbedtls_md_info_from_type( digest ) != NULL ) - TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 ); + TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, + msg_len, hash_result ) == 0 ); - TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_buffer_rand, &info, MBEDTLS_RSA_PRIVATE, digest, 0, hash_result, output ) == result ); + TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_buffer_rand, &info, MBEDTLS_RSA_PRIVATE, + digest, 0, hash_result, output ) == result ); if( result == 0 ) { hexify( output_str, output, ctx.len); @@ -167,7 +162,8 @@ void pkcs1_rsassa_pss_sign( int mod, int radix_P, char *input_P, int radix_Q, } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -183,28 +179,34 @@ void pkcs1_rsassa_pss_verify( int mod, int radix_N, char *input_N, int radix_E, unsigned char result_str[1000]; mbedtls_rsa_context ctx; size_t msg_len; + mbedtls_mpi N, E; ((void) salt); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash ); memset( message_str, 0x00, 1000 ); memset( hash_result, 0x00, 1000 ); memset( result_str, 0x00, 1000 ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); unhexify( result_str, result_hex_str ); if( mbedtls_md_info_from_type( digest ) != NULL ) - TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 ); + TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, + msg_len, hash_result ) == 0 ); - TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, digest, 0, hash_result, result_str ) == result ); + TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, + digest, 0, hash_result, result_str ) == result ); exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -225,16 +227,19 @@ void pkcs1_rsassa_pss_verify_ext( int mod, unsigned char result_str[1000]; mbedtls_rsa_context ctx; size_t msg_len, hash_len; + mbedtls_mpi N, E; + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, ctx_hash ); memset( message_str, 0x00, 1000 ); memset( hash_result, 0x00, 1000 ); memset( result_str, 0x00, 1000 ); - ctx.len = mod / 8 + ( ( mod % 8 ) ? 1 : 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -262,6 +267,7 @@ void pkcs1_rsassa_pss_verify_ext( int mod, result_str ) == result_full ); exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data index df7c1407c..416f9dfe4 100644 --- a/tests/suites/test_suite_pkparse.data +++ b/tests/suites/test_suite_pkparse.data @@ -485,4 +485,4 @@ Key ASN1 (RSAPrivateKey, values present, length mismatch) pk_parse_key_rsa:"301c02010002010102010102010102010102010102010102010102010100":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT Key ASN1 (RSAPrivateKey, values present, check_privkey fails) -pk_parse_key_rsa:"301b020100020101020101020101020101020101020101020101020101":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +pk_parse_key_rsa:"301b020100020102020101020101020101020101020101020101020101":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data index fc7d93588..46046119d 100644 --- a/tests/suites/test_suite_rsa.data +++ b/tests/suites/test_suite_rsa.data @@ -274,12 +274,15 @@ RSA Check Private key #6 (No D) mbedtls_rsa_check_privkey:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED RSA Check Private key #7 (No DP) +depends_on:!MBEDTLS_RSA_NO_CRT mbedtls_rsa_check_privkey:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED RSA Check Private key #8 (No DQ) +depends_on:!MBEDTLS_RSA_NO_CRT mbedtls_rsa_check_privkey:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED RSA Check Private key #9 (No QP) +depends_on:!MBEDTLS_RSA_NO_CRT mbedtls_rsa_check_privkey:2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED RSA Check Private key #10 (Incorrect) @@ -370,6 +373,201 @@ RSA Generate Key - 1025 bit key # mbedtls_rsa_gen_key only supports even-sized keys mbedtls_rsa_gen_key:1025:3:MBEDTLS_ERR_RSA_BAD_INPUT_DATA +RSA Validate Params, toy example +mbedtls_rsa_validate_params:10:"15":10:"3":10:"5":10:"3":10:"3":0:0 + +RSA Validate Params, toy example, N missing +mbedtls_rsa_validate_params:10:"":10:"3":10:"5":10:"3":10:"3":0:0 + +RSA Validate Params, toy example, E missing +mbedtls_rsa_validate_params:10:"15":10:"3":10:"5":10:"3":10:"":0:0 + +RSA Validate Params, toy example, corrupted +mbedtls_rsa_validate_params:10:"16":10:"3":10:"5":10:"3":10:"3":0:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + +RSA Validate Params, toy example, non-primes, no PRNG +mbedtls_rsa_validate_params:10:"45":10:"9":10:"5":10:"7":10:"23":0:0 + +RSA Validate Params, toy example, non-primes, PRNG +mbedtls_rsa_validate_params:10:"45":10:"9":10:"5":10:"7":10:"23":1:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + +RSA Validate Params +mbedtls_rsa_validate_params:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:0 + +RSA Validate Params, N missing +mbedtls_rsa_validate_params:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:0 + +RSA Validate Params, bad N +mbedtls_rsa_validate_params:16:"b38bc65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + +RSA Validate Params, non-prime, no PRNG +mbedtls_rsa_validate_params:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd18":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"":0:0 + +RSA Validate Params, non-prime, PRNG +mbedtls_rsa_validate_params:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd18":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"":1:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + +RSA Deduce Private, toy example +mbedtls_rsa_deduce_private_exponent:10:"7":10:"11":10:"7":10:"13":0:0 + +RSA Deduce Private, toy example, corrupted +mbedtls_rsa_deduce_private_exponent:10:"3":10:"5":10:"3":10:"3":1:MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + +RSA Deduce Private +mbedtls_rsa_deduce_private_exponent:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":0:0 + +RSA Deduce Private, corrupted +mbedtls_rsa_deduce_private_exponent:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":1:MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + +RSA Deduce Primes, toy example +mbedtls_rsa_deduce_primes:10:"35":10:"5":10:"5":10:"5":10:"7":0:0 + +RSA Deduce Primes, toy example, corrupted +mbedtls_rsa_deduce_primes:10:"35":10:"5":10:"5":10:"5":10:"7":1:MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +RSA Deduce Moduli +mbedtls_rsa_deduce_primes:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":0:0 + +RSA Deduce Moduli, corrupted +mbedtls_rsa_deduce_primes:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":1:MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +RSA Import (N,P,Q,D,E) +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:1:0:0 + +RSA Import (N,P,Q,D,E), inconsistent +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC3672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:1:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:0 + +RSA Import (N,P,Q,D,E), successive +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1:0:0 + +RSA Import (N,P,Q,D,E), successive, inconsistent +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC3672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:0 + +RSA Import (-,P,Q,D,E) +mbedtls_rsa_import:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:1:0:0 + +RSA Import (-,P,Q,D,E), successive +mbedtls_rsa_import:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1:0:0 + +RSA Import (N,-,-,D,E) +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:1:0:0 + +RSA Import (N,-,-,D,E), succesive +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1:0:0 + +RSA Import (N,P,Q,-,E) +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":0:1:0:0 + +RSA Import (N,P,Q,-,E), successive +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":1:1:0:0 + +RSA Import (-,P,Q,-,E) +mbedtls_rsa_import:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":0:1:0:0 + +RSA Import (-,P,Q,-,E), successive +mbedtls_rsa_import:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":1:1:0:0 + +RSA Import (N,-,Q,-,E) +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":0:1:0:MBEDTLS_ERR_RSA_BAD_INPUT_DATA + +RSA Import (N,-,Q,-,E), successive +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":1:1:0:MBEDTLS_ERR_RSA_BAD_INPUT_DATA + +RSA Import (N,-,-,-,E), complete public key +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"":16:"3":0:0:0:0 + +RSA Import (N,-,-,-,E), complete public key, successive +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"":16:"3":1:0:0:0 + +RSA Import (N,-,-,-,E), complete public key, corrupted +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"":16:"4":0:0:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:0 + +RSA Import (N,-,-,-,E), complete public key, successive, corrupted +mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"":16:"4":1:0:MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:0 + +RSA Import Raw (N,P,Q,D,E), complete private key +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":0:1:0:0 + +RSA Import Raw (N,P,Q,D,E), successive +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:1:0:0 + +RSA Import Raw (-,P,Q,D,E) +mbedtls_rsa_import_raw:"":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":0:1:0:0 + +RSA Import Raw (-,P,Q,D,E), successive +mbedtls_rsa_import_raw:"":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:1:0:0 + +RSA Import Raw (N,-,-,D,E) +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":0:1:0:0 + +RSA Import Raw (N,-,-,D,E), successive +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:1:0:0 + +RSA Import Raw (N,P,Q,-,E) +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":0:1:0:0 + +RSA Import Raw (N,P,Q,-,E), successive +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":1:1:0:0 + +RSA Import Raw (-,P,Q,-,E) +mbedtls_rsa_import_raw:"":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":0:1:0:0 + +RSA Import Raw (-,P,Q,-,E), successive +mbedtls_rsa_import_raw:"":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":1:1:0:0 + +RSA Import Raw (N,-,Q,-,E) +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":0:1:0:MBEDTLS_ERR_RSA_BAD_INPUT_DATA + +RSA Import Raw (N,-,Q,-,E), successive +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":1:1:0:MBEDTLS_ERR_RSA_BAD_INPUT_DATA + +RSA Import Raw (N,-,-,-,E) +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"":"03":0:0:0:0 + +RSA Import Raw (N,-,-,-,E), successive +mbedtls_rsa_import_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"":"03":1:0:0:0 + +RSA Export (N,P,Q,D,E) +mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:0 + +RSA Export (N,P,Q,D,E), successive +mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1 + +RSA Export (N,-,-,D,E) +mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:0 + +RSA Export (N,-,-,D,E), succesive +mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1 + +RSA Export (N,P,Q,-,E) +mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":1:0 + +RSA Export (N,P,Q,-,E), successive +mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":1:1 + +RSA Export (N,-,-,-,E) +mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"":16:"3":0:0 + +RSA Export Raw (N,P,Q,D,E) +mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:0 + +RSA Export Raw (N,P,Q,D,E), successive +mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:1 + +RSA Export Raw (N,-,-,D,E) +mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:0 + +RSA Export Raw (N,-,-,D,E), succesive +mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:1 + +RSA Export Raw (N,P,Q,-,E) +mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":1:0 + +RSA Export Raw (N,P,Q,-,E), successive +mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"":"03":1:1 + +RSA Export Raw (N,-,-,-,E) +mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"":"03":0:0 + RSA PKCS1 Encrypt Bad RNG depends_on:MBEDTLS_PKCS1_V15 rsa_pkcs1_encrypt_bad_rng:"4E636AF98E40F3ADCFCCB698F4E80B9F":MBEDTLS_RSA_PKCS_V15:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"a42eda41e56235e666e7faaa77100197f657288a1bf183e4820f0c37ce2c456b960278d6003e0bbcd4be4a969f8e8fd9231e1f492414f00ed09844994c86ec32db7cde3bec7f0c3dbf6ae55baeb2712fa609f5fc3207a824eb3dace31849cd6a6084318523912bccb84cf42e3c6d6d1685131d69bb545acec827d2b0dfdd5568b7dcc4f5a11d6916583fefa689d367f8c9e1d95dcd2240895a9470b0c1730f97cd6e8546860bd254801769f54be96e16362ddcbf34d56035028890199e0f48db38642cb66a4181e028a6443a404fea284ce02b4614b683367d40874e505611d23142d49f06feea831d52d347b13610b413c4efc43a6de9f0b08d2a951dc503b6":MBEDTLS_ERR_RSA_RNG_FAILED diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function index 09309d687..639bcb89d 100644 --- a/tests/suites/test_suite_rsa.function +++ b/tests/suites/test_suite_rsa.function @@ -1,5 +1,6 @@ /* BEGIN_HEADER */ #include "mbedtls/rsa.h" +#include "mbedtls/rsa_internal.h" #include "mbedtls/md2.h" #include "mbedtls/md4.h" #include "mbedtls/md5.h" @@ -27,11 +28,12 @@ void mbedtls_rsa_pkcs1_sign( char *message_hex_string, int padding_mode, int dig unsigned char output[1000]; unsigned char output_str[1000]; mbedtls_rsa_context ctx; - mbedtls_mpi P1, Q1, H, G; + mbedtls_mpi N, P, Q, E; int msg_len; rnd_pseudo_info rnd_info; - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, padding_mode, 0 ); memset( message_str, 0x00, 1000 ); @@ -40,21 +42,14 @@ void mbedtls_rsa_pkcs1_sign( char *message_hex_string, int padding_mode, int dig memset( output_str, 0x00, 1000 ); memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -74,8 +69,8 @@ void mbedtls_rsa_pkcs1_sign( char *message_hex_string, int padding_mode, int dig } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); - mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -91,15 +86,18 @@ void mbedtls_rsa_pkcs1_verify( char *message_hex_string, int padding_mode, int d mbedtls_rsa_context ctx; int msg_len; + mbedtls_mpi N, E; + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, padding_mode, 0 ); memset( message_str, 0x00, 1000 ); memset( hash_result, 0x00, 1000 ); memset( result_str, 0x00, 1000 ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -111,6 +109,7 @@ void mbedtls_rsa_pkcs1_verify( char *message_hex_string, int padding_mode, int d TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, digest, 0, hash_result, result_str ) == result ); exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -129,12 +128,13 @@ void rsa_pkcs1_sign_raw( char *message_hex_string, char *hash_result_string, unsigned char output[1000]; unsigned char output_str[1000]; mbedtls_rsa_context ctx; - mbedtls_mpi P1, Q1, H, G; + mbedtls_mpi N, P, Q, E; int hash_len; rnd_pseudo_info rnd_info; - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); mbedtls_rsa_init( &ctx, padding_mode, 0 ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); memset( message_str, 0x00, 1000 ); memset( hash_result, 0x00, 1000 ); @@ -142,21 +142,14 @@ void rsa_pkcs1_sign_raw( char *message_hex_string, char *hash_result_string, memset( output_str, 0x00, 1000 ); memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); unhexify( message_str, message_hex_string ); @@ -195,7 +188,9 @@ void rsa_pkcs1_sign_raw( char *message_hex_string, char *hash_result_string, } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); + mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -214,23 +209,30 @@ void rsa_pkcs1_verify_raw( char *message_hex_string, char *hash_result_string, mbedtls_rsa_context ctx; size_t hash_len, olen; + mbedtls_mpi N, E; + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); + mbedtls_rsa_init( &ctx, padding_mode, 0 ); memset( message_str, 0x00, 1000 ); memset( hash_result, 0x00, 1000 ); memset( result_str, 0x00, 1000 ); memset( output, 0x00, sizeof( output ) ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); unhexify( message_str, message_hex_string ); hash_len = unhexify( hash_result, hash_result_string ); unhexify( result_str, result_hex_str ); - TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_NONE, hash_len, hash_result, result_str ) == correct ); + TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, NULL, NULL, + MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_NONE, + hash_len, hash_result, + result_str ) == correct ); /* For PKCS#1 v1.5, there is an alternative way to verify signatures */ if( padding_mode == MBEDTLS_RSA_PKCS_V15 ) @@ -259,6 +261,7 @@ void rsa_pkcs1_verify_raw( char *message_hex_string, char *hash_result_string, } exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -275,6 +278,9 @@ void mbedtls_rsa_pkcs1_encrypt( char *message_hex_string, int padding_mode, int size_t msg_len; rnd_pseudo_info rnd_info; + mbedtls_mpi N, E; + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); + memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); mbedtls_rsa_init( &ctx, padding_mode, 0 ); @@ -282,10 +288,11 @@ void mbedtls_rsa_pkcs1_encrypt( char *message_hex_string, int padding_mode, int memset( output, 0x00, 1000 ); memset( output_str, 0x00, 1000 ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -301,6 +308,7 @@ void mbedtls_rsa_pkcs1_encrypt( char *message_hex_string, int padding_mode, int } exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -317,15 +325,19 @@ void rsa_pkcs1_encrypt_bad_rng( char *message_hex_string, int padding_mode, mbedtls_rsa_context ctx; size_t msg_len; + mbedtls_mpi N, E; + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, padding_mode, 0 ); memset( message_str, 0x00, 1000 ); memset( output, 0x00, 1000 ); memset( output_str, 0x00, 1000 ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); msg_len = unhexify( message_str, message_hex_string ); @@ -341,6 +353,7 @@ void rsa_pkcs1_encrypt_bad_rng( char *message_hex_string, int padding_mode, } exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -355,11 +368,13 @@ void mbedtls_rsa_pkcs1_decrypt( char *message_hex_string, int padding_mode, int unsigned char output[1000]; unsigned char output_str[1000]; mbedtls_rsa_context ctx; - mbedtls_mpi P1, Q1, H, G; size_t output_len; rnd_pseudo_info rnd_info; + mbedtls_mpi N, P, Q, E; + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); mbedtls_rsa_init( &ctx, padding_mode, 0 ); memset( message_str, 0x00, 1000 ); @@ -367,21 +382,15 @@ void mbedtls_rsa_pkcs1_decrypt( char *message_hex_string, int padding_mode, int memset( output_str, 0x00, 1000 ); memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); unhexify( message_str, message_hex_string ); @@ -396,7 +405,8 @@ void mbedtls_rsa_pkcs1_decrypt( char *message_hex_string, int padding_mode, int } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -410,16 +420,20 @@ void mbedtls_rsa_public( char *message_hex_string, int mod, int radix_N, char *i unsigned char output_str[1000]; mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */ + mbedtls_mpi N, E; + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 ); mbedtls_rsa_init( &ctx2, MBEDTLS_RSA_PKCS_V15, 0 ); memset( message_str, 0x00, 1000 ); memset( output, 0x00, 1000 ); memset( output_str, 0x00, 1000 ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 ); unhexify( message_str, message_hex_string ); @@ -450,6 +464,7 @@ void mbedtls_rsa_public( char *message_hex_string, int mod, int radix_N, char *i } exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); mbedtls_rsa_free( &ctx2 ); } @@ -464,32 +479,26 @@ void mbedtls_rsa_private( char *message_hex_string, int mod, int radix_P, char * unsigned char output[1000]; unsigned char output_str[1000]; mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */ - mbedtls_mpi P1, Q1, H, G; + mbedtls_mpi N, P, Q, E; rnd_pseudo_info rnd_info; int i; - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); + mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 ); mbedtls_rsa_init( &ctx2, MBEDTLS_RSA_PKCS_V15, 0 ); memset( message_str, 0x00, 1000 ); memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) ); - ctx.len = mod / 8; - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); - - TEST_ASSERT( mbedtls_mpi_sub_int( &P1, &ctx.P, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_sub_int( &Q1, &ctx.Q, 1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_gcd( &G, &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.D , &ctx.E, &H ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DP, &ctx.D, &P1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_mod_mpi( &ctx.DQ, &ctx.D, &Q1 ) == 0 ); - TEST_ASSERT( mbedtls_mpi_inv_mod( &ctx.QP, &ctx.Q, &ctx.P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 ); + TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) ); + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 ); unhexify( message_str, message_hex_string ); @@ -530,7 +539,9 @@ void mbedtls_rsa_private( char *message_hex_string, int mod, int radix_P, char * } exit: - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); + mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &E ); + mbedtls_rsa_free( &ctx ); mbedtls_rsa_free( &ctx2 ); } /* END_CASE */ @@ -550,21 +561,25 @@ void mbedtls_rsa_check_pubkey( int radix_N, char *input_N, int radix_E, char *in int result ) { mbedtls_rsa_context ctx; + mbedtls_mpi N, E; + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E ); mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 ); if( strlen( input_N ) ) { - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); } if( strlen( input_E ) ) { - TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); } + TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 ); TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == result ); exit: + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E ); mbedtls_rsa_free( &ctx ); } /* END_CASE */ @@ -602,6 +617,7 @@ void mbedtls_rsa_check_privkey( int mod, int radix_P, char *input_P, int radix_Q { TEST_ASSERT( mbedtls_mpi_read_string( &ctx.D, radix_D, input_D ) == 0 ); } +#if !defined(MBEDTLS_RSA_NO_CRT) if( strlen( input_DP ) ) { TEST_ASSERT( mbedtls_mpi_read_string( &ctx.DP, radix_DP, input_DP ) == 0 ); @@ -614,6 +630,11 @@ void mbedtls_rsa_check_privkey( int mod, int radix_P, char *input_P, int radix_Q { TEST_ASSERT( mbedtls_mpi_read_string( &ctx.QP, radix_QP, input_QP ) == 0 ); } +#else + ((void) radix_DP); ((void) input_DP); + ((void) radix_DQ); ((void) input_DQ); + ((void) radix_QP); ((void) input_QP); +#endif TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == result ); @@ -669,6 +690,7 @@ void rsa_check_pubpriv( int mod, int radix_Npub, char *input_Npub, { TEST_ASSERT( mbedtls_mpi_read_string( &prv.D, radix_D, input_D ) == 0 ); } +#if !defined(MBEDTLS_RSA_NO_CRT) if( strlen( input_DP ) ) { TEST_ASSERT( mbedtls_mpi_read_string( &prv.DP, radix_DP, input_DP ) == 0 ); @@ -681,6 +703,11 @@ void rsa_check_pubpriv( int mod, int radix_Npub, char *input_Npub, { TEST_ASSERT( mbedtls_mpi_read_string( &prv.QP, radix_QP, input_QP ) == 0 ); } +#else + ((void) radix_DP); ((void) input_DP); + ((void) radix_DQ); ((void) input_DQ); + ((void) radix_QP); ((void) input_QP); +#endif TEST_ASSERT( mbedtls_rsa_check_pub_priv( &pub, &prv ) == result ); @@ -702,8 +729,9 @@ void mbedtls_rsa_gen_key( int nrbits, int exponent, int result) mbedtls_entropy_init( &entropy ); mbedtls_rsa_init ( &ctx, 0, 0 ); - TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, - (const unsigned char *) pers, strlen( pers ) ) == 0 ); + TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, + &entropy, (const unsigned char *) pers, + strlen( pers ) ) == 0 ); TEST_ASSERT( mbedtls_rsa_gen_key( &ctx, mbedtls_ctr_drbg_random, &ctr_drbg, nrbits, exponent ) == result ); if( result == 0 ) @@ -719,6 +747,721 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C */ +void mbedtls_rsa_deduce_primes( int radix_N, char *input_N, + int radix_D, char *input_D, + int radix_E, char *input_E, + int radix_P, char *output_P, + int radix_Q, char *output_Q, + int corrupt, int result ) +{ + mbedtls_mpi N, P, Pp, Q, Qp, D, E; + + mbedtls_mpi_init( &N ); + mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &Pp ); mbedtls_mpi_init( &Qp ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); + + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Qp, radix_P, output_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Pp, radix_Q, output_Q ) == 0 ); + + if( corrupt ) + TEST_ASSERT( mbedtls_mpi_add_int( &D, &D, 2 ) == 0 ); + + /* Try to deduce P, Q from N, D, E only. */ + TEST_ASSERT( mbedtls_rsa_deduce_primes( &N, &D, &E, &P, &Q ) == result ); + + if( !corrupt ) + { + /* Check if (P,Q) = (Pp, Qp) or (P,Q) = (Qp, Pp) */ + TEST_ASSERT( ( mbedtls_mpi_cmp_mpi( &P, &Pp ) == 0 && mbedtls_mpi_cmp_mpi( &Q, &Qp ) == 0 ) || + ( mbedtls_mpi_cmp_mpi( &P, &Qp ) == 0 && mbedtls_mpi_cmp_mpi( &Q, &Pp ) == 0 ) ); + } + +exit: + mbedtls_mpi_free( &N ); + mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &Pp ); mbedtls_mpi_free( &Qp ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void mbedtls_rsa_deduce_private_exponent( int radix_P, char *input_P, + int radix_Q, char *input_Q, + int radix_E, char *input_E, + int radix_D, char *output_D, + int corrupt, int result ) +{ + mbedtls_mpi P, Q, D, Dp, E, R, Rp; + + mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &Dp ); + mbedtls_mpi_init( &E ); + mbedtls_mpi_init( &R ); mbedtls_mpi_init( &Rp ); + + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + TEST_ASSERT( mbedtls_mpi_read_string( &Dp, radix_D, output_D ) == 0 ); + + if( corrupt ) + { + /* Make E even */ + TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 0 ) == 0 ); + } + + /* Try to deduce D from N, P, Q, E. */ + TEST_ASSERT( mbedtls_rsa_deduce_private_exponent( &P, &Q, + &E, &D ) == result ); + + if( !corrupt ) + { + /* + * Check that D and Dp agree modulo LCM(P-1, Q-1). + */ + + /* Replace P,Q by P-1, Q-1 */ + TEST_ASSERT( mbedtls_mpi_sub_int( &P, &P, 1 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_sub_int( &Q, &Q, 1 ) == 0 ); + + /* Check D == Dp modulo P-1 */ + TEST_ASSERT( mbedtls_mpi_mod_mpi( &R, &D, &P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_mod_mpi( &Rp, &Dp, &P ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &Rp ) == 0 ); + + /* Check D == Dp modulo Q-1 */ + TEST_ASSERT( mbedtls_mpi_mod_mpi( &R, &D, &Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_mod_mpi( &Rp, &Dp, &Q ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &Rp ) == 0 ); + } + +exit: + + mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &Dp ); + mbedtls_mpi_free( &E ); + mbedtls_mpi_free( &R ); mbedtls_mpi_free( &Rp ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */ +void mbedtls_rsa_import( int radix_N, char *input_N, + int radix_P, char *input_P, + int radix_Q, char *input_Q, + int radix_D, char *input_D, + int radix_E, char *input_E, + int successive, + int is_priv, + int res_check, + int res_complete ) +{ + mbedtls_mpi N, P, Q, D, E; + mbedtls_rsa_context ctx; + + /* Buffers used for encryption-decryption test */ + unsigned char *buf_orig = NULL; + unsigned char *buf_enc = NULL; + unsigned char *buf_dec = NULL; + + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + const char *pers = "test_suite_rsa"; + + const int have_N = ( strlen( input_N ) > 0 ); + const int have_P = ( strlen( input_P ) > 0 ); + const int have_Q = ( strlen( input_Q ) > 0 ); + const int have_D = ( strlen( input_D ) > 0 ); + const int have_E = ( strlen( input_E ) > 0 ); + + mbedtls_ctr_drbg_init( &ctr_drbg ); + + mbedtls_entropy_init( &entropy ); + TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, + (const unsigned char *) pers, strlen( pers ) ) == 0 ); + + mbedtls_rsa_init( &ctx, 0, 0 ); + + mbedtls_mpi_init( &N ); + mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); + + if( have_N ) + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + + if( have_P ) + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + + if( have_Q ) + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + + if( have_D ) + TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 ); + + if( have_E ) + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + + if( !successive ) + { + TEST_ASSERT( mbedtls_rsa_import( &ctx, + have_N ? &N : NULL, + have_P ? &P : NULL, + have_Q ? &Q : NULL, + have_D ? &D : NULL, + have_E ? &E : NULL ) == 0 ); + } + else + { + /* Import N, P, Q, D, E separately. + * This should make no functional difference. */ + + TEST_ASSERT( mbedtls_rsa_import( &ctx, + have_N ? &N : NULL, + NULL, NULL, NULL, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import( &ctx, + NULL, + have_P ? &P : NULL, + NULL, NULL, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import( &ctx, + NULL, NULL, + have_Q ? &Q : NULL, + NULL, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import( &ctx, + NULL, NULL, NULL, + have_D ? &D : NULL, + NULL ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import( &ctx, + NULL, NULL, NULL, NULL, + have_E ? &E : NULL ) == 0 ); + } + + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == res_complete ); + + /* On expected success, perform some public and private + * key operations to check if the key is working properly. */ + if( res_complete == 0 ) + { + if( is_priv ) + TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == res_check ); + else + TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == res_check ); + + if( res_check != 0 ) + goto exit; + + buf_orig = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) ); + buf_enc = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) ); + buf_dec = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) ); + if( buf_orig == NULL || buf_enc == NULL || buf_dec == NULL ) + goto exit; + + TEST_ASSERT( mbedtls_ctr_drbg_random( &ctr_drbg, + buf_orig, mbedtls_rsa_get_len( &ctx ) ) == 0 ); + + /* Make sure the number we're generating is smaller than the modulus */ + buf_orig[0] = 0x00; + + TEST_ASSERT( mbedtls_rsa_public( &ctx, buf_orig, buf_enc ) == 0 ); + + if( is_priv ) + { + TEST_ASSERT( mbedtls_rsa_private( &ctx, mbedtls_ctr_drbg_random, + &ctr_drbg, buf_enc, + buf_dec ) == 0 ); + + TEST_ASSERT( memcmp( buf_orig, buf_dec, + mbedtls_rsa_get_len( &ctx ) ) == 0 ); + } + } + +exit: + + mbedtls_free( buf_orig ); + mbedtls_free( buf_enc ); + mbedtls_free( buf_dec ); + + mbedtls_rsa_free( &ctx ); + + mbedtls_ctr_drbg_free( &ctr_drbg ); + mbedtls_entropy_free( &entropy ); + + mbedtls_mpi_free( &N ); + mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void mbedtls_rsa_export( int radix_N, char *input_N, + int radix_P, char *input_P, + int radix_Q, char *input_Q, + int radix_D, char *input_D, + int radix_E, char *input_E, + int is_priv, + int successive ) +{ + /* Original MPI's with which we set up the RSA context */ + mbedtls_mpi N, P, Q, D, E; + + /* Exported MPI's */ + mbedtls_mpi Ne, Pe, Qe, De, Ee; + + const int have_N = ( strlen( input_N ) > 0 ); + const int have_P = ( strlen( input_P ) > 0 ); + const int have_Q = ( strlen( input_Q ) > 0 ); + const int have_D = ( strlen( input_D ) > 0 ); + const int have_E = ( strlen( input_E ) > 0 ); + + mbedtls_rsa_context ctx; + + mbedtls_rsa_init( &ctx, 0, 0 ); + + mbedtls_mpi_init( &N ); + mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); + + mbedtls_mpi_init( &Ne ); + mbedtls_mpi_init( &Pe ); mbedtls_mpi_init( &Qe ); + mbedtls_mpi_init( &De ); mbedtls_mpi_init( &Ee ); + + /* Setup RSA context */ + + if( have_N ) + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + + if( have_P ) + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + + if( have_Q ) + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + + if( have_D ) + TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 ); + + if( have_E ) + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import( &ctx, + strlen( input_N ) ? &N : NULL, + strlen( input_P ) ? &P : NULL, + strlen( input_Q ) ? &Q : NULL, + strlen( input_D ) ? &D : NULL, + strlen( input_E ) ? &E : NULL ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); + + /* + * Export parameters and compare to original ones. + */ + + /* N and E must always be present. */ + if( !successive ) + { + TEST_ASSERT( mbedtls_rsa_export( &ctx, &Ne, NULL, NULL, NULL, &Ee ) == 0 ); + } + else + { + TEST_ASSERT( mbedtls_rsa_export( &ctx, &Ne, NULL, NULL, NULL, NULL ) == 0 ); + TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, NULL, NULL, NULL, &Ee ) == 0 ); + } + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &N, &Ne ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &E, &Ee ) == 0 ); + + /* If we were providing enough information to setup a complete private context, + * we expect to be able to export all core parameters. */ + + if( is_priv ) + { + if( !successive ) + { + TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, &Pe, &Qe, + &De, NULL ) == 0 ); + } + else + { + TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, &Pe, NULL, + NULL, NULL ) == 0 ); + TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, NULL, &Qe, + NULL, NULL ) == 0 ); + TEST_ASSERT( mbedtls_rsa_export( &ctx, NULL, NULL, NULL, + &De, NULL ) == 0 ); + } + + if( have_P ) + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P, &Pe ) == 0 ); + + if( have_Q ) + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &Qe ) == 0 ); + + if( have_D ) + TEST_ASSERT( mbedtls_mpi_cmp_mpi( &D, &De ) == 0 ); + + /* While at it, perform a sanity check */ + TEST_ASSERT( mbedtls_rsa_validate_params( &Ne, &Pe, &Qe, &De, &Ee, + NULL, NULL ) == 0 ); + } + +exit: + + mbedtls_rsa_free( &ctx ); + + mbedtls_mpi_free( &N ); + mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); + + mbedtls_mpi_free( &Ne ); + mbedtls_mpi_free( &Pe ); mbedtls_mpi_free( &Qe ); + mbedtls_mpi_free( &De ); mbedtls_mpi_free( &Ee ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */ +void mbedtls_rsa_validate_params( int radix_N, char *input_N, + int radix_P, char *input_P, + int radix_Q, char *input_Q, + int radix_D, char *input_D, + int radix_E, char *input_E, + int prng, int result ) +{ + /* Original MPI's with which we set up the RSA context */ + mbedtls_mpi N, P, Q, D, E; + + const int have_N = ( strlen( input_N ) > 0 ); + const int have_P = ( strlen( input_P ) > 0 ); + const int have_Q = ( strlen( input_Q ) > 0 ); + const int have_D = ( strlen( input_D ) > 0 ); + const int have_E = ( strlen( input_E ) > 0 ); + + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + const char *pers = "test_suite_rsa"; + + mbedtls_mpi_init( &N ); + mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); + + mbedtls_ctr_drbg_init( &ctr_drbg ); + mbedtls_entropy_init( &entropy ); + TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, + &entropy, (const unsigned char *) pers, + strlen( pers ) ) == 0 ); + + if( have_N ) + TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 ); + + if( have_P ) + TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 ); + + if( have_Q ) + TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 ); + + if( have_D ) + TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 ); + + if( have_E ) + TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_validate_params( have_N ? &N : NULL, + have_P ? &P : NULL, + have_Q ? &Q : NULL, + have_D ? &D : NULL, + have_E ? &E : NULL, + prng ? mbedtls_ctr_drbg_random : NULL, + prng ? &ctr_drbg : NULL ) == result ); +exit: + + mbedtls_ctr_drbg_free( &ctr_drbg ); + mbedtls_entropy_free( &entropy ); + + mbedtls_mpi_free( &N ); + mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C */ +void mbedtls_rsa_export_raw( char *input_N, char *input_P, + char *input_Q, char *input_D, + char *input_E, int is_priv, + int successive ) +{ + /* Original raw buffers with which we set up the RSA context */ + unsigned char bufN[1000]; + unsigned char bufP[1000]; + unsigned char bufQ[1000]; + unsigned char bufD[1000]; + unsigned char bufE[1000]; + + size_t lenN = 0; + size_t lenP = 0; + size_t lenQ = 0; + size_t lenD = 0; + size_t lenE = 0; + + /* Exported buffers */ + unsigned char bufNe[ sizeof( bufN ) ]; + unsigned char bufPe[ sizeof( bufP ) ]; + unsigned char bufQe[ sizeof( bufQ ) ]; + unsigned char bufDe[ sizeof( bufD ) ]; + unsigned char bufEe[ sizeof( bufE ) ]; + + const int have_N = ( strlen( input_N ) > 0 ); + const int have_P = ( strlen( input_P ) > 0 ); + const int have_Q = ( strlen( input_Q ) > 0 ); + const int have_D = ( strlen( input_D ) > 0 ); + const int have_E = ( strlen( input_E ) > 0 ); + + mbedtls_rsa_context ctx; + + mbedtls_rsa_init( &ctx, 0, 0 ); + + /* Setup RSA context */ + + if( have_N ) + lenN = unhexify( bufN, input_N ); + + if( have_P ) + lenP = unhexify( bufP, input_P ); + + if( have_Q ) + lenQ = unhexify( bufQ, input_Q ); + + if( have_D ) + lenD = unhexify( bufD, input_D ); + + if( have_E ) + lenE = unhexify( bufE, input_E ); + + TEST_ASSERT( mbedtls_rsa_import_raw( &ctx, + have_N ? bufN : NULL, lenN, + have_P ? bufP : NULL, lenP, + have_Q ? bufQ : NULL, lenQ, + have_D ? bufD : NULL, lenD, + have_E ? bufE : NULL, lenE ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 ); + + /* + * Export parameters and compare to original ones. + */ + + /* N and E must always be present. */ + if( !successive ) + { + TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, bufNe, lenN, + NULL, 0, NULL, 0, NULL, 0, + bufEe, lenE ) == 0 ); + } + else + { + TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, bufNe, lenN, + NULL, 0, NULL, 0, NULL, 0, + NULL, 0 ) == 0 ); + TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, + bufEe, lenE ) == 0 ); + } + TEST_ASSERT( memcmp( bufN, bufNe, lenN ) == 0 ); + TEST_ASSERT( memcmp( bufE, bufEe, lenE ) == 0 ); + + /* If we were providing enough information to setup a complete private context, + * we expect to be able to export all core parameters. */ + + if( is_priv ) + { + if( !successive ) + { + TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0, + bufPe, lenP ? lenP : sizeof( bufPe ), + bufQe, lenQ ? lenQ : sizeof( bufQe ), + bufDe, lenD ? lenD : sizeof( bufDe ), + NULL, 0 ) == 0 ); + } + else + { + TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0, + bufPe, lenP ? lenP : sizeof( bufPe ), + NULL, 0, NULL, 0, + NULL, 0 ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0, NULL, 0, + bufQe, lenQ ? lenQ : sizeof( bufQe ), + NULL, 0, NULL, 0 ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_export_raw( &ctx, NULL, 0, NULL, 0, + NULL, 0, bufDe, lenD ? lenD : sizeof( bufDe ), + NULL, 0 ) == 0 ); + } + + if( have_P ) + TEST_ASSERT( memcmp( bufP, bufPe, lenP ) == 0 ); + + if( have_Q ) + TEST_ASSERT( memcmp( bufQ, bufQe, lenQ ) == 0 ); + + if( have_D ) + TEST_ASSERT( memcmp( bufD, bufDe, lenD ) == 0 ); + + } + +exit: + mbedtls_rsa_free( &ctx ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */ +void mbedtls_rsa_import_raw( char *input_N, + char *input_P, char *input_Q, + char *input_D, char *input_E, + int successive, + int is_priv, + int res_check, + int res_complete ) +{ + unsigned char bufN[1000]; + unsigned char bufP[1000]; + unsigned char bufQ[1000]; + unsigned char bufD[1000]; + unsigned char bufE[1000]; + + /* Buffers used for encryption-decryption test */ + unsigned char *buf_orig = NULL; + unsigned char *buf_enc = NULL; + unsigned char *buf_dec = NULL; + + size_t lenN = 0; + size_t lenP = 0; + size_t lenQ = 0; + size_t lenD = 0; + size_t lenE = 0; + + mbedtls_rsa_context ctx; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + + const char *pers = "test_suite_rsa"; + + mbedtls_ctr_drbg_init( &ctr_drbg ); + mbedtls_entropy_init( &entropy ); + mbedtls_rsa_init( &ctx, 0, 0 ); + + TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, + &entropy, (const unsigned char *) pers, + strlen( pers ) ) == 0 ); + + if( strlen( input_N ) ) + lenN = unhexify( bufN, input_N ); + + if( strlen( input_P ) ) + lenP = unhexify( bufP, input_P ); + + if( strlen( input_Q ) ) + lenQ = unhexify( bufQ, input_Q ); + + if( strlen( input_D ) ) + lenD = unhexify( bufD, input_D ); + + if( strlen( input_E ) ) + lenE = unhexify( bufE, input_E ); + + if( !successive ) + { + TEST_ASSERT( mbedtls_rsa_import_raw( &ctx, + ( lenN > 0 ) ? bufN : NULL, lenN, + ( lenP > 0 ) ? bufP : NULL, lenP, + ( lenQ > 0 ) ? bufQ : NULL, lenQ, + ( lenD > 0 ) ? bufD : NULL, lenD, + ( lenE > 0 ) ? bufE : NULL, lenE ) == 0 ); + } + else + { + /* Import N, P, Q, D, E separately. + * This should make no functional difference. */ + + TEST_ASSERT( mbedtls_rsa_import_raw( &ctx, + ( lenN > 0 ) ? bufN : NULL, lenN, + NULL, 0, NULL, 0, NULL, 0, NULL, 0 ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import_raw( &ctx, + NULL, 0, + ( lenP > 0 ) ? bufP : NULL, lenP, + NULL, 0, NULL, 0, NULL, 0 ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import_raw( &ctx, + NULL, 0, NULL, 0, + ( lenQ > 0 ) ? bufQ : NULL, lenQ, + NULL, 0, NULL, 0 ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import_raw( &ctx, + NULL, 0, NULL, 0, NULL, 0, + ( lenD > 0 ) ? bufD : NULL, lenD, + NULL, 0 ) == 0 ); + + TEST_ASSERT( mbedtls_rsa_import_raw( &ctx, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, + ( lenE > 0 ) ? bufE : NULL, lenE ) == 0 ); + } + + TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == res_complete ); + + /* On expected success, perform some public and private + * key operations to check if the key is working properly. */ + if( res_complete == 0 ) + { + if( is_priv ) + TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == res_check ); + else + TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == res_check ); + + if( res_check != 0 ) + goto exit; + + buf_orig = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) ); + buf_enc = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) ); + buf_dec = mbedtls_calloc( 1, mbedtls_rsa_get_len( &ctx ) ); + if( buf_orig == NULL || buf_enc == NULL || buf_dec == NULL ) + goto exit; + + TEST_ASSERT( mbedtls_ctr_drbg_random( &ctr_drbg, + buf_orig, mbedtls_rsa_get_len( &ctx ) ) == 0 ); + + /* Make sure the number we're generating is smaller than the modulus */ + buf_orig[0] = 0x00; + + TEST_ASSERT( mbedtls_rsa_public( &ctx, buf_orig, buf_enc ) == 0 ); + + if( is_priv ) + { + TEST_ASSERT( mbedtls_rsa_private( &ctx, mbedtls_ctr_drbg_random, + &ctr_drbg, buf_enc, + buf_dec ) == 0 ); + + TEST_ASSERT( memcmp( buf_orig, buf_dec, + mbedtls_rsa_get_len( &ctx ) ) == 0 ); + } + } + +exit: + + mbedtls_free( buf_orig ); + mbedtls_free( buf_enc ); + mbedtls_free( buf_dec ); + + mbedtls_rsa_free( &ctx ); + + mbedtls_ctr_drbg_free( &ctr_drbg ); + mbedtls_entropy_free( &entropy ); + +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void rsa_selftest() {