mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-07-07 16:30:46 +00:00
Introduce new files rsa_internal.[ch] for RSA helper functions
This commit splits off the RSA helper functions into separate headers and compilation units to have a clearer separation of the public RSA interface, intended to be used by end-users, and the helper functions which are publicly provided only for the benefit of designers of alternative RSA implementations.
This commit is contained in:
parent
04877a48d4
commit
a565f54c4c
|
@ -1650,6 +1650,7 @@
|
||||||
* library/ecp.c
|
* library/ecp.c
|
||||||
* library/ecdsa.c
|
* library/ecdsa.c
|
||||||
* library/rsa.c
|
* library/rsa.c
|
||||||
|
* library/rsa_internal.c
|
||||||
* library/ssl_tls.c
|
* library/ssl_tls.c
|
||||||
*
|
*
|
||||||
* This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
|
* This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
|
||||||
|
@ -2263,6 +2264,7 @@
|
||||||
* Enable the RSA public-key cryptosystem.
|
* Enable the RSA public-key cryptosystem.
|
||||||
*
|
*
|
||||||
* Module: library/rsa.c
|
* Module: library/rsa.c
|
||||||
|
* library/rsa_internal.c
|
||||||
* Caller: library/ssl_cli.c
|
* Caller: library/ssl_cli.c
|
||||||
* library/ssl_srv.c
|
* library/ssl_srv.c
|
||||||
* library/ssl_tls.c
|
* library/ssl_tls.c
|
||||||
|
|
|
@ -74,162 +74,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper functions for RSA-related operations on MPI's.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \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 D RSA private exponent
|
|
||||||
* \param E RSA public 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 *D,
|
|
||||||
mbedtls_mpi const *E,
|
|
||||||
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 = PQ
|
|
||||||
* - 1 < D, E < N
|
|
||||||
* - D and E are modular inverses modulo P-1 and Q-1
|
|
||||||
* - 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 );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of RSA interface
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_RSA_ALT)
|
#if !defined(MBEDTLS_RSA_ALT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
219
include/mbedtls/rsa_internal.h
Normal file
219
include/mbedtls/rsa_internal.h
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
/**
|
||||||
|
* \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 make do with the implementation of the RSA module.
|
||||||
|
*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_RSA_C)
|
||||||
|
|
||||||
|
#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 D RSA private exponent
|
||||||
|
* \param E RSA public 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 *D,
|
||||||
|
mbedtls_mpi const *E,
|
||||||
|
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 = PQ
|
||||||
|
* - 1 < D, E < N
|
||||||
|
* - D and E are modular inverses modulo P-1 and Q-1
|
||||||
|
* - 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 /* MBEDTLS_RSA_C */
|
||||||
|
|
||||||
|
#endif /* rsa_internal.h */
|
|
@ -48,6 +48,7 @@ set(src_crypto
|
||||||
platform.c
|
platform.c
|
||||||
ripemd160.c
|
ripemd160.c
|
||||||
rsa.c
|
rsa.c
|
||||||
|
rsa_internal.c
|
||||||
sha1.c
|
sha1.c
|
||||||
sha256.c
|
sha256.c
|
||||||
sha512.c
|
sha512.c
|
||||||
|
|
|
@ -59,9 +59,9 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
|
||||||
padlock.o pem.o pk.o \
|
padlock.o pem.o pk.o \
|
||||||
pk_wrap.o pkcs12.o pkcs5.o \
|
pk_wrap.o pkcs12.o pkcs5.o \
|
||||||
pkparse.o pkwrite.o platform.o \
|
pkparse.o pkwrite.o platform.o \
|
||||||
ripemd160.o rsa.o sha1.o \
|
ripemd160.o rsa_internal.o rsa.o \
|
||||||
sha256.o sha512.o threading.o \
|
sha1.o sha256.o sha512.o \
|
||||||
timing.o version.o \
|
threading.o timing.o version.o \
|
||||||
version_features.o xtea.o
|
version_features.o xtea.o
|
||||||
|
|
||||||
OBJS_X509= certs.o pkcs11.o x509.o \
|
OBJS_X509= certs.o pkcs11.o x509.o \
|
||||||
|
|
475
library/rsa.c
475
library/rsa.c
|
@ -46,6 +46,7 @@
|
||||||
#if defined(MBEDTLS_RSA_C)
|
#if defined(MBEDTLS_RSA_C)
|
||||||
|
|
||||||
#include "mbedtls/rsa.h"
|
#include "mbedtls/rsa.h"
|
||||||
|
#include "mbedtls/rsa_internal.h"
|
||||||
#include "mbedtls/oid.h"
|
#include "mbedtls/oid.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -67,483 +68,13 @@
|
||||||
#define mbedtls_free free
|
#define mbedtls_free free
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_RSA_ALT)
|
||||||
|
|
||||||
/* Implementation that should never be optimized out by the compiler */
|
/* Implementation that should never be optimized out by the compiler */
|
||||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||||
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
|
volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Context-independent RSA helper functions.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* The helper functions do not use the RSA context structure
|
|
||||||
* and therefore do not need to be replaced when providing
|
|
||||||
* an alternative RSA implementation.
|
|
||||||
*
|
|
||||||
* Their main purpose is to provide common MPI operations in the context
|
|
||||||
* of RSA that can be easily shared across multiple implementations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Given the modulus N=PQ and a pair of public and private
|
|
||||||
* exponents E and D, respectively, factor N.
|
|
||||||
*
|
|
||||||
* 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 *D, mbedtls_mpi const *E,
|
|
||||||
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; /* During factorization attempts, stores a random integer
|
|
||||||
* in the range of [0,..,N] */
|
|
||||||
|
|
||||||
const unsigned int 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, 257, 263, 269,
|
|
||||||
271, 277, 281, 283, 293, 307, 311, 313
|
|
||||||
};
|
|
||||||
|
|
||||||
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 = 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 )
|
|
||||||
{
|
|
||||||
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 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = PQ
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default RSA interface implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_RSA_ALT)
|
|
||||||
|
|
||||||
int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
|
int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
|
||||||
const mbedtls_mpi *N,
|
const mbedtls_mpi *N,
|
||||||
const mbedtls_mpi *P, const mbedtls_mpi *Q,
|
const mbedtls_mpi *P, const mbedtls_mpi *Q,
|
||||||
|
|
471
library/rsa_internal.c
Normal file
471
library/rsa_internal.c
Normal file
|
@ -0,0 +1,471 @@
|
||||||
|
/*
|
||||||
|
* 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 *D, mbedtls_mpi const *E,
|
||||||
|
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 int 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, 257, 263, 269,
|
||||||
|
271, 277, 281, 283, 293, 307, 311, 313
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = 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 )
|
||||||
|
{
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = PQ
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 */
|
|
@ -1,5 +1,6 @@
|
||||||
/* BEGIN_HEADER */
|
/* BEGIN_HEADER */
|
||||||
#include "mbedtls/rsa.h"
|
#include "mbedtls/rsa.h"
|
||||||
|
#include "mbedtls/rsa_internal.h"
|
||||||
#include "mbedtls/md2.h"
|
#include "mbedtls/md2.h"
|
||||||
#include "mbedtls/md4.h"
|
#include "mbedtls/md4.h"
|
||||||
#include "mbedtls/md5.h"
|
#include "mbedtls/md5.h"
|
||||||
|
|
Loading…
Reference in a new issue