xref: /aosp_15_r20/external/mbedtls/library/rsa.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi  *  The RSA public-key cryptosystem
3*62c56f98SSadaf Ebrahimi  *
4*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
5*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6*62c56f98SSadaf Ebrahimi  */
7*62c56f98SSadaf Ebrahimi 
8*62c56f98SSadaf Ebrahimi /*
9*62c56f98SSadaf Ebrahimi  *  The following sources were referenced in the design of this implementation
10*62c56f98SSadaf Ebrahimi  *  of the RSA algorithm:
11*62c56f98SSadaf Ebrahimi  *
12*62c56f98SSadaf Ebrahimi  *  [1] A method for obtaining digital signatures and public-key cryptosystems
13*62c56f98SSadaf Ebrahimi  *      R Rivest, A Shamir, and L Adleman
14*62c56f98SSadaf Ebrahimi  *      http://people.csail.mit.edu/rivest/pubs.html#RSA78
15*62c56f98SSadaf Ebrahimi  *
16*62c56f98SSadaf Ebrahimi  *  [2] Handbook of Applied Cryptography - 1997, Chapter 8
17*62c56f98SSadaf Ebrahimi  *      Menezes, van Oorschot and Vanstone
18*62c56f98SSadaf Ebrahimi  *
19*62c56f98SSadaf Ebrahimi  *  [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
20*62c56f98SSadaf Ebrahimi  *      Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
21*62c56f98SSadaf Ebrahimi  *      Stefan Mangard
22*62c56f98SSadaf Ebrahimi  *      https://arxiv.org/abs/1702.08719v2
23*62c56f98SSadaf Ebrahimi  *
24*62c56f98SSadaf Ebrahimi  */
25*62c56f98SSadaf Ebrahimi 
26*62c56f98SSadaf Ebrahimi #include "common.h"
27*62c56f98SSadaf Ebrahimi 
28*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
29*62c56f98SSadaf Ebrahimi 
30*62c56f98SSadaf Ebrahimi #include "mbedtls/rsa.h"
31*62c56f98SSadaf Ebrahimi #include "bignum_core.h"
32*62c56f98SSadaf Ebrahimi #include "rsa_alt_helpers.h"
33*62c56f98SSadaf Ebrahimi #include "mbedtls/oid.h"
34*62c56f98SSadaf Ebrahimi #include "mbedtls/platform_util.h"
35*62c56f98SSadaf Ebrahimi #include "mbedtls/error.h"
36*62c56f98SSadaf Ebrahimi #include "constant_time_internal.h"
37*62c56f98SSadaf Ebrahimi #include "mbedtls/constant_time.h"
38*62c56f98SSadaf Ebrahimi #include "md_psa.h"
39*62c56f98SSadaf Ebrahimi 
40*62c56f98SSadaf Ebrahimi #include <string.h>
41*62c56f98SSadaf Ebrahimi 
42*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__)
43*62c56f98SSadaf Ebrahimi #include <stdlib.h>
44*62c56f98SSadaf Ebrahimi #endif
45*62c56f98SSadaf Ebrahimi 
46*62c56f98SSadaf Ebrahimi #include "mbedtls/platform.h"
47*62c56f98SSadaf Ebrahimi 
48*62c56f98SSadaf Ebrahimi 
49*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
50*62c56f98SSadaf Ebrahimi 
51*62c56f98SSadaf Ebrahimi /** This function performs the unpadding part of a PKCS#1 v1.5 decryption
52*62c56f98SSadaf Ebrahimi  *  operation (EME-PKCS1-v1_5 decoding).
53*62c56f98SSadaf Ebrahimi  *
54*62c56f98SSadaf Ebrahimi  * \note The return value from this function is a sensitive value
55*62c56f98SSadaf Ebrahimi  *       (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
56*62c56f98SSadaf Ebrahimi  *       in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
57*62c56f98SSadaf Ebrahimi  *       is often a situation that an attacker can provoke and leaking which
58*62c56f98SSadaf Ebrahimi  *       one is the result is precisely the information the attacker wants.
59*62c56f98SSadaf Ebrahimi  *
60*62c56f98SSadaf Ebrahimi  * \param input          The input buffer which is the payload inside PKCS#1v1.5
61*62c56f98SSadaf Ebrahimi  *                       encryption padding, called the "encoded message EM"
62*62c56f98SSadaf Ebrahimi  *                       by the terminology.
63*62c56f98SSadaf Ebrahimi  * \param ilen           The length of the payload in the \p input buffer.
64*62c56f98SSadaf Ebrahimi  * \param output         The buffer for the payload, called "message M" by the
65*62c56f98SSadaf Ebrahimi  *                       PKCS#1 terminology. This must be a writable buffer of
66*62c56f98SSadaf Ebrahimi  *                       length \p output_max_len bytes.
67*62c56f98SSadaf Ebrahimi  * \param olen           The address at which to store the length of
68*62c56f98SSadaf Ebrahimi  *                       the payload. This must not be \c NULL.
69*62c56f98SSadaf Ebrahimi  * \param output_max_len The length in bytes of the output buffer \p output.
70*62c56f98SSadaf Ebrahimi  *
71*62c56f98SSadaf Ebrahimi  * \return      \c 0 on success.
72*62c56f98SSadaf Ebrahimi  * \return      #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
73*62c56f98SSadaf Ebrahimi  *              The output buffer is too small for the unpadded payload.
74*62c56f98SSadaf Ebrahimi  * \return      #MBEDTLS_ERR_RSA_INVALID_PADDING
75*62c56f98SSadaf Ebrahimi  *              The input doesn't contain properly formatted padding.
76*62c56f98SSadaf Ebrahimi  */
mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char * input,size_t ilen,unsigned char * output,size_t output_max_len,size_t * olen)77*62c56f98SSadaf Ebrahimi static int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input,
78*62c56f98SSadaf Ebrahimi                                                 size_t ilen,
79*62c56f98SSadaf Ebrahimi                                                 unsigned char *output,
80*62c56f98SSadaf Ebrahimi                                                 size_t output_max_len,
81*62c56f98SSadaf Ebrahimi                                                 size_t *olen)
82*62c56f98SSadaf Ebrahimi {
83*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
84*62c56f98SSadaf Ebrahimi     size_t i, plaintext_max_size;
85*62c56f98SSadaf Ebrahimi 
86*62c56f98SSadaf Ebrahimi     /* The following variables take sensitive values: their value must
87*62c56f98SSadaf Ebrahimi      * not leak into the observable behavior of the function other than
88*62c56f98SSadaf Ebrahimi      * the designated outputs (output, olen, return value). Otherwise
89*62c56f98SSadaf Ebrahimi      * this would open the execution of the function to
90*62c56f98SSadaf Ebrahimi      * side-channel-based variants of the Bleichenbacher padding oracle
91*62c56f98SSadaf Ebrahimi      * attack. Potential side channels include overall timing, memory
92*62c56f98SSadaf Ebrahimi      * access patterns (especially visible to an adversary who has access
93*62c56f98SSadaf Ebrahimi      * to a shared memory cache), and branches (especially visible to
94*62c56f98SSadaf Ebrahimi      * an adversary who has access to a shared code cache or to a shared
95*62c56f98SSadaf Ebrahimi      * branch predictor). */
96*62c56f98SSadaf Ebrahimi     size_t pad_count = 0;
97*62c56f98SSadaf Ebrahimi     mbedtls_ct_condition_t bad;
98*62c56f98SSadaf Ebrahimi     mbedtls_ct_condition_t pad_done;
99*62c56f98SSadaf Ebrahimi     size_t plaintext_size = 0;
100*62c56f98SSadaf Ebrahimi     mbedtls_ct_condition_t output_too_large;
101*62c56f98SSadaf Ebrahimi 
102*62c56f98SSadaf Ebrahimi     plaintext_max_size = (output_max_len > ilen - 11) ? ilen - 11
103*62c56f98SSadaf Ebrahimi                                                         : output_max_len;
104*62c56f98SSadaf Ebrahimi 
105*62c56f98SSadaf Ebrahimi     /* Check and get padding length in constant time and constant
106*62c56f98SSadaf Ebrahimi      * memory trace. The first byte must be 0. */
107*62c56f98SSadaf Ebrahimi     bad = mbedtls_ct_bool(input[0]);
108*62c56f98SSadaf Ebrahimi 
109*62c56f98SSadaf Ebrahimi 
110*62c56f98SSadaf Ebrahimi     /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
111*62c56f98SSadaf Ebrahimi      * where PS must be at least 8 nonzero bytes. */
112*62c56f98SSadaf Ebrahimi     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(input[1], MBEDTLS_RSA_CRYPT));
113*62c56f98SSadaf Ebrahimi 
114*62c56f98SSadaf Ebrahimi     /* Read the whole buffer. Set pad_done to nonzero if we find
115*62c56f98SSadaf Ebrahimi      * the 0x00 byte and remember the padding length in pad_count. */
116*62c56f98SSadaf Ebrahimi     pad_done = MBEDTLS_CT_FALSE;
117*62c56f98SSadaf Ebrahimi     for (i = 2; i < ilen; i++) {
118*62c56f98SSadaf Ebrahimi         mbedtls_ct_condition_t found = mbedtls_ct_uint_eq(input[i], 0);
119*62c56f98SSadaf Ebrahimi         pad_done   = mbedtls_ct_bool_or(pad_done, found);
120*62c56f98SSadaf Ebrahimi         pad_count += mbedtls_ct_uint_if_else_0(mbedtls_ct_bool_not(pad_done), 1);
121*62c56f98SSadaf Ebrahimi     }
122*62c56f98SSadaf Ebrahimi 
123*62c56f98SSadaf Ebrahimi     /* If pad_done is still zero, there's no data, only unfinished padding. */
124*62c56f98SSadaf Ebrahimi     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_not(pad_done));
125*62c56f98SSadaf Ebrahimi 
126*62c56f98SSadaf Ebrahimi     /* There must be at least 8 bytes of padding. */
127*62c56f98SSadaf Ebrahimi     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_gt(8, pad_count));
128*62c56f98SSadaf Ebrahimi 
129*62c56f98SSadaf Ebrahimi     /* If the padding is valid, set plaintext_size to the number of
130*62c56f98SSadaf Ebrahimi      * remaining bytes after stripping the padding. If the padding
131*62c56f98SSadaf Ebrahimi      * is invalid, avoid leaking this fact through the size of the
132*62c56f98SSadaf Ebrahimi      * output: use the maximum message size that fits in the output
133*62c56f98SSadaf Ebrahimi      * buffer. Do it without branches to avoid leaking the padding
134*62c56f98SSadaf Ebrahimi      * validity through timing. RSA keys are small enough that all the
135*62c56f98SSadaf Ebrahimi      * size_t values involved fit in unsigned int. */
136*62c56f98SSadaf Ebrahimi     plaintext_size = mbedtls_ct_uint_if(
137*62c56f98SSadaf Ebrahimi         bad, (unsigned) plaintext_max_size,
138*62c56f98SSadaf Ebrahimi         (unsigned) (ilen - pad_count - 3));
139*62c56f98SSadaf Ebrahimi 
140*62c56f98SSadaf Ebrahimi     /* Set output_too_large to 0 if the plaintext fits in the output
141*62c56f98SSadaf Ebrahimi      * buffer and to 1 otherwise. */
142*62c56f98SSadaf Ebrahimi     output_too_large = mbedtls_ct_uint_gt(plaintext_size,
143*62c56f98SSadaf Ebrahimi                                           plaintext_max_size);
144*62c56f98SSadaf Ebrahimi 
145*62c56f98SSadaf Ebrahimi     /* Set ret without branches to avoid timing attacks. Return:
146*62c56f98SSadaf Ebrahimi      * - INVALID_PADDING if the padding is bad (bad != 0).
147*62c56f98SSadaf Ebrahimi      * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
148*62c56f98SSadaf Ebrahimi      *   plaintext does not fit in the output buffer.
149*62c56f98SSadaf Ebrahimi      * - 0 if the padding is correct. */
150*62c56f98SSadaf Ebrahimi     ret = mbedtls_ct_error_if(
151*62c56f98SSadaf Ebrahimi         bad,
152*62c56f98SSadaf Ebrahimi         MBEDTLS_ERR_RSA_INVALID_PADDING,
153*62c56f98SSadaf Ebrahimi         mbedtls_ct_error_if_else_0(output_too_large, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE)
154*62c56f98SSadaf Ebrahimi         );
155*62c56f98SSadaf Ebrahimi 
156*62c56f98SSadaf Ebrahimi     /* If the padding is bad or the plaintext is too large, zero the
157*62c56f98SSadaf Ebrahimi      * data that we're about to copy to the output buffer.
158*62c56f98SSadaf Ebrahimi      * We need to copy the same amount of data
159*62c56f98SSadaf Ebrahimi      * from the same buffer whether the padding is good or not to
160*62c56f98SSadaf Ebrahimi      * avoid leaking the padding validity through overall timing or
161*62c56f98SSadaf Ebrahimi      * through memory or cache access patterns. */
162*62c56f98SSadaf Ebrahimi     mbedtls_ct_zeroize_if(mbedtls_ct_bool_or(bad, output_too_large), input + 11, ilen - 11);
163*62c56f98SSadaf Ebrahimi 
164*62c56f98SSadaf Ebrahimi     /* If the plaintext is too large, truncate it to the buffer size.
165*62c56f98SSadaf Ebrahimi      * Copy anyway to avoid revealing the length through timing, because
166*62c56f98SSadaf Ebrahimi      * revealing the length is as bad as revealing the padding validity
167*62c56f98SSadaf Ebrahimi      * for a Bleichenbacher attack. */
168*62c56f98SSadaf Ebrahimi     plaintext_size = mbedtls_ct_uint_if(output_too_large,
169*62c56f98SSadaf Ebrahimi                                         (unsigned) plaintext_max_size,
170*62c56f98SSadaf Ebrahimi                                         (unsigned) plaintext_size);
171*62c56f98SSadaf Ebrahimi 
172*62c56f98SSadaf Ebrahimi     /* Move the plaintext to the leftmost position where it can start in
173*62c56f98SSadaf Ebrahimi      * the working buffer, i.e. make it start plaintext_max_size from
174*62c56f98SSadaf Ebrahimi      * the end of the buffer. Do this with a memory access trace that
175*62c56f98SSadaf Ebrahimi      * does not depend on the plaintext size. After this move, the
176*62c56f98SSadaf Ebrahimi      * starting location of the plaintext is no longer sensitive
177*62c56f98SSadaf Ebrahimi      * information. */
178*62c56f98SSadaf Ebrahimi     mbedtls_ct_memmove_left(input + ilen - plaintext_max_size,
179*62c56f98SSadaf Ebrahimi                             plaintext_max_size,
180*62c56f98SSadaf Ebrahimi                             plaintext_max_size - plaintext_size);
181*62c56f98SSadaf Ebrahimi 
182*62c56f98SSadaf Ebrahimi     /* Finally copy the decrypted plaintext plus trailing zeros into the output
183*62c56f98SSadaf Ebrahimi      * buffer. If output_max_len is 0, then output may be an invalid pointer
184*62c56f98SSadaf Ebrahimi      * and the result of memcpy() would be undefined; prevent undefined
185*62c56f98SSadaf Ebrahimi      * behavior making sure to depend only on output_max_len (the size of the
186*62c56f98SSadaf Ebrahimi      * user-provided output buffer), which is independent from plaintext
187*62c56f98SSadaf Ebrahimi      * length, validity of padding, success of the decryption, and other
188*62c56f98SSadaf Ebrahimi      * secrets. */
189*62c56f98SSadaf Ebrahimi     if (output_max_len != 0) {
190*62c56f98SSadaf Ebrahimi         memcpy(output, input + ilen - plaintext_max_size, plaintext_max_size);
191*62c56f98SSadaf Ebrahimi     }
192*62c56f98SSadaf Ebrahimi 
193*62c56f98SSadaf Ebrahimi     /* Report the amount of data we copied to the output buffer. In case
194*62c56f98SSadaf Ebrahimi      * of errors (bad padding or output too large), the value of *olen
195*62c56f98SSadaf Ebrahimi      * when this function returns is not specified. Making it equivalent
196*62c56f98SSadaf Ebrahimi      * to the good case limits the risks of leaking the padding validity. */
197*62c56f98SSadaf Ebrahimi     *olen = plaintext_size;
198*62c56f98SSadaf Ebrahimi 
199*62c56f98SSadaf Ebrahimi     return ret;
200*62c56f98SSadaf Ebrahimi }
201*62c56f98SSadaf Ebrahimi 
202*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
203*62c56f98SSadaf Ebrahimi 
204*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_ALT)
205*62c56f98SSadaf Ebrahimi 
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)206*62c56f98SSadaf Ebrahimi int mbedtls_rsa_import(mbedtls_rsa_context *ctx,
207*62c56f98SSadaf Ebrahimi                        const mbedtls_mpi *N,
208*62c56f98SSadaf Ebrahimi                        const mbedtls_mpi *P, const mbedtls_mpi *Q,
209*62c56f98SSadaf Ebrahimi                        const mbedtls_mpi *D, const mbedtls_mpi *E)
210*62c56f98SSadaf Ebrahimi {
211*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
212*62c56f98SSadaf Ebrahimi 
213*62c56f98SSadaf Ebrahimi     if ((N != NULL && (ret = mbedtls_mpi_copy(&ctx->N, N)) != 0) ||
214*62c56f98SSadaf Ebrahimi         (P != NULL && (ret = mbedtls_mpi_copy(&ctx->P, P)) != 0) ||
215*62c56f98SSadaf Ebrahimi         (Q != NULL && (ret = mbedtls_mpi_copy(&ctx->Q, Q)) != 0) ||
216*62c56f98SSadaf Ebrahimi         (D != NULL && (ret = mbedtls_mpi_copy(&ctx->D, D)) != 0) ||
217*62c56f98SSadaf Ebrahimi         (E != NULL && (ret = mbedtls_mpi_copy(&ctx->E, E)) != 0)) {
218*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
219*62c56f98SSadaf Ebrahimi     }
220*62c56f98SSadaf Ebrahimi 
221*62c56f98SSadaf Ebrahimi     if (N != NULL) {
222*62c56f98SSadaf Ebrahimi         ctx->len = mbedtls_mpi_size(&ctx->N);
223*62c56f98SSadaf Ebrahimi     }
224*62c56f98SSadaf Ebrahimi 
225*62c56f98SSadaf Ebrahimi     return 0;
226*62c56f98SSadaf Ebrahimi }
227*62c56f98SSadaf Ebrahimi 
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)228*62c56f98SSadaf Ebrahimi int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx,
229*62c56f98SSadaf Ebrahimi                            unsigned char const *N, size_t N_len,
230*62c56f98SSadaf Ebrahimi                            unsigned char const *P, size_t P_len,
231*62c56f98SSadaf Ebrahimi                            unsigned char const *Q, size_t Q_len,
232*62c56f98SSadaf Ebrahimi                            unsigned char const *D, size_t D_len,
233*62c56f98SSadaf Ebrahimi                            unsigned char const *E, size_t E_len)
234*62c56f98SSadaf Ebrahimi {
235*62c56f98SSadaf Ebrahimi     int ret = 0;
236*62c56f98SSadaf Ebrahimi 
237*62c56f98SSadaf Ebrahimi     if (N != NULL) {
238*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->N, N, N_len));
239*62c56f98SSadaf Ebrahimi         ctx->len = mbedtls_mpi_size(&ctx->N);
240*62c56f98SSadaf Ebrahimi     }
241*62c56f98SSadaf Ebrahimi 
242*62c56f98SSadaf Ebrahimi     if (P != NULL) {
243*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->P, P, P_len));
244*62c56f98SSadaf Ebrahimi     }
245*62c56f98SSadaf Ebrahimi 
246*62c56f98SSadaf Ebrahimi     if (Q != NULL) {
247*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->Q, Q, Q_len));
248*62c56f98SSadaf Ebrahimi     }
249*62c56f98SSadaf Ebrahimi 
250*62c56f98SSadaf Ebrahimi     if (D != NULL) {
251*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->D, D, D_len));
252*62c56f98SSadaf Ebrahimi     }
253*62c56f98SSadaf Ebrahimi 
254*62c56f98SSadaf Ebrahimi     if (E != NULL) {
255*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->E, E, E_len));
256*62c56f98SSadaf Ebrahimi     }
257*62c56f98SSadaf Ebrahimi 
258*62c56f98SSadaf Ebrahimi cleanup:
259*62c56f98SSadaf Ebrahimi 
260*62c56f98SSadaf Ebrahimi     if (ret != 0) {
261*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
262*62c56f98SSadaf Ebrahimi     }
263*62c56f98SSadaf Ebrahimi 
264*62c56f98SSadaf Ebrahimi     return 0;
265*62c56f98SSadaf Ebrahimi }
266*62c56f98SSadaf Ebrahimi 
267*62c56f98SSadaf Ebrahimi /*
268*62c56f98SSadaf Ebrahimi  * Checks whether the context fields are set in such a way
269*62c56f98SSadaf Ebrahimi  * that the RSA primitives will be able to execute without error.
270*62c56f98SSadaf Ebrahimi  * It does *not* make guarantees for consistency of the parameters.
271*62c56f98SSadaf Ebrahimi  */
rsa_check_context(mbedtls_rsa_context const * ctx,int is_priv,int blinding_needed)272*62c56f98SSadaf Ebrahimi static int rsa_check_context(mbedtls_rsa_context const *ctx, int is_priv,
273*62c56f98SSadaf Ebrahimi                              int blinding_needed)
274*62c56f98SSadaf Ebrahimi {
275*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
276*62c56f98SSadaf Ebrahimi     /* blinding_needed is only used for NO_CRT to decide whether
277*62c56f98SSadaf Ebrahimi      * P,Q need to be present or not. */
278*62c56f98SSadaf Ebrahimi     ((void) blinding_needed);
279*62c56f98SSadaf Ebrahimi #endif
280*62c56f98SSadaf Ebrahimi 
281*62c56f98SSadaf Ebrahimi     if (ctx->len != mbedtls_mpi_size(&ctx->N) ||
282*62c56f98SSadaf Ebrahimi         ctx->len > MBEDTLS_MPI_MAX_SIZE) {
283*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
284*62c56f98SSadaf Ebrahimi     }
285*62c56f98SSadaf Ebrahimi 
286*62c56f98SSadaf Ebrahimi     /*
287*62c56f98SSadaf Ebrahimi      * 1. Modular exponentiation needs positive, odd moduli.
288*62c56f98SSadaf Ebrahimi      */
289*62c56f98SSadaf Ebrahimi 
290*62c56f98SSadaf Ebrahimi     /* Modular exponentiation wrt. N is always used for
291*62c56f98SSadaf Ebrahimi      * RSA public key operations. */
292*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_cmp_int(&ctx->N, 0) <= 0 ||
293*62c56f98SSadaf Ebrahimi         mbedtls_mpi_get_bit(&ctx->N, 0) == 0) {
294*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
295*62c56f98SSadaf Ebrahimi     }
296*62c56f98SSadaf Ebrahimi 
297*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
298*62c56f98SSadaf Ebrahimi     /* Modular exponentiation for P and Q is only
299*62c56f98SSadaf Ebrahimi      * used for private key operations and if CRT
300*62c56f98SSadaf Ebrahimi      * is used. */
301*62c56f98SSadaf Ebrahimi     if (is_priv &&
302*62c56f98SSadaf Ebrahimi         (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 ||
303*62c56f98SSadaf Ebrahimi          mbedtls_mpi_get_bit(&ctx->P, 0) == 0 ||
304*62c56f98SSadaf Ebrahimi          mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0 ||
305*62c56f98SSadaf Ebrahimi          mbedtls_mpi_get_bit(&ctx->Q, 0) == 0)) {
306*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
307*62c56f98SSadaf Ebrahimi     }
308*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_RSA_NO_CRT */
309*62c56f98SSadaf Ebrahimi 
310*62c56f98SSadaf Ebrahimi     /*
311*62c56f98SSadaf Ebrahimi      * 2. Exponents must be positive
312*62c56f98SSadaf Ebrahimi      */
313*62c56f98SSadaf Ebrahimi 
314*62c56f98SSadaf Ebrahimi     /* Always need E for public key operations */
315*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_cmp_int(&ctx->E, 0) <= 0) {
316*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
317*62c56f98SSadaf Ebrahimi     }
318*62c56f98SSadaf Ebrahimi 
319*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_NO_CRT)
320*62c56f98SSadaf Ebrahimi     /* For private key operations, use D or DP & DQ
321*62c56f98SSadaf Ebrahimi      * as (unblinded) exponents. */
322*62c56f98SSadaf Ebrahimi     if (is_priv && mbedtls_mpi_cmp_int(&ctx->D, 0) <= 0) {
323*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
324*62c56f98SSadaf Ebrahimi     }
325*62c56f98SSadaf Ebrahimi #else
326*62c56f98SSadaf Ebrahimi     if (is_priv &&
327*62c56f98SSadaf Ebrahimi         (mbedtls_mpi_cmp_int(&ctx->DP, 0) <= 0 ||
328*62c56f98SSadaf Ebrahimi          mbedtls_mpi_cmp_int(&ctx->DQ, 0) <= 0)) {
329*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
330*62c56f98SSadaf Ebrahimi     }
331*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_NO_CRT */
332*62c56f98SSadaf Ebrahimi 
333*62c56f98SSadaf Ebrahimi     /* Blinding shouldn't make exponents negative either,
334*62c56f98SSadaf Ebrahimi      * so check that P, Q >= 1 if that hasn't yet been
335*62c56f98SSadaf Ebrahimi      * done as part of 1. */
336*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_NO_CRT)
337*62c56f98SSadaf Ebrahimi     if (is_priv && blinding_needed &&
338*62c56f98SSadaf Ebrahimi         (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 ||
339*62c56f98SSadaf Ebrahimi          mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0)) {
340*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
341*62c56f98SSadaf Ebrahimi     }
342*62c56f98SSadaf Ebrahimi #endif
343*62c56f98SSadaf Ebrahimi 
344*62c56f98SSadaf Ebrahimi     /* It wouldn't lead to an error if it wasn't satisfied,
345*62c56f98SSadaf Ebrahimi      * but check for QP >= 1 nonetheless. */
346*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
347*62c56f98SSadaf Ebrahimi     if (is_priv &&
348*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->QP, 0) <= 0) {
349*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
350*62c56f98SSadaf Ebrahimi     }
351*62c56f98SSadaf Ebrahimi #endif
352*62c56f98SSadaf Ebrahimi 
353*62c56f98SSadaf Ebrahimi     return 0;
354*62c56f98SSadaf Ebrahimi }
355*62c56f98SSadaf Ebrahimi 
mbedtls_rsa_complete(mbedtls_rsa_context * ctx)356*62c56f98SSadaf Ebrahimi int mbedtls_rsa_complete(mbedtls_rsa_context *ctx)
357*62c56f98SSadaf Ebrahimi {
358*62c56f98SSadaf Ebrahimi     int ret = 0;
359*62c56f98SSadaf Ebrahimi     int have_N, have_P, have_Q, have_D, have_E;
360*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
361*62c56f98SSadaf Ebrahimi     int have_DP, have_DQ, have_QP;
362*62c56f98SSadaf Ebrahimi #endif
363*62c56f98SSadaf Ebrahimi     int n_missing, pq_missing, d_missing, is_pub, is_priv;
364*62c56f98SSadaf Ebrahimi 
365*62c56f98SSadaf Ebrahimi     have_N = (mbedtls_mpi_cmp_int(&ctx->N, 0) != 0);
366*62c56f98SSadaf Ebrahimi     have_P = (mbedtls_mpi_cmp_int(&ctx->P, 0) != 0);
367*62c56f98SSadaf Ebrahimi     have_Q = (mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0);
368*62c56f98SSadaf Ebrahimi     have_D = (mbedtls_mpi_cmp_int(&ctx->D, 0) != 0);
369*62c56f98SSadaf Ebrahimi     have_E = (mbedtls_mpi_cmp_int(&ctx->E, 0) != 0);
370*62c56f98SSadaf Ebrahimi 
371*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
372*62c56f98SSadaf Ebrahimi     have_DP = (mbedtls_mpi_cmp_int(&ctx->DP, 0) != 0);
373*62c56f98SSadaf Ebrahimi     have_DQ = (mbedtls_mpi_cmp_int(&ctx->DQ, 0) != 0);
374*62c56f98SSadaf Ebrahimi     have_QP = (mbedtls_mpi_cmp_int(&ctx->QP, 0) != 0);
375*62c56f98SSadaf Ebrahimi #endif
376*62c56f98SSadaf Ebrahimi 
377*62c56f98SSadaf Ebrahimi     /*
378*62c56f98SSadaf Ebrahimi      * Check whether provided parameters are enough
379*62c56f98SSadaf Ebrahimi      * to deduce all others. The following incomplete
380*62c56f98SSadaf Ebrahimi      * parameter sets for private keys are supported:
381*62c56f98SSadaf Ebrahimi      *
382*62c56f98SSadaf Ebrahimi      * (1) P, Q missing.
383*62c56f98SSadaf Ebrahimi      * (2) D and potentially N missing.
384*62c56f98SSadaf Ebrahimi      *
385*62c56f98SSadaf Ebrahimi      */
386*62c56f98SSadaf Ebrahimi 
387*62c56f98SSadaf Ebrahimi     n_missing  =              have_P &&  have_Q &&  have_D && have_E;
388*62c56f98SSadaf Ebrahimi     pq_missing =   have_N && !have_P && !have_Q &&  have_D && have_E;
389*62c56f98SSadaf Ebrahimi     d_missing  =              have_P &&  have_Q && !have_D && have_E;
390*62c56f98SSadaf Ebrahimi     is_pub     =   have_N && !have_P && !have_Q && !have_D && have_E;
391*62c56f98SSadaf Ebrahimi 
392*62c56f98SSadaf Ebrahimi     /* These three alternatives are mutually exclusive */
393*62c56f98SSadaf Ebrahimi     is_priv = n_missing || pq_missing || d_missing;
394*62c56f98SSadaf Ebrahimi 
395*62c56f98SSadaf Ebrahimi     if (!is_priv && !is_pub) {
396*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
397*62c56f98SSadaf Ebrahimi     }
398*62c56f98SSadaf Ebrahimi 
399*62c56f98SSadaf Ebrahimi     /*
400*62c56f98SSadaf Ebrahimi      * Step 1: Deduce N if P, Q are provided.
401*62c56f98SSadaf Ebrahimi      */
402*62c56f98SSadaf Ebrahimi 
403*62c56f98SSadaf Ebrahimi     if (!have_N && have_P && have_Q) {
404*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P,
405*62c56f98SSadaf Ebrahimi                                        &ctx->Q)) != 0) {
406*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
407*62c56f98SSadaf Ebrahimi         }
408*62c56f98SSadaf Ebrahimi 
409*62c56f98SSadaf Ebrahimi         ctx->len = mbedtls_mpi_size(&ctx->N);
410*62c56f98SSadaf Ebrahimi     }
411*62c56f98SSadaf Ebrahimi 
412*62c56f98SSadaf Ebrahimi     /*
413*62c56f98SSadaf Ebrahimi      * Step 2: Deduce and verify all remaining core parameters.
414*62c56f98SSadaf Ebrahimi      */
415*62c56f98SSadaf Ebrahimi 
416*62c56f98SSadaf Ebrahimi     if (pq_missing) {
417*62c56f98SSadaf Ebrahimi         ret = mbedtls_rsa_deduce_primes(&ctx->N, &ctx->E, &ctx->D,
418*62c56f98SSadaf Ebrahimi                                         &ctx->P, &ctx->Q);
419*62c56f98SSadaf Ebrahimi         if (ret != 0) {
420*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
421*62c56f98SSadaf Ebrahimi         }
422*62c56f98SSadaf Ebrahimi 
423*62c56f98SSadaf Ebrahimi     } else if (d_missing) {
424*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_rsa_deduce_private_exponent(&ctx->P,
425*62c56f98SSadaf Ebrahimi                                                        &ctx->Q,
426*62c56f98SSadaf Ebrahimi                                                        &ctx->E,
427*62c56f98SSadaf Ebrahimi                                                        &ctx->D)) != 0) {
428*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
429*62c56f98SSadaf Ebrahimi         }
430*62c56f98SSadaf Ebrahimi     }
431*62c56f98SSadaf Ebrahimi 
432*62c56f98SSadaf Ebrahimi     /*
433*62c56f98SSadaf Ebrahimi      * Step 3: Deduce all additional parameters specific
434*62c56f98SSadaf Ebrahimi      *         to our current RSA implementation.
435*62c56f98SSadaf Ebrahimi      */
436*62c56f98SSadaf Ebrahimi 
437*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
438*62c56f98SSadaf Ebrahimi     if (is_priv && !(have_DP && have_DQ && have_QP)) {
439*62c56f98SSadaf Ebrahimi         ret = mbedtls_rsa_deduce_crt(&ctx->P,  &ctx->Q,  &ctx->D,
440*62c56f98SSadaf Ebrahimi                                      &ctx->DP, &ctx->DQ, &ctx->QP);
441*62c56f98SSadaf Ebrahimi         if (ret != 0) {
442*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
443*62c56f98SSadaf Ebrahimi         }
444*62c56f98SSadaf Ebrahimi     }
445*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_NO_CRT */
446*62c56f98SSadaf Ebrahimi 
447*62c56f98SSadaf Ebrahimi     /*
448*62c56f98SSadaf Ebrahimi      * Step 3: Basic sanity checks
449*62c56f98SSadaf Ebrahimi      */
450*62c56f98SSadaf Ebrahimi 
451*62c56f98SSadaf Ebrahimi     return rsa_check_context(ctx, is_priv, 1);
452*62c56f98SSadaf Ebrahimi }
453*62c56f98SSadaf Ebrahimi 
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)454*62c56f98SSadaf Ebrahimi int mbedtls_rsa_export_raw(const mbedtls_rsa_context *ctx,
455*62c56f98SSadaf Ebrahimi                            unsigned char *N, size_t N_len,
456*62c56f98SSadaf Ebrahimi                            unsigned char *P, size_t P_len,
457*62c56f98SSadaf Ebrahimi                            unsigned char *Q, size_t Q_len,
458*62c56f98SSadaf Ebrahimi                            unsigned char *D, size_t D_len,
459*62c56f98SSadaf Ebrahimi                            unsigned char *E, size_t E_len)
460*62c56f98SSadaf Ebrahimi {
461*62c56f98SSadaf Ebrahimi     int ret = 0;
462*62c56f98SSadaf Ebrahimi     int is_priv;
463*62c56f98SSadaf Ebrahimi 
464*62c56f98SSadaf Ebrahimi     /* Check if key is private or public */
465*62c56f98SSadaf Ebrahimi     is_priv =
466*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 &&
467*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 &&
468*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 &&
469*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 &&
470*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->E, 0) != 0;
471*62c56f98SSadaf Ebrahimi 
472*62c56f98SSadaf Ebrahimi     if (!is_priv) {
473*62c56f98SSadaf Ebrahimi         /* If we're trying to export private parameters for a public key,
474*62c56f98SSadaf Ebrahimi          * something must be wrong. */
475*62c56f98SSadaf Ebrahimi         if (P != NULL || Q != NULL || D != NULL) {
476*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
477*62c56f98SSadaf Ebrahimi         }
478*62c56f98SSadaf Ebrahimi 
479*62c56f98SSadaf Ebrahimi     }
480*62c56f98SSadaf Ebrahimi 
481*62c56f98SSadaf Ebrahimi     if (N != NULL) {
482*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->N, N, N_len));
483*62c56f98SSadaf Ebrahimi     }
484*62c56f98SSadaf Ebrahimi 
485*62c56f98SSadaf Ebrahimi     if (P != NULL) {
486*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->P, P, P_len));
487*62c56f98SSadaf Ebrahimi     }
488*62c56f98SSadaf Ebrahimi 
489*62c56f98SSadaf Ebrahimi     if (Q != NULL) {
490*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->Q, Q, Q_len));
491*62c56f98SSadaf Ebrahimi     }
492*62c56f98SSadaf Ebrahimi 
493*62c56f98SSadaf Ebrahimi     if (D != NULL) {
494*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->D, D, D_len));
495*62c56f98SSadaf Ebrahimi     }
496*62c56f98SSadaf Ebrahimi 
497*62c56f98SSadaf Ebrahimi     if (E != NULL) {
498*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->E, E, E_len));
499*62c56f98SSadaf Ebrahimi     }
500*62c56f98SSadaf Ebrahimi 
501*62c56f98SSadaf Ebrahimi cleanup:
502*62c56f98SSadaf Ebrahimi 
503*62c56f98SSadaf Ebrahimi     return ret;
504*62c56f98SSadaf Ebrahimi }
505*62c56f98SSadaf Ebrahimi 
mbedtls_rsa_export(const mbedtls_rsa_context * ctx,mbedtls_mpi * N,mbedtls_mpi * P,mbedtls_mpi * Q,mbedtls_mpi * D,mbedtls_mpi * E)506*62c56f98SSadaf Ebrahimi int mbedtls_rsa_export(const mbedtls_rsa_context *ctx,
507*62c56f98SSadaf Ebrahimi                        mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
508*62c56f98SSadaf Ebrahimi                        mbedtls_mpi *D, mbedtls_mpi *E)
509*62c56f98SSadaf Ebrahimi {
510*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
511*62c56f98SSadaf Ebrahimi     int is_priv;
512*62c56f98SSadaf Ebrahimi 
513*62c56f98SSadaf Ebrahimi     /* Check if key is private or public */
514*62c56f98SSadaf Ebrahimi     is_priv =
515*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 &&
516*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 &&
517*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 &&
518*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 &&
519*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->E, 0) != 0;
520*62c56f98SSadaf Ebrahimi 
521*62c56f98SSadaf Ebrahimi     if (!is_priv) {
522*62c56f98SSadaf Ebrahimi         /* If we're trying to export private parameters for a public key,
523*62c56f98SSadaf Ebrahimi          * something must be wrong. */
524*62c56f98SSadaf Ebrahimi         if (P != NULL || Q != NULL || D != NULL) {
525*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
526*62c56f98SSadaf Ebrahimi         }
527*62c56f98SSadaf Ebrahimi 
528*62c56f98SSadaf Ebrahimi     }
529*62c56f98SSadaf Ebrahimi 
530*62c56f98SSadaf Ebrahimi     /* Export all requested core parameters. */
531*62c56f98SSadaf Ebrahimi 
532*62c56f98SSadaf Ebrahimi     if ((N != NULL && (ret = mbedtls_mpi_copy(N, &ctx->N)) != 0) ||
533*62c56f98SSadaf Ebrahimi         (P != NULL && (ret = mbedtls_mpi_copy(P, &ctx->P)) != 0) ||
534*62c56f98SSadaf Ebrahimi         (Q != NULL && (ret = mbedtls_mpi_copy(Q, &ctx->Q)) != 0) ||
535*62c56f98SSadaf Ebrahimi         (D != NULL && (ret = mbedtls_mpi_copy(D, &ctx->D)) != 0) ||
536*62c56f98SSadaf Ebrahimi         (E != NULL && (ret = mbedtls_mpi_copy(E, &ctx->E)) != 0)) {
537*62c56f98SSadaf Ebrahimi         return ret;
538*62c56f98SSadaf Ebrahimi     }
539*62c56f98SSadaf Ebrahimi 
540*62c56f98SSadaf Ebrahimi     return 0;
541*62c56f98SSadaf Ebrahimi }
542*62c56f98SSadaf Ebrahimi 
543*62c56f98SSadaf Ebrahimi /*
544*62c56f98SSadaf Ebrahimi  * Export CRT parameters
545*62c56f98SSadaf Ebrahimi  * This must also be implemented if CRT is not used, for being able to
546*62c56f98SSadaf Ebrahimi  * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
547*62c56f98SSadaf Ebrahimi  * can be used in this case.
548*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_export_crt(const mbedtls_rsa_context * ctx,mbedtls_mpi * DP,mbedtls_mpi * DQ,mbedtls_mpi * QP)549*62c56f98SSadaf Ebrahimi int mbedtls_rsa_export_crt(const mbedtls_rsa_context *ctx,
550*62c56f98SSadaf Ebrahimi                            mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP)
551*62c56f98SSadaf Ebrahimi {
552*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
553*62c56f98SSadaf Ebrahimi     int is_priv;
554*62c56f98SSadaf Ebrahimi 
555*62c56f98SSadaf Ebrahimi     /* Check if key is private or public */
556*62c56f98SSadaf Ebrahimi     is_priv =
557*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 &&
558*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 &&
559*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 &&
560*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 &&
561*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_int(&ctx->E, 0) != 0;
562*62c56f98SSadaf Ebrahimi 
563*62c56f98SSadaf Ebrahimi     if (!is_priv) {
564*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
565*62c56f98SSadaf Ebrahimi     }
566*62c56f98SSadaf Ebrahimi 
567*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
568*62c56f98SSadaf Ebrahimi     /* Export all requested blinding parameters. */
569*62c56f98SSadaf Ebrahimi     if ((DP != NULL && (ret = mbedtls_mpi_copy(DP, &ctx->DP)) != 0) ||
570*62c56f98SSadaf Ebrahimi         (DQ != NULL && (ret = mbedtls_mpi_copy(DQ, &ctx->DQ)) != 0) ||
571*62c56f98SSadaf Ebrahimi         (QP != NULL && (ret = mbedtls_mpi_copy(QP, &ctx->QP)) != 0)) {
572*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
573*62c56f98SSadaf Ebrahimi     }
574*62c56f98SSadaf Ebrahimi #else
575*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
576*62c56f98SSadaf Ebrahimi                                       DP, DQ, QP)) != 0) {
577*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
578*62c56f98SSadaf Ebrahimi     }
579*62c56f98SSadaf Ebrahimi #endif
580*62c56f98SSadaf Ebrahimi 
581*62c56f98SSadaf Ebrahimi     return 0;
582*62c56f98SSadaf Ebrahimi }
583*62c56f98SSadaf Ebrahimi 
584*62c56f98SSadaf Ebrahimi /*
585*62c56f98SSadaf Ebrahimi  * Initialize an RSA context
586*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_init(mbedtls_rsa_context * ctx)587*62c56f98SSadaf Ebrahimi void mbedtls_rsa_init(mbedtls_rsa_context *ctx)
588*62c56f98SSadaf Ebrahimi {
589*62c56f98SSadaf Ebrahimi     memset(ctx, 0, sizeof(mbedtls_rsa_context));
590*62c56f98SSadaf Ebrahimi 
591*62c56f98SSadaf Ebrahimi     ctx->padding = MBEDTLS_RSA_PKCS_V15;
592*62c56f98SSadaf Ebrahimi     ctx->hash_id = MBEDTLS_MD_NONE;
593*62c56f98SSadaf Ebrahimi 
594*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
595*62c56f98SSadaf Ebrahimi     /* Set ctx->ver to nonzero to indicate that the mutex has been
596*62c56f98SSadaf Ebrahimi      * initialized and will need to be freed. */
597*62c56f98SSadaf Ebrahimi     ctx->ver = 1;
598*62c56f98SSadaf Ebrahimi     mbedtls_mutex_init(&ctx->mutex);
599*62c56f98SSadaf Ebrahimi #endif
600*62c56f98SSadaf Ebrahimi }
601*62c56f98SSadaf Ebrahimi 
602*62c56f98SSadaf Ebrahimi /*
603*62c56f98SSadaf Ebrahimi  * Set padding for an existing RSA context
604*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_set_padding(mbedtls_rsa_context * ctx,int padding,mbedtls_md_type_t hash_id)605*62c56f98SSadaf Ebrahimi int mbedtls_rsa_set_padding(mbedtls_rsa_context *ctx, int padding,
606*62c56f98SSadaf Ebrahimi                             mbedtls_md_type_t hash_id)
607*62c56f98SSadaf Ebrahimi {
608*62c56f98SSadaf Ebrahimi     switch (padding) {
609*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
610*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V15:
611*62c56f98SSadaf Ebrahimi             break;
612*62c56f98SSadaf Ebrahimi #endif
613*62c56f98SSadaf Ebrahimi 
614*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
615*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V21:
616*62c56f98SSadaf Ebrahimi             break;
617*62c56f98SSadaf Ebrahimi #endif
618*62c56f98SSadaf Ebrahimi         default:
619*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_INVALID_PADDING;
620*62c56f98SSadaf Ebrahimi     }
621*62c56f98SSadaf Ebrahimi 
622*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
623*62c56f98SSadaf Ebrahimi     if ((padding == MBEDTLS_RSA_PKCS_V21) &&
624*62c56f98SSadaf Ebrahimi         (hash_id != MBEDTLS_MD_NONE)) {
625*62c56f98SSadaf Ebrahimi         /* Just make sure this hash is supported in this build. */
626*62c56f98SSadaf Ebrahimi         if (mbedtls_md_info_from_type(hash_id) == NULL) {
627*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_INVALID_PADDING;
628*62c56f98SSadaf Ebrahimi         }
629*62c56f98SSadaf Ebrahimi     }
630*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V21 */
631*62c56f98SSadaf Ebrahimi 
632*62c56f98SSadaf Ebrahimi     ctx->padding = padding;
633*62c56f98SSadaf Ebrahimi     ctx->hash_id = hash_id;
634*62c56f98SSadaf Ebrahimi 
635*62c56f98SSadaf Ebrahimi     return 0;
636*62c56f98SSadaf Ebrahimi }
637*62c56f98SSadaf Ebrahimi 
638*62c56f98SSadaf Ebrahimi /*
639*62c56f98SSadaf Ebrahimi  * Get padding mode of initialized RSA context
640*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_get_padding_mode(const mbedtls_rsa_context * ctx)641*62c56f98SSadaf Ebrahimi int mbedtls_rsa_get_padding_mode(const mbedtls_rsa_context *ctx)
642*62c56f98SSadaf Ebrahimi {
643*62c56f98SSadaf Ebrahimi     return ctx->padding;
644*62c56f98SSadaf Ebrahimi }
645*62c56f98SSadaf Ebrahimi 
646*62c56f98SSadaf Ebrahimi /*
647*62c56f98SSadaf Ebrahimi  * Get hash identifier of mbedtls_md_type_t type
648*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_get_md_alg(const mbedtls_rsa_context * ctx)649*62c56f98SSadaf Ebrahimi int mbedtls_rsa_get_md_alg(const mbedtls_rsa_context *ctx)
650*62c56f98SSadaf Ebrahimi {
651*62c56f98SSadaf Ebrahimi     return ctx->hash_id;
652*62c56f98SSadaf Ebrahimi }
653*62c56f98SSadaf Ebrahimi 
654*62c56f98SSadaf Ebrahimi /*
655*62c56f98SSadaf Ebrahimi  * Get length in bytes of RSA modulus
656*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_get_len(const mbedtls_rsa_context * ctx)657*62c56f98SSadaf Ebrahimi size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx)
658*62c56f98SSadaf Ebrahimi {
659*62c56f98SSadaf Ebrahimi     return ctx->len;
660*62c56f98SSadaf Ebrahimi }
661*62c56f98SSadaf Ebrahimi 
662*62c56f98SSadaf Ebrahimi 
663*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_GENPRIME)
664*62c56f98SSadaf Ebrahimi 
665*62c56f98SSadaf Ebrahimi /*
666*62c56f98SSadaf Ebrahimi  * Generate an RSA keypair
667*62c56f98SSadaf Ebrahimi  *
668*62c56f98SSadaf Ebrahimi  * This generation method follows the RSA key pair generation procedure of
669*62c56f98SSadaf Ebrahimi  * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
670*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_gen_key(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,unsigned int nbits,int exponent)671*62c56f98SSadaf Ebrahimi int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
672*62c56f98SSadaf Ebrahimi                         int (*f_rng)(void *, unsigned char *, size_t),
673*62c56f98SSadaf Ebrahimi                         void *p_rng,
674*62c56f98SSadaf Ebrahimi                         unsigned int nbits, int exponent)
675*62c56f98SSadaf Ebrahimi {
676*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
677*62c56f98SSadaf Ebrahimi     mbedtls_mpi H, G, L;
678*62c56f98SSadaf Ebrahimi     int prime_quality = 0;
679*62c56f98SSadaf Ebrahimi 
680*62c56f98SSadaf Ebrahimi     /*
681*62c56f98SSadaf Ebrahimi      * If the modulus is 1024 bit long or shorter, then the security strength of
682*62c56f98SSadaf Ebrahimi      * the RSA algorithm is less than or equal to 80 bits and therefore an error
683*62c56f98SSadaf Ebrahimi      * rate of 2^-80 is sufficient.
684*62c56f98SSadaf Ebrahimi      */
685*62c56f98SSadaf Ebrahimi     if (nbits > 1024) {
686*62c56f98SSadaf Ebrahimi         prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR;
687*62c56f98SSadaf Ebrahimi     }
688*62c56f98SSadaf Ebrahimi 
689*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&H);
690*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&G);
691*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&L);
692*62c56f98SSadaf Ebrahimi 
693*62c56f98SSadaf Ebrahimi     if (exponent < 3 || nbits % 2 != 0) {
694*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
695*62c56f98SSadaf Ebrahimi         goto cleanup;
696*62c56f98SSadaf Ebrahimi     }
697*62c56f98SSadaf Ebrahimi 
698*62c56f98SSadaf Ebrahimi     if (nbits < MBEDTLS_RSA_GEN_KEY_MIN_BITS) {
699*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
700*62c56f98SSadaf Ebrahimi         goto cleanup;
701*62c56f98SSadaf Ebrahimi     }
702*62c56f98SSadaf Ebrahimi 
703*62c56f98SSadaf Ebrahimi     /*
704*62c56f98SSadaf Ebrahimi      * find primes P and Q with Q < P so that:
705*62c56f98SSadaf Ebrahimi      * 1.  |P-Q| > 2^( nbits / 2 - 100 )
706*62c56f98SSadaf Ebrahimi      * 2.  GCD( E, (P-1)*(Q-1) ) == 1
707*62c56f98SSadaf Ebrahimi      * 3.  E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
708*62c56f98SSadaf Ebrahimi      */
709*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->E, exponent));
710*62c56f98SSadaf Ebrahimi 
711*62c56f98SSadaf Ebrahimi     do {
712*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->P, nbits >> 1,
713*62c56f98SSadaf Ebrahimi                                               prime_quality, f_rng, p_rng));
714*62c56f98SSadaf Ebrahimi 
715*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->Q, nbits >> 1,
716*62c56f98SSadaf Ebrahimi                                               prime_quality, f_rng, p_rng));
717*62c56f98SSadaf Ebrahimi 
718*62c56f98SSadaf Ebrahimi         /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
719*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&H, &ctx->P, &ctx->Q));
720*62c56f98SSadaf Ebrahimi         if (mbedtls_mpi_bitlen(&H) <= ((nbits >= 200) ? ((nbits >> 1) - 99) : 0)) {
721*62c56f98SSadaf Ebrahimi             continue;
722*62c56f98SSadaf Ebrahimi         }
723*62c56f98SSadaf Ebrahimi 
724*62c56f98SSadaf Ebrahimi         /* not required by any standards, but some users rely on the fact that P > Q */
725*62c56f98SSadaf Ebrahimi         if (H.s < 0) {
726*62c56f98SSadaf Ebrahimi             mbedtls_mpi_swap(&ctx->P, &ctx->Q);
727*62c56f98SSadaf Ebrahimi         }
728*62c56f98SSadaf Ebrahimi 
729*62c56f98SSadaf Ebrahimi         /* Temporarily replace P,Q by P-1, Q-1 */
730*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->P, &ctx->P, 1));
731*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->Q, &ctx->Q, 1));
732*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&H, &ctx->P, &ctx->Q));
733*62c56f98SSadaf Ebrahimi 
734*62c56f98SSadaf Ebrahimi         /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
735*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->E, &H));
736*62c56f98SSadaf Ebrahimi         if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
737*62c56f98SSadaf Ebrahimi             continue;
738*62c56f98SSadaf Ebrahimi         }
739*62c56f98SSadaf Ebrahimi 
740*62c56f98SSadaf Ebrahimi         /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
741*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->P, &ctx->Q));
742*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&L, NULL, &H, &G));
743*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->D, &ctx->E, &L));
744*62c56f98SSadaf Ebrahimi 
745*62c56f98SSadaf Ebrahimi         if (mbedtls_mpi_bitlen(&ctx->D) <= ((nbits + 1) / 2)) {      // (FIPS 186-4 §B.3.1 criterion 3(a))
746*62c56f98SSadaf Ebrahimi             continue;
747*62c56f98SSadaf Ebrahimi         }
748*62c56f98SSadaf Ebrahimi 
749*62c56f98SSadaf Ebrahimi         break;
750*62c56f98SSadaf Ebrahimi     } while (1);
751*62c56f98SSadaf Ebrahimi 
752*62c56f98SSadaf Ebrahimi     /* Restore P,Q */
753*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->P,  &ctx->P, 1));
754*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->Q,  &ctx->Q, 1));
755*62c56f98SSadaf Ebrahimi 
756*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, &ctx->Q));
757*62c56f98SSadaf Ebrahimi 
758*62c56f98SSadaf Ebrahimi     ctx->len = mbedtls_mpi_size(&ctx->N);
759*62c56f98SSadaf Ebrahimi 
760*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
761*62c56f98SSadaf Ebrahimi     /*
762*62c56f98SSadaf Ebrahimi      * DP = D mod (P - 1)
763*62c56f98SSadaf Ebrahimi      * DQ = D mod (Q - 1)
764*62c56f98SSadaf Ebrahimi      * QP = Q^-1 mod P
765*62c56f98SSadaf Ebrahimi      */
766*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
767*62c56f98SSadaf Ebrahimi                                            &ctx->DP, &ctx->DQ, &ctx->QP));
768*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_NO_CRT */
769*62c56f98SSadaf Ebrahimi 
770*62c56f98SSadaf Ebrahimi     /* Double-check */
771*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_check_privkey(ctx));
772*62c56f98SSadaf Ebrahimi 
773*62c56f98SSadaf Ebrahimi cleanup:
774*62c56f98SSadaf Ebrahimi 
775*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&H);
776*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&G);
777*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&L);
778*62c56f98SSadaf Ebrahimi 
779*62c56f98SSadaf Ebrahimi     if (ret != 0) {
780*62c56f98SSadaf Ebrahimi         mbedtls_rsa_free(ctx);
781*62c56f98SSadaf Ebrahimi 
782*62c56f98SSadaf Ebrahimi         if ((-ret & ~0x7f) == 0) {
783*62c56f98SSadaf Ebrahimi             ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret);
784*62c56f98SSadaf Ebrahimi         }
785*62c56f98SSadaf Ebrahimi         return ret;
786*62c56f98SSadaf Ebrahimi     }
787*62c56f98SSadaf Ebrahimi 
788*62c56f98SSadaf Ebrahimi     return 0;
789*62c56f98SSadaf Ebrahimi }
790*62c56f98SSadaf Ebrahimi 
791*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_GENPRIME */
792*62c56f98SSadaf Ebrahimi 
793*62c56f98SSadaf Ebrahimi /*
794*62c56f98SSadaf Ebrahimi  * Check a public RSA key
795*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_check_pubkey(const mbedtls_rsa_context * ctx)796*62c56f98SSadaf Ebrahimi int mbedtls_rsa_check_pubkey(const mbedtls_rsa_context *ctx)
797*62c56f98SSadaf Ebrahimi {
798*62c56f98SSadaf Ebrahimi     if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */) != 0) {
799*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
800*62c56f98SSadaf Ebrahimi     }
801*62c56f98SSadaf Ebrahimi 
802*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_bitlen(&ctx->N) < 128) {
803*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
804*62c56f98SSadaf Ebrahimi     }
805*62c56f98SSadaf Ebrahimi 
806*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_get_bit(&ctx->E, 0) == 0 ||
807*62c56f98SSadaf Ebrahimi         mbedtls_mpi_bitlen(&ctx->E)     < 2  ||
808*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_mpi(&ctx->E, &ctx->N) >= 0) {
809*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
810*62c56f98SSadaf Ebrahimi     }
811*62c56f98SSadaf Ebrahimi 
812*62c56f98SSadaf Ebrahimi     return 0;
813*62c56f98SSadaf Ebrahimi }
814*62c56f98SSadaf Ebrahimi 
815*62c56f98SSadaf Ebrahimi /*
816*62c56f98SSadaf Ebrahimi  * Check for the consistency of all fields in an RSA private key context
817*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_check_privkey(const mbedtls_rsa_context * ctx)818*62c56f98SSadaf Ebrahimi int mbedtls_rsa_check_privkey(const mbedtls_rsa_context *ctx)
819*62c56f98SSadaf Ebrahimi {
820*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_check_pubkey(ctx) != 0 ||
821*62c56f98SSadaf Ebrahimi         rsa_check_context(ctx, 1 /* private */, 1 /* blinding */) != 0) {
822*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
823*62c56f98SSadaf Ebrahimi     }
824*62c56f98SSadaf Ebrahimi 
825*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_validate_params(&ctx->N, &ctx->P, &ctx->Q,
826*62c56f98SSadaf Ebrahimi                                     &ctx->D, &ctx->E, NULL, NULL) != 0) {
827*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
828*62c56f98SSadaf Ebrahimi     }
829*62c56f98SSadaf Ebrahimi 
830*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
831*62c56f98SSadaf Ebrahimi     else if (mbedtls_rsa_validate_crt(&ctx->P, &ctx->Q, &ctx->D,
832*62c56f98SSadaf Ebrahimi                                       &ctx->DP, &ctx->DQ, &ctx->QP) != 0) {
833*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
834*62c56f98SSadaf Ebrahimi     }
835*62c56f98SSadaf Ebrahimi #endif
836*62c56f98SSadaf Ebrahimi 
837*62c56f98SSadaf Ebrahimi     return 0;
838*62c56f98SSadaf Ebrahimi }
839*62c56f98SSadaf Ebrahimi 
840*62c56f98SSadaf Ebrahimi /*
841*62c56f98SSadaf Ebrahimi  * Check if contexts holding a public and private key match
842*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context * pub,const mbedtls_rsa_context * prv)843*62c56f98SSadaf Ebrahimi int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub,
844*62c56f98SSadaf Ebrahimi                                const mbedtls_rsa_context *prv)
845*62c56f98SSadaf Ebrahimi {
846*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_check_pubkey(pub)  != 0 ||
847*62c56f98SSadaf Ebrahimi         mbedtls_rsa_check_privkey(prv) != 0) {
848*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
849*62c56f98SSadaf Ebrahimi     }
850*62c56f98SSadaf Ebrahimi 
851*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_cmp_mpi(&pub->N, &prv->N) != 0 ||
852*62c56f98SSadaf Ebrahimi         mbedtls_mpi_cmp_mpi(&pub->E, &prv->E) != 0) {
853*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
854*62c56f98SSadaf Ebrahimi     }
855*62c56f98SSadaf Ebrahimi 
856*62c56f98SSadaf Ebrahimi     return 0;
857*62c56f98SSadaf Ebrahimi }
858*62c56f98SSadaf Ebrahimi 
859*62c56f98SSadaf Ebrahimi /*
860*62c56f98SSadaf Ebrahimi  * Do an RSA public key operation
861*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_public(mbedtls_rsa_context * ctx,const unsigned char * input,unsigned char * output)862*62c56f98SSadaf Ebrahimi int mbedtls_rsa_public(mbedtls_rsa_context *ctx,
863*62c56f98SSadaf Ebrahimi                        const unsigned char *input,
864*62c56f98SSadaf Ebrahimi                        unsigned char *output)
865*62c56f98SSadaf Ebrahimi {
866*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
867*62c56f98SSadaf Ebrahimi     size_t olen;
868*62c56f98SSadaf Ebrahimi     mbedtls_mpi T;
869*62c56f98SSadaf Ebrahimi 
870*62c56f98SSadaf Ebrahimi     if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */)) {
871*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
872*62c56f98SSadaf Ebrahimi     }
873*62c56f98SSadaf Ebrahimi 
874*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&T);
875*62c56f98SSadaf Ebrahimi 
876*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
877*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
878*62c56f98SSadaf Ebrahimi         return ret;
879*62c56f98SSadaf Ebrahimi     }
880*62c56f98SSadaf Ebrahimi #endif
881*62c56f98SSadaf Ebrahimi 
882*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len));
883*62c56f98SSadaf Ebrahimi 
884*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) {
885*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
886*62c56f98SSadaf Ebrahimi         goto cleanup;
887*62c56f98SSadaf Ebrahimi     }
888*62c56f98SSadaf Ebrahimi 
889*62c56f98SSadaf Ebrahimi     olen = ctx->len;
890*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
891*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
892*62c56f98SSadaf Ebrahimi 
893*62c56f98SSadaf Ebrahimi cleanup:
894*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
895*62c56f98SSadaf Ebrahimi     if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
896*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
897*62c56f98SSadaf Ebrahimi     }
898*62c56f98SSadaf Ebrahimi #endif
899*62c56f98SSadaf Ebrahimi 
900*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&T);
901*62c56f98SSadaf Ebrahimi 
902*62c56f98SSadaf Ebrahimi     if (ret != 0) {
903*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret);
904*62c56f98SSadaf Ebrahimi     }
905*62c56f98SSadaf Ebrahimi 
906*62c56f98SSadaf Ebrahimi     return 0;
907*62c56f98SSadaf Ebrahimi }
908*62c56f98SSadaf Ebrahimi 
909*62c56f98SSadaf Ebrahimi /*
910*62c56f98SSadaf Ebrahimi  * Generate or update blinding values, see section 10 of:
911*62c56f98SSadaf Ebrahimi  *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
912*62c56f98SSadaf Ebrahimi  *  DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
913*62c56f98SSadaf Ebrahimi  *  Berlin Heidelberg, 1996. p. 104-113.
914*62c56f98SSadaf Ebrahimi  */
rsa_prepare_blinding(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)915*62c56f98SSadaf Ebrahimi static int rsa_prepare_blinding(mbedtls_rsa_context *ctx,
916*62c56f98SSadaf Ebrahimi                                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
917*62c56f98SSadaf Ebrahimi {
918*62c56f98SSadaf Ebrahimi     int ret, count = 0;
919*62c56f98SSadaf Ebrahimi     mbedtls_mpi R;
920*62c56f98SSadaf Ebrahimi 
921*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&R);
922*62c56f98SSadaf Ebrahimi 
923*62c56f98SSadaf Ebrahimi     if (ctx->Vf.p != NULL) {
924*62c56f98SSadaf Ebrahimi         /* We already have blinding values, just update them by squaring */
925*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
926*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
927*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
928*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->N));
929*62c56f98SSadaf Ebrahimi 
930*62c56f98SSadaf Ebrahimi         goto cleanup;
931*62c56f98SSadaf Ebrahimi     }
932*62c56f98SSadaf Ebrahimi 
933*62c56f98SSadaf Ebrahimi     /* Unblinding value: Vf = random number, invertible mod N */
934*62c56f98SSadaf Ebrahimi     do {
935*62c56f98SSadaf Ebrahimi         if (count++ > 10) {
936*62c56f98SSadaf Ebrahimi             ret = MBEDTLS_ERR_RSA_RNG_FAILED;
937*62c56f98SSadaf Ebrahimi             goto cleanup;
938*62c56f98SSadaf Ebrahimi         }
939*62c56f98SSadaf Ebrahimi 
940*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->Vf, ctx->len - 1, f_rng, p_rng));
941*62c56f98SSadaf Ebrahimi 
942*62c56f98SSadaf Ebrahimi         /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
943*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, ctx->len - 1, f_rng, p_rng));
944*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vf, &R));
945*62c56f98SSadaf Ebrahimi         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
946*62c56f98SSadaf Ebrahimi 
947*62c56f98SSadaf Ebrahimi         /* At this point, Vi is invertible mod N if and only if both Vf and R
948*62c56f98SSadaf Ebrahimi          * are invertible mod N. If one of them isn't, we don't need to know
949*62c56f98SSadaf Ebrahimi          * which one, we just loop and choose new values for both of them.
950*62c56f98SSadaf Ebrahimi          * (Each iteration succeeds with overwhelming probability.) */
951*62c56f98SSadaf Ebrahimi         ret = mbedtls_mpi_inv_mod(&ctx->Vi, &ctx->Vi, &ctx->N);
952*62c56f98SSadaf Ebrahimi         if (ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
953*62c56f98SSadaf Ebrahimi             goto cleanup;
954*62c56f98SSadaf Ebrahimi         }
955*62c56f98SSadaf Ebrahimi 
956*62c56f98SSadaf Ebrahimi     } while (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
957*62c56f98SSadaf Ebrahimi 
958*62c56f98SSadaf Ebrahimi     /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
959*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &R));
960*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
961*62c56f98SSadaf Ebrahimi 
962*62c56f98SSadaf Ebrahimi     /* Blinding value: Vi = Vf^(-e) mod N
963*62c56f98SSadaf Ebrahimi      * (Vi already contains Vf^-1 at this point) */
964*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN));
965*62c56f98SSadaf Ebrahimi 
966*62c56f98SSadaf Ebrahimi 
967*62c56f98SSadaf Ebrahimi cleanup:
968*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&R);
969*62c56f98SSadaf Ebrahimi 
970*62c56f98SSadaf Ebrahimi     return ret;
971*62c56f98SSadaf Ebrahimi }
972*62c56f98SSadaf Ebrahimi 
973*62c56f98SSadaf Ebrahimi /*
974*62c56f98SSadaf Ebrahimi  * Unblind
975*62c56f98SSadaf Ebrahimi  * T = T * Vf mod N
976*62c56f98SSadaf Ebrahimi  */
rsa_unblind(mbedtls_mpi * T,mbedtls_mpi * Vf,const mbedtls_mpi * N)977*62c56f98SSadaf Ebrahimi static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N)
978*62c56f98SSadaf Ebrahimi {
979*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
980*62c56f98SSadaf Ebrahimi     const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
981*62c56f98SSadaf Ebrahimi     const size_t nlimbs = N->n;
982*62c56f98SSadaf Ebrahimi     const size_t tlimbs = mbedtls_mpi_core_montmul_working_limbs(nlimbs);
983*62c56f98SSadaf Ebrahimi     mbedtls_mpi RR, M_T;
984*62c56f98SSadaf Ebrahimi 
985*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&RR);
986*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&M_T);
987*62c56f98SSadaf Ebrahimi 
988*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
989*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&M_T, tlimbs));
990*62c56f98SSadaf Ebrahimi 
991*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs));
992*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs));
993*62c56f98SSadaf Ebrahimi 
994*62c56f98SSadaf Ebrahimi     /* T = T * Vf mod N
995*62c56f98SSadaf Ebrahimi      * Reminder: montmul(A, B, N) = A * B * R^-1 mod N
996*62c56f98SSadaf Ebrahimi      * Usually both operands are multiplied by R mod N beforehand (by calling
997*62c56f98SSadaf Ebrahimi      * `to_mont_rep()` on them), yielding a result that's also * R mod N (aka
998*62c56f98SSadaf Ebrahimi      * "in the Montgomery domain"). Here we only multiply one operand by R mod
999*62c56f98SSadaf Ebrahimi      * N, so the result is directly what we want - no need to call
1000*62c56f98SSadaf Ebrahimi      * `from_mont_rep()` on it. */
1001*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_to_mont_rep(T->p, T->p, N->p, nlimbs, mm, RR.p, M_T.p);
1002*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_montmul(T->p, T->p, Vf->p, nlimbs, N->p, nlimbs, mm, M_T.p);
1003*62c56f98SSadaf Ebrahimi 
1004*62c56f98SSadaf Ebrahimi cleanup:
1005*62c56f98SSadaf Ebrahimi 
1006*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&RR);
1007*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&M_T);
1008*62c56f98SSadaf Ebrahimi 
1009*62c56f98SSadaf Ebrahimi     return ret;
1010*62c56f98SSadaf Ebrahimi }
1011*62c56f98SSadaf Ebrahimi 
1012*62c56f98SSadaf Ebrahimi /*
1013*62c56f98SSadaf Ebrahimi  * Exponent blinding supposed to prevent side-channel attacks using multiple
1014*62c56f98SSadaf Ebrahimi  * traces of measurements to recover the RSA key. The more collisions are there,
1015*62c56f98SSadaf Ebrahimi  * the more bits of the key can be recovered. See [3].
1016*62c56f98SSadaf Ebrahimi  *
1017*62c56f98SSadaf Ebrahimi  * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
1018*62c56f98SSadaf Ebrahimi  * observations on average.
1019*62c56f98SSadaf Ebrahimi  *
1020*62c56f98SSadaf Ebrahimi  * For example with 28 byte blinding to achieve 2 collisions the adversary has
1021*62c56f98SSadaf Ebrahimi  * to make 2^112 observations on average.
1022*62c56f98SSadaf Ebrahimi  *
1023*62c56f98SSadaf Ebrahimi  * (With the currently (as of 2017 April) known best algorithms breaking 2048
1024*62c56f98SSadaf Ebrahimi  * bit RSA requires approximately as much time as trying out 2^112 random keys.
1025*62c56f98SSadaf Ebrahimi  * Thus in this sense with 28 byte blinding the security is not reduced by
1026*62c56f98SSadaf Ebrahimi  * side-channel attacks like the one in [3])
1027*62c56f98SSadaf Ebrahimi  *
1028*62c56f98SSadaf Ebrahimi  * This countermeasure does not help if the key recovery is possible with a
1029*62c56f98SSadaf Ebrahimi  * single trace.
1030*62c56f98SSadaf Ebrahimi  */
1031*62c56f98SSadaf Ebrahimi #define RSA_EXPONENT_BLINDING 28
1032*62c56f98SSadaf Ebrahimi 
1033*62c56f98SSadaf Ebrahimi /*
1034*62c56f98SSadaf Ebrahimi  * Do an RSA private key operation
1035*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_private(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,const unsigned char * input,unsigned char * output)1036*62c56f98SSadaf Ebrahimi int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
1037*62c56f98SSadaf Ebrahimi                         int (*f_rng)(void *, unsigned char *, size_t),
1038*62c56f98SSadaf Ebrahimi                         void *p_rng,
1039*62c56f98SSadaf Ebrahimi                         const unsigned char *input,
1040*62c56f98SSadaf Ebrahimi                         unsigned char *output)
1041*62c56f98SSadaf Ebrahimi {
1042*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1043*62c56f98SSadaf Ebrahimi     size_t olen;
1044*62c56f98SSadaf Ebrahimi 
1045*62c56f98SSadaf Ebrahimi     /* Temporary holding the result */
1046*62c56f98SSadaf Ebrahimi     mbedtls_mpi T;
1047*62c56f98SSadaf Ebrahimi 
1048*62c56f98SSadaf Ebrahimi     /* Temporaries holding P-1, Q-1 and the
1049*62c56f98SSadaf Ebrahimi      * exponent blinding factor, respectively. */
1050*62c56f98SSadaf Ebrahimi     mbedtls_mpi P1, Q1, R;
1051*62c56f98SSadaf Ebrahimi 
1052*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
1053*62c56f98SSadaf Ebrahimi     /* Temporaries holding the results mod p resp. mod q. */
1054*62c56f98SSadaf Ebrahimi     mbedtls_mpi TP, TQ;
1055*62c56f98SSadaf Ebrahimi 
1056*62c56f98SSadaf Ebrahimi     /* Temporaries holding the blinded exponents for
1057*62c56f98SSadaf Ebrahimi      * the mod p resp. mod q computation (if used). */
1058*62c56f98SSadaf Ebrahimi     mbedtls_mpi DP_blind, DQ_blind;
1059*62c56f98SSadaf Ebrahimi #else
1060*62c56f98SSadaf Ebrahimi     /* Temporary holding the blinded exponent (if used). */
1061*62c56f98SSadaf Ebrahimi     mbedtls_mpi D_blind;
1062*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_NO_CRT */
1063*62c56f98SSadaf Ebrahimi 
1064*62c56f98SSadaf Ebrahimi     /* Temporaries holding the initial input and the double
1065*62c56f98SSadaf Ebrahimi      * checked result; should be the same in the end. */
1066*62c56f98SSadaf Ebrahimi     mbedtls_mpi input_blinded, check_result_blinded;
1067*62c56f98SSadaf Ebrahimi 
1068*62c56f98SSadaf Ebrahimi     if (f_rng == NULL) {
1069*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1070*62c56f98SSadaf Ebrahimi     }
1071*62c56f98SSadaf Ebrahimi 
1072*62c56f98SSadaf Ebrahimi     if (rsa_check_context(ctx, 1 /* private key checks */,
1073*62c56f98SSadaf Ebrahimi                           1 /* blinding on        */) != 0) {
1074*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1075*62c56f98SSadaf Ebrahimi     }
1076*62c56f98SSadaf Ebrahimi 
1077*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
1078*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
1079*62c56f98SSadaf Ebrahimi         return ret;
1080*62c56f98SSadaf Ebrahimi     }
1081*62c56f98SSadaf Ebrahimi #endif
1082*62c56f98SSadaf Ebrahimi 
1083*62c56f98SSadaf Ebrahimi     /* MPI Initialization */
1084*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&T);
1085*62c56f98SSadaf Ebrahimi 
1086*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&P1);
1087*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&Q1);
1088*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&R);
1089*62c56f98SSadaf Ebrahimi 
1090*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_NO_CRT)
1091*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&D_blind);
1092*62c56f98SSadaf Ebrahimi #else
1093*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&DP_blind);
1094*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&DQ_blind);
1095*62c56f98SSadaf Ebrahimi #endif
1096*62c56f98SSadaf Ebrahimi 
1097*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
1098*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&TP); mbedtls_mpi_init(&TQ);
1099*62c56f98SSadaf Ebrahimi #endif
1100*62c56f98SSadaf Ebrahimi 
1101*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&input_blinded);
1102*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&check_result_blinded);
1103*62c56f98SSadaf Ebrahimi 
1104*62c56f98SSadaf Ebrahimi     /* End of MPI initialization */
1105*62c56f98SSadaf Ebrahimi 
1106*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len));
1107*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) {
1108*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1109*62c56f98SSadaf Ebrahimi         goto cleanup;
1110*62c56f98SSadaf Ebrahimi     }
1111*62c56f98SSadaf Ebrahimi 
1112*62c56f98SSadaf Ebrahimi     /*
1113*62c56f98SSadaf Ebrahimi      * Blinding
1114*62c56f98SSadaf Ebrahimi      * T = T * Vi mod N
1115*62c56f98SSadaf Ebrahimi      */
1116*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(rsa_prepare_blinding(ctx, f_rng, p_rng));
1117*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vi));
1118*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N));
1119*62c56f98SSadaf Ebrahimi 
1120*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&input_blinded, &T));
1121*62c56f98SSadaf Ebrahimi 
1122*62c56f98SSadaf Ebrahimi     /*
1123*62c56f98SSadaf Ebrahimi      * Exponent blinding
1124*62c56f98SSadaf Ebrahimi      */
1125*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&P1, &ctx->P, 1));
1126*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&Q1, &ctx->Q, 1));
1127*62c56f98SSadaf Ebrahimi 
1128*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_NO_CRT)
1129*62c56f98SSadaf Ebrahimi     /*
1130*62c56f98SSadaf Ebrahimi      * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1131*62c56f98SSadaf Ebrahimi      */
1132*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING,
1133*62c56f98SSadaf Ebrahimi                                             f_rng, p_rng));
1134*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &P1, &Q1));
1135*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &D_blind, &R));
1136*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&D_blind, &D_blind, &ctx->D));
1137*62c56f98SSadaf Ebrahimi #else
1138*62c56f98SSadaf Ebrahimi     /*
1139*62c56f98SSadaf Ebrahimi      * DP_blind = ( P - 1 ) * R + DP
1140*62c56f98SSadaf Ebrahimi      */
1141*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING,
1142*62c56f98SSadaf Ebrahimi                                             f_rng, p_rng));
1143*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DP_blind, &P1, &R));
1144*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DP_blind, &DP_blind,
1145*62c56f98SSadaf Ebrahimi                                         &ctx->DP));
1146*62c56f98SSadaf Ebrahimi 
1147*62c56f98SSadaf Ebrahimi     /*
1148*62c56f98SSadaf Ebrahimi      * DQ_blind = ( Q - 1 ) * R + DQ
1149*62c56f98SSadaf Ebrahimi      */
1150*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING,
1151*62c56f98SSadaf Ebrahimi                                             f_rng, p_rng));
1152*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DQ_blind, &Q1, &R));
1153*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DQ_blind, &DQ_blind,
1154*62c56f98SSadaf Ebrahimi                                         &ctx->DQ));
1155*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_NO_CRT */
1156*62c56f98SSadaf Ebrahimi 
1157*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_NO_CRT)
1158*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &D_blind, &ctx->N, &ctx->RN));
1159*62c56f98SSadaf Ebrahimi #else
1160*62c56f98SSadaf Ebrahimi     /*
1161*62c56f98SSadaf Ebrahimi      * Faster decryption using the CRT
1162*62c56f98SSadaf Ebrahimi      *
1163*62c56f98SSadaf Ebrahimi      * TP = input ^ dP mod P
1164*62c56f98SSadaf Ebrahimi      * TQ = input ^ dQ mod Q
1165*62c56f98SSadaf Ebrahimi      */
1166*62c56f98SSadaf Ebrahimi 
1167*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, &DP_blind, &ctx->P, &ctx->RP));
1168*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, &DQ_blind, &ctx->Q, &ctx->RQ));
1169*62c56f98SSadaf Ebrahimi 
1170*62c56f98SSadaf Ebrahimi     /*
1171*62c56f98SSadaf Ebrahimi      * T = (TP - TQ) * (Q^-1 mod P) mod P
1172*62c56f98SSadaf Ebrahimi      */
1173*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&T, &TP, &TQ));
1174*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->QP));
1175*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &TP, &ctx->P));
1176*62c56f98SSadaf Ebrahimi 
1177*62c56f98SSadaf Ebrahimi     /*
1178*62c56f98SSadaf Ebrahimi      * T = TQ + T * Q
1179*62c56f98SSadaf Ebrahimi      */
1180*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->Q));
1181*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&T, &TQ, &TP));
1182*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_NO_CRT */
1183*62c56f98SSadaf Ebrahimi 
1184*62c56f98SSadaf Ebrahimi     /* Verify the result to prevent glitching attacks. */
1185*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&check_result_blinded, &T, &ctx->E,
1186*62c56f98SSadaf Ebrahimi                                         &ctx->N, &ctx->RN));
1187*62c56f98SSadaf Ebrahimi     if (mbedtls_mpi_cmp_mpi(&check_result_blinded, &input_blinded) != 0) {
1188*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
1189*62c56f98SSadaf Ebrahimi         goto cleanup;
1190*62c56f98SSadaf Ebrahimi     }
1191*62c56f98SSadaf Ebrahimi 
1192*62c56f98SSadaf Ebrahimi     /*
1193*62c56f98SSadaf Ebrahimi      * Unblind
1194*62c56f98SSadaf Ebrahimi      * T = T * Vf mod N
1195*62c56f98SSadaf Ebrahimi      */
1196*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N));
1197*62c56f98SSadaf Ebrahimi 
1198*62c56f98SSadaf Ebrahimi     olen = ctx->len;
1199*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
1200*62c56f98SSadaf Ebrahimi 
1201*62c56f98SSadaf Ebrahimi cleanup:
1202*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
1203*62c56f98SSadaf Ebrahimi     if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
1204*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
1205*62c56f98SSadaf Ebrahimi     }
1206*62c56f98SSadaf Ebrahimi #endif
1207*62c56f98SSadaf Ebrahimi 
1208*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&P1);
1209*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&Q1);
1210*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&R);
1211*62c56f98SSadaf Ebrahimi 
1212*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_NO_CRT)
1213*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&D_blind);
1214*62c56f98SSadaf Ebrahimi #else
1215*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&DP_blind);
1216*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&DQ_blind);
1217*62c56f98SSadaf Ebrahimi #endif
1218*62c56f98SSadaf Ebrahimi 
1219*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&T);
1220*62c56f98SSadaf Ebrahimi 
1221*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
1222*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&TP); mbedtls_mpi_free(&TQ);
1223*62c56f98SSadaf Ebrahimi #endif
1224*62c56f98SSadaf Ebrahimi 
1225*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&check_result_blinded);
1226*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&input_blinded);
1227*62c56f98SSadaf Ebrahimi 
1228*62c56f98SSadaf Ebrahimi     if (ret != 0 && ret >= -0x007f) {
1229*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret);
1230*62c56f98SSadaf Ebrahimi     }
1231*62c56f98SSadaf Ebrahimi 
1232*62c56f98SSadaf Ebrahimi     return ret;
1233*62c56f98SSadaf Ebrahimi }
1234*62c56f98SSadaf Ebrahimi 
1235*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
1236*62c56f98SSadaf Ebrahimi /**
1237*62c56f98SSadaf Ebrahimi  * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1238*62c56f98SSadaf Ebrahimi  *
1239*62c56f98SSadaf Ebrahimi  * \param dst       buffer to mask
1240*62c56f98SSadaf Ebrahimi  * \param dlen      length of destination buffer
1241*62c56f98SSadaf Ebrahimi  * \param src       source of the mask generation
1242*62c56f98SSadaf Ebrahimi  * \param slen      length of the source buffer
1243*62c56f98SSadaf Ebrahimi  * \param md_alg    message digest to use
1244*62c56f98SSadaf Ebrahimi  */
mgf_mask(unsigned char * dst,size_t dlen,unsigned char * src,size_t slen,mbedtls_md_type_t md_alg)1245*62c56f98SSadaf Ebrahimi static int mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src,
1246*62c56f98SSadaf Ebrahimi                     size_t slen, mbedtls_md_type_t md_alg)
1247*62c56f98SSadaf Ebrahimi {
1248*62c56f98SSadaf Ebrahimi     unsigned char counter[4];
1249*62c56f98SSadaf Ebrahimi     unsigned char *p;
1250*62c56f98SSadaf Ebrahimi     unsigned int hlen;
1251*62c56f98SSadaf Ebrahimi     size_t i, use_len;
1252*62c56f98SSadaf Ebrahimi     unsigned char mask[MBEDTLS_MD_MAX_SIZE];
1253*62c56f98SSadaf Ebrahimi     int ret = 0;
1254*62c56f98SSadaf Ebrahimi     const mbedtls_md_info_t *md_info;
1255*62c56f98SSadaf Ebrahimi     mbedtls_md_context_t md_ctx;
1256*62c56f98SSadaf Ebrahimi 
1257*62c56f98SSadaf Ebrahimi     mbedtls_md_init(&md_ctx);
1258*62c56f98SSadaf Ebrahimi     md_info = mbedtls_md_info_from_type(md_alg);
1259*62c56f98SSadaf Ebrahimi     if (md_info == NULL) {
1260*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1261*62c56f98SSadaf Ebrahimi     }
1262*62c56f98SSadaf Ebrahimi 
1263*62c56f98SSadaf Ebrahimi     mbedtls_md_init(&md_ctx);
1264*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
1265*62c56f98SSadaf Ebrahimi         goto exit;
1266*62c56f98SSadaf Ebrahimi     }
1267*62c56f98SSadaf Ebrahimi 
1268*62c56f98SSadaf Ebrahimi     hlen = mbedtls_md_get_size(md_info);
1269*62c56f98SSadaf Ebrahimi 
1270*62c56f98SSadaf Ebrahimi     memset(mask, 0, sizeof(mask));
1271*62c56f98SSadaf Ebrahimi     memset(counter, 0, 4);
1272*62c56f98SSadaf Ebrahimi 
1273*62c56f98SSadaf Ebrahimi     /* Generate and apply dbMask */
1274*62c56f98SSadaf Ebrahimi     p = dst;
1275*62c56f98SSadaf Ebrahimi 
1276*62c56f98SSadaf Ebrahimi     while (dlen > 0) {
1277*62c56f98SSadaf Ebrahimi         use_len = hlen;
1278*62c56f98SSadaf Ebrahimi         if (dlen < hlen) {
1279*62c56f98SSadaf Ebrahimi             use_len = dlen;
1280*62c56f98SSadaf Ebrahimi         }
1281*62c56f98SSadaf Ebrahimi 
1282*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
1283*62c56f98SSadaf Ebrahimi             goto exit;
1284*62c56f98SSadaf Ebrahimi         }
1285*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_md_update(&md_ctx, src, slen)) != 0) {
1286*62c56f98SSadaf Ebrahimi             goto exit;
1287*62c56f98SSadaf Ebrahimi         }
1288*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_md_update(&md_ctx, counter, 4)) != 0) {
1289*62c56f98SSadaf Ebrahimi             goto exit;
1290*62c56f98SSadaf Ebrahimi         }
1291*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_md_finish(&md_ctx, mask)) != 0) {
1292*62c56f98SSadaf Ebrahimi             goto exit;
1293*62c56f98SSadaf Ebrahimi         }
1294*62c56f98SSadaf Ebrahimi 
1295*62c56f98SSadaf Ebrahimi         for (i = 0; i < use_len; ++i) {
1296*62c56f98SSadaf Ebrahimi             *p++ ^= mask[i];
1297*62c56f98SSadaf Ebrahimi         }
1298*62c56f98SSadaf Ebrahimi 
1299*62c56f98SSadaf Ebrahimi         counter[3]++;
1300*62c56f98SSadaf Ebrahimi 
1301*62c56f98SSadaf Ebrahimi         dlen -= use_len;
1302*62c56f98SSadaf Ebrahimi     }
1303*62c56f98SSadaf Ebrahimi 
1304*62c56f98SSadaf Ebrahimi exit:
1305*62c56f98SSadaf Ebrahimi     mbedtls_platform_zeroize(mask, sizeof(mask));
1306*62c56f98SSadaf Ebrahimi     mbedtls_md_free(&md_ctx);
1307*62c56f98SSadaf Ebrahimi 
1308*62c56f98SSadaf Ebrahimi     return ret;
1309*62c56f98SSadaf Ebrahimi }
1310*62c56f98SSadaf Ebrahimi 
1311*62c56f98SSadaf Ebrahimi /**
1312*62c56f98SSadaf Ebrahimi  * Generate Hash(M') as in RFC 8017 page 43 points 5 and 6.
1313*62c56f98SSadaf Ebrahimi  *
1314*62c56f98SSadaf Ebrahimi  * \param hash      the input hash
1315*62c56f98SSadaf Ebrahimi  * \param hlen      length of the input hash
1316*62c56f98SSadaf Ebrahimi  * \param salt      the input salt
1317*62c56f98SSadaf Ebrahimi  * \param slen      length of the input salt
1318*62c56f98SSadaf Ebrahimi  * \param out       the output buffer - must be large enough for \p md_alg
1319*62c56f98SSadaf Ebrahimi  * \param md_alg    message digest to use
1320*62c56f98SSadaf Ebrahimi  */
hash_mprime(const unsigned char * hash,size_t hlen,const unsigned char * salt,size_t slen,unsigned char * out,mbedtls_md_type_t md_alg)1321*62c56f98SSadaf Ebrahimi static int hash_mprime(const unsigned char *hash, size_t hlen,
1322*62c56f98SSadaf Ebrahimi                        const unsigned char *salt, size_t slen,
1323*62c56f98SSadaf Ebrahimi                        unsigned char *out, mbedtls_md_type_t md_alg)
1324*62c56f98SSadaf Ebrahimi {
1325*62c56f98SSadaf Ebrahimi     const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1326*62c56f98SSadaf Ebrahimi 
1327*62c56f98SSadaf Ebrahimi     mbedtls_md_context_t md_ctx;
1328*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1329*62c56f98SSadaf Ebrahimi 
1330*62c56f98SSadaf Ebrahimi     const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg);
1331*62c56f98SSadaf Ebrahimi     if (md_info == NULL) {
1332*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1333*62c56f98SSadaf Ebrahimi     }
1334*62c56f98SSadaf Ebrahimi 
1335*62c56f98SSadaf Ebrahimi     mbedtls_md_init(&md_ctx);
1336*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
1337*62c56f98SSadaf Ebrahimi         goto exit;
1338*62c56f98SSadaf Ebrahimi     }
1339*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
1340*62c56f98SSadaf Ebrahimi         goto exit;
1341*62c56f98SSadaf Ebrahimi     }
1342*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_md_update(&md_ctx, zeros, sizeof(zeros))) != 0) {
1343*62c56f98SSadaf Ebrahimi         goto exit;
1344*62c56f98SSadaf Ebrahimi     }
1345*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_md_update(&md_ctx, hash, hlen)) != 0) {
1346*62c56f98SSadaf Ebrahimi         goto exit;
1347*62c56f98SSadaf Ebrahimi     }
1348*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_md_update(&md_ctx, salt, slen)) != 0) {
1349*62c56f98SSadaf Ebrahimi         goto exit;
1350*62c56f98SSadaf Ebrahimi     }
1351*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_md_finish(&md_ctx, out)) != 0) {
1352*62c56f98SSadaf Ebrahimi         goto exit;
1353*62c56f98SSadaf Ebrahimi     }
1354*62c56f98SSadaf Ebrahimi 
1355*62c56f98SSadaf Ebrahimi exit:
1356*62c56f98SSadaf Ebrahimi     mbedtls_md_free(&md_ctx);
1357*62c56f98SSadaf Ebrahimi 
1358*62c56f98SSadaf Ebrahimi     return ret;
1359*62c56f98SSadaf Ebrahimi }
1360*62c56f98SSadaf Ebrahimi 
1361*62c56f98SSadaf Ebrahimi /**
1362*62c56f98SSadaf Ebrahimi  * Compute a hash.
1363*62c56f98SSadaf Ebrahimi  *
1364*62c56f98SSadaf Ebrahimi  * \param md_alg    algorithm to use
1365*62c56f98SSadaf Ebrahimi  * \param input     input message to hash
1366*62c56f98SSadaf Ebrahimi  * \param ilen      input length
1367*62c56f98SSadaf Ebrahimi  * \param output    the output buffer - must be large enough for \p md_alg
1368*62c56f98SSadaf Ebrahimi  */
compute_hash(mbedtls_md_type_t md_alg,const unsigned char * input,size_t ilen,unsigned char * output)1369*62c56f98SSadaf Ebrahimi static int compute_hash(mbedtls_md_type_t md_alg,
1370*62c56f98SSadaf Ebrahimi                         const unsigned char *input, size_t ilen,
1371*62c56f98SSadaf Ebrahimi                         unsigned char *output)
1372*62c56f98SSadaf Ebrahimi {
1373*62c56f98SSadaf Ebrahimi     const mbedtls_md_info_t *md_info;
1374*62c56f98SSadaf Ebrahimi 
1375*62c56f98SSadaf Ebrahimi     md_info = mbedtls_md_info_from_type(md_alg);
1376*62c56f98SSadaf Ebrahimi     if (md_info == NULL) {
1377*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1378*62c56f98SSadaf Ebrahimi     }
1379*62c56f98SSadaf Ebrahimi 
1380*62c56f98SSadaf Ebrahimi     return mbedtls_md(md_info, input, ilen, output);
1381*62c56f98SSadaf Ebrahimi }
1382*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V21 */
1383*62c56f98SSadaf Ebrahimi 
1384*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
1385*62c56f98SSadaf Ebrahimi /*
1386*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1387*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,const unsigned char * label,size_t label_len,size_t ilen,const unsigned char * input,unsigned char * output)1388*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
1389*62c56f98SSadaf Ebrahimi                                    int (*f_rng)(void *, unsigned char *, size_t),
1390*62c56f98SSadaf Ebrahimi                                    void *p_rng,
1391*62c56f98SSadaf Ebrahimi                                    const unsigned char *label, size_t label_len,
1392*62c56f98SSadaf Ebrahimi                                    size_t ilen,
1393*62c56f98SSadaf Ebrahimi                                    const unsigned char *input,
1394*62c56f98SSadaf Ebrahimi                                    unsigned char *output)
1395*62c56f98SSadaf Ebrahimi {
1396*62c56f98SSadaf Ebrahimi     size_t olen;
1397*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1398*62c56f98SSadaf Ebrahimi     unsigned char *p = output;
1399*62c56f98SSadaf Ebrahimi     unsigned int hlen;
1400*62c56f98SSadaf Ebrahimi 
1401*62c56f98SSadaf Ebrahimi     if (f_rng == NULL) {
1402*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1403*62c56f98SSadaf Ebrahimi     }
1404*62c56f98SSadaf Ebrahimi 
1405*62c56f98SSadaf Ebrahimi     hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
1406*62c56f98SSadaf Ebrahimi     if (hlen == 0) {
1407*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1408*62c56f98SSadaf Ebrahimi     }
1409*62c56f98SSadaf Ebrahimi 
1410*62c56f98SSadaf Ebrahimi     olen = ctx->len;
1411*62c56f98SSadaf Ebrahimi 
1412*62c56f98SSadaf Ebrahimi     /* first comparison checks for overflow */
1413*62c56f98SSadaf Ebrahimi     if (ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2) {
1414*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1415*62c56f98SSadaf Ebrahimi     }
1416*62c56f98SSadaf Ebrahimi 
1417*62c56f98SSadaf Ebrahimi     memset(output, 0, olen);
1418*62c56f98SSadaf Ebrahimi 
1419*62c56f98SSadaf Ebrahimi     *p++ = 0;
1420*62c56f98SSadaf Ebrahimi 
1421*62c56f98SSadaf Ebrahimi     /* Generate a random octet string seed */
1422*62c56f98SSadaf Ebrahimi     if ((ret = f_rng(p_rng, p, hlen)) != 0) {
1423*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret);
1424*62c56f98SSadaf Ebrahimi     }
1425*62c56f98SSadaf Ebrahimi 
1426*62c56f98SSadaf Ebrahimi     p += hlen;
1427*62c56f98SSadaf Ebrahimi 
1428*62c56f98SSadaf Ebrahimi     /* Construct DB */
1429*62c56f98SSadaf Ebrahimi     ret = compute_hash((mbedtls_md_type_t) ctx->hash_id, label, label_len, p);
1430*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1431*62c56f98SSadaf Ebrahimi         return ret;
1432*62c56f98SSadaf Ebrahimi     }
1433*62c56f98SSadaf Ebrahimi     p += hlen;
1434*62c56f98SSadaf Ebrahimi     p += olen - 2 * hlen - 2 - ilen;
1435*62c56f98SSadaf Ebrahimi     *p++ = 1;
1436*62c56f98SSadaf Ebrahimi     if (ilen != 0) {
1437*62c56f98SSadaf Ebrahimi         memcpy(p, input, ilen);
1438*62c56f98SSadaf Ebrahimi     }
1439*62c56f98SSadaf Ebrahimi 
1440*62c56f98SSadaf Ebrahimi     /* maskedDB: Apply dbMask to DB */
1441*62c56f98SSadaf Ebrahimi     if ((ret = mgf_mask(output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1442*62c56f98SSadaf Ebrahimi                         (mbedtls_md_type_t) ctx->hash_id)) != 0) {
1443*62c56f98SSadaf Ebrahimi         return ret;
1444*62c56f98SSadaf Ebrahimi     }
1445*62c56f98SSadaf Ebrahimi 
1446*62c56f98SSadaf Ebrahimi     /* maskedSeed: Apply seedMask to seed */
1447*62c56f98SSadaf Ebrahimi     if ((ret = mgf_mask(output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1448*62c56f98SSadaf Ebrahimi                         (mbedtls_md_type_t) ctx->hash_id)) != 0) {
1449*62c56f98SSadaf Ebrahimi         return ret;
1450*62c56f98SSadaf Ebrahimi     }
1451*62c56f98SSadaf Ebrahimi 
1452*62c56f98SSadaf Ebrahimi     return mbedtls_rsa_public(ctx, output, output);
1453*62c56f98SSadaf Ebrahimi }
1454*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V21 */
1455*62c56f98SSadaf Ebrahimi 
1456*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
1457*62c56f98SSadaf Ebrahimi /*
1458*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1459*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,size_t ilen,const unsigned char * input,unsigned char * output)1460*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx,
1461*62c56f98SSadaf Ebrahimi                                         int (*f_rng)(void *, unsigned char *, size_t),
1462*62c56f98SSadaf Ebrahimi                                         void *p_rng, size_t ilen,
1463*62c56f98SSadaf Ebrahimi                                         const unsigned char *input,
1464*62c56f98SSadaf Ebrahimi                                         unsigned char *output)
1465*62c56f98SSadaf Ebrahimi {
1466*62c56f98SSadaf Ebrahimi     size_t nb_pad, olen;
1467*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1468*62c56f98SSadaf Ebrahimi     unsigned char *p = output;
1469*62c56f98SSadaf Ebrahimi 
1470*62c56f98SSadaf Ebrahimi     olen = ctx->len;
1471*62c56f98SSadaf Ebrahimi 
1472*62c56f98SSadaf Ebrahimi     /* first comparison checks for overflow */
1473*62c56f98SSadaf Ebrahimi     if (ilen + 11 < ilen || olen < ilen + 11) {
1474*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1475*62c56f98SSadaf Ebrahimi     }
1476*62c56f98SSadaf Ebrahimi 
1477*62c56f98SSadaf Ebrahimi     nb_pad = olen - 3 - ilen;
1478*62c56f98SSadaf Ebrahimi 
1479*62c56f98SSadaf Ebrahimi     *p++ = 0;
1480*62c56f98SSadaf Ebrahimi 
1481*62c56f98SSadaf Ebrahimi     if (f_rng == NULL) {
1482*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1483*62c56f98SSadaf Ebrahimi     }
1484*62c56f98SSadaf Ebrahimi 
1485*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_RSA_CRYPT;
1486*62c56f98SSadaf Ebrahimi 
1487*62c56f98SSadaf Ebrahimi     while (nb_pad-- > 0) {
1488*62c56f98SSadaf Ebrahimi         int rng_dl = 100;
1489*62c56f98SSadaf Ebrahimi 
1490*62c56f98SSadaf Ebrahimi         do {
1491*62c56f98SSadaf Ebrahimi             ret = f_rng(p_rng, p, 1);
1492*62c56f98SSadaf Ebrahimi         } while (*p == 0 && --rng_dl && ret == 0);
1493*62c56f98SSadaf Ebrahimi 
1494*62c56f98SSadaf Ebrahimi         /* Check if RNG failed to generate data */
1495*62c56f98SSadaf Ebrahimi         if (rng_dl == 0 || ret != 0) {
1496*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret);
1497*62c56f98SSadaf Ebrahimi         }
1498*62c56f98SSadaf Ebrahimi 
1499*62c56f98SSadaf Ebrahimi         p++;
1500*62c56f98SSadaf Ebrahimi     }
1501*62c56f98SSadaf Ebrahimi 
1502*62c56f98SSadaf Ebrahimi     *p++ = 0;
1503*62c56f98SSadaf Ebrahimi     if (ilen != 0) {
1504*62c56f98SSadaf Ebrahimi         memcpy(p, input, ilen);
1505*62c56f98SSadaf Ebrahimi     }
1506*62c56f98SSadaf Ebrahimi 
1507*62c56f98SSadaf Ebrahimi     return mbedtls_rsa_public(ctx, output, output);
1508*62c56f98SSadaf Ebrahimi }
1509*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V15 */
1510*62c56f98SSadaf Ebrahimi 
1511*62c56f98SSadaf Ebrahimi /*
1512*62c56f98SSadaf Ebrahimi  * Add the message padding, then do an RSA operation
1513*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,size_t ilen,const unsigned char * input,unsigned char * output)1514*62c56f98SSadaf Ebrahimi int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx,
1515*62c56f98SSadaf Ebrahimi                               int (*f_rng)(void *, unsigned char *, size_t),
1516*62c56f98SSadaf Ebrahimi                               void *p_rng,
1517*62c56f98SSadaf Ebrahimi                               size_t ilen,
1518*62c56f98SSadaf Ebrahimi                               const unsigned char *input,
1519*62c56f98SSadaf Ebrahimi                               unsigned char *output)
1520*62c56f98SSadaf Ebrahimi {
1521*62c56f98SSadaf Ebrahimi     switch (ctx->padding) {
1522*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
1523*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V15:
1524*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx, f_rng, p_rng,
1525*62c56f98SSadaf Ebrahimi                                                        ilen, input, output);
1526*62c56f98SSadaf Ebrahimi #endif
1527*62c56f98SSadaf Ebrahimi 
1528*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
1529*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V21:
1530*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsaes_oaep_encrypt(ctx, f_rng, p_rng, NULL, 0,
1531*62c56f98SSadaf Ebrahimi                                                   ilen, input, output);
1532*62c56f98SSadaf Ebrahimi #endif
1533*62c56f98SSadaf Ebrahimi 
1534*62c56f98SSadaf Ebrahimi         default:
1535*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_INVALID_PADDING;
1536*62c56f98SSadaf Ebrahimi     }
1537*62c56f98SSadaf Ebrahimi }
1538*62c56f98SSadaf Ebrahimi 
1539*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
1540*62c56f98SSadaf Ebrahimi /*
1541*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
1542*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,const unsigned char * label,size_t label_len,size_t * olen,const unsigned char * input,unsigned char * output,size_t output_max_len)1543*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
1544*62c56f98SSadaf Ebrahimi                                    int (*f_rng)(void *, unsigned char *, size_t),
1545*62c56f98SSadaf Ebrahimi                                    void *p_rng,
1546*62c56f98SSadaf Ebrahimi                                    const unsigned char *label, size_t label_len,
1547*62c56f98SSadaf Ebrahimi                                    size_t *olen,
1548*62c56f98SSadaf Ebrahimi                                    const unsigned char *input,
1549*62c56f98SSadaf Ebrahimi                                    unsigned char *output,
1550*62c56f98SSadaf Ebrahimi                                    size_t output_max_len)
1551*62c56f98SSadaf Ebrahimi {
1552*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1553*62c56f98SSadaf Ebrahimi     size_t ilen, i, pad_len;
1554*62c56f98SSadaf Ebrahimi     unsigned char *p;
1555*62c56f98SSadaf Ebrahimi     mbedtls_ct_condition_t bad, in_padding;
1556*62c56f98SSadaf Ebrahimi     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1557*62c56f98SSadaf Ebrahimi     unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
1558*62c56f98SSadaf Ebrahimi     unsigned int hlen;
1559*62c56f98SSadaf Ebrahimi 
1560*62c56f98SSadaf Ebrahimi     /*
1561*62c56f98SSadaf Ebrahimi      * Parameters sanity checks
1562*62c56f98SSadaf Ebrahimi      */
1563*62c56f98SSadaf Ebrahimi     if (ctx->padding != MBEDTLS_RSA_PKCS_V21) {
1564*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1565*62c56f98SSadaf Ebrahimi     }
1566*62c56f98SSadaf Ebrahimi 
1567*62c56f98SSadaf Ebrahimi     ilen = ctx->len;
1568*62c56f98SSadaf Ebrahimi 
1569*62c56f98SSadaf Ebrahimi     if (ilen < 16 || ilen > sizeof(buf)) {
1570*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1571*62c56f98SSadaf Ebrahimi     }
1572*62c56f98SSadaf Ebrahimi 
1573*62c56f98SSadaf Ebrahimi     hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
1574*62c56f98SSadaf Ebrahimi     if (hlen == 0) {
1575*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1576*62c56f98SSadaf Ebrahimi     }
1577*62c56f98SSadaf Ebrahimi 
1578*62c56f98SSadaf Ebrahimi     // checking for integer underflow
1579*62c56f98SSadaf Ebrahimi     if (2 * hlen + 2 > ilen) {
1580*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1581*62c56f98SSadaf Ebrahimi     }
1582*62c56f98SSadaf Ebrahimi 
1583*62c56f98SSadaf Ebrahimi     /*
1584*62c56f98SSadaf Ebrahimi      * RSA operation
1585*62c56f98SSadaf Ebrahimi      */
1586*62c56f98SSadaf Ebrahimi     ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf);
1587*62c56f98SSadaf Ebrahimi 
1588*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1589*62c56f98SSadaf Ebrahimi         goto cleanup;
1590*62c56f98SSadaf Ebrahimi     }
1591*62c56f98SSadaf Ebrahimi 
1592*62c56f98SSadaf Ebrahimi     /*
1593*62c56f98SSadaf Ebrahimi      * Unmask data and generate lHash
1594*62c56f98SSadaf Ebrahimi      */
1595*62c56f98SSadaf Ebrahimi     /* seed: Apply seedMask to maskedSeed */
1596*62c56f98SSadaf Ebrahimi     if ((ret = mgf_mask(buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1597*62c56f98SSadaf Ebrahimi                         (mbedtls_md_type_t) ctx->hash_id)) != 0 ||
1598*62c56f98SSadaf Ebrahimi         /* DB: Apply dbMask to maskedDB */
1599*62c56f98SSadaf Ebrahimi         (ret = mgf_mask(buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1600*62c56f98SSadaf Ebrahimi                         (mbedtls_md_type_t) ctx->hash_id)) != 0) {
1601*62c56f98SSadaf Ebrahimi         goto cleanup;
1602*62c56f98SSadaf Ebrahimi     }
1603*62c56f98SSadaf Ebrahimi 
1604*62c56f98SSadaf Ebrahimi     /* Generate lHash */
1605*62c56f98SSadaf Ebrahimi     ret = compute_hash((mbedtls_md_type_t) ctx->hash_id,
1606*62c56f98SSadaf Ebrahimi                        label, label_len, lhash);
1607*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1608*62c56f98SSadaf Ebrahimi         goto cleanup;
1609*62c56f98SSadaf Ebrahimi     }
1610*62c56f98SSadaf Ebrahimi 
1611*62c56f98SSadaf Ebrahimi     /*
1612*62c56f98SSadaf Ebrahimi      * Check contents, in "constant-time"
1613*62c56f98SSadaf Ebrahimi      */
1614*62c56f98SSadaf Ebrahimi     p = buf;
1615*62c56f98SSadaf Ebrahimi 
1616*62c56f98SSadaf Ebrahimi     bad = mbedtls_ct_bool(*p++); /* First byte must be 0 */
1617*62c56f98SSadaf Ebrahimi 
1618*62c56f98SSadaf Ebrahimi     p += hlen; /* Skip seed */
1619*62c56f98SSadaf Ebrahimi 
1620*62c56f98SSadaf Ebrahimi     /* Check lHash */
1621*62c56f98SSadaf Ebrahimi     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool(mbedtls_ct_memcmp(lhash, p, hlen)));
1622*62c56f98SSadaf Ebrahimi     p += hlen;
1623*62c56f98SSadaf Ebrahimi 
1624*62c56f98SSadaf Ebrahimi     /* Get zero-padding len, but always read till end of buffer
1625*62c56f98SSadaf Ebrahimi      * (minus one, for the 01 byte) */
1626*62c56f98SSadaf Ebrahimi     pad_len = 0;
1627*62c56f98SSadaf Ebrahimi     in_padding = MBEDTLS_CT_TRUE;
1628*62c56f98SSadaf Ebrahimi     for (i = 0; i < ilen - 2 * hlen - 2; i++) {
1629*62c56f98SSadaf Ebrahimi         in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_uint_eq(p[i], 0));
1630*62c56f98SSadaf Ebrahimi         pad_len += mbedtls_ct_uint_if_else_0(in_padding, 1);
1631*62c56f98SSadaf Ebrahimi     }
1632*62c56f98SSadaf Ebrahimi 
1633*62c56f98SSadaf Ebrahimi     p += pad_len;
1634*62c56f98SSadaf Ebrahimi     bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(*p++, 0x01));
1635*62c56f98SSadaf Ebrahimi 
1636*62c56f98SSadaf Ebrahimi     /*
1637*62c56f98SSadaf Ebrahimi      * The only information "leaked" is whether the padding was correct or not
1638*62c56f98SSadaf Ebrahimi      * (eg, no data is copied if it was not correct). This meets the
1639*62c56f98SSadaf Ebrahimi      * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1640*62c56f98SSadaf Ebrahimi      * the different error conditions.
1641*62c56f98SSadaf Ebrahimi      */
1642*62c56f98SSadaf Ebrahimi     if (bad != MBEDTLS_CT_FALSE) {
1643*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1644*62c56f98SSadaf Ebrahimi         goto cleanup;
1645*62c56f98SSadaf Ebrahimi     }
1646*62c56f98SSadaf Ebrahimi 
1647*62c56f98SSadaf Ebrahimi     if (ilen - (p - buf) > output_max_len) {
1648*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1649*62c56f98SSadaf Ebrahimi         goto cleanup;
1650*62c56f98SSadaf Ebrahimi     }
1651*62c56f98SSadaf Ebrahimi 
1652*62c56f98SSadaf Ebrahimi     *olen = ilen - (p - buf);
1653*62c56f98SSadaf Ebrahimi     if (*olen != 0) {
1654*62c56f98SSadaf Ebrahimi         memcpy(output, p, *olen);
1655*62c56f98SSadaf Ebrahimi     }
1656*62c56f98SSadaf Ebrahimi     ret = 0;
1657*62c56f98SSadaf Ebrahimi 
1658*62c56f98SSadaf Ebrahimi cleanup:
1659*62c56f98SSadaf Ebrahimi     mbedtls_platform_zeroize(buf, sizeof(buf));
1660*62c56f98SSadaf Ebrahimi     mbedtls_platform_zeroize(lhash, sizeof(lhash));
1661*62c56f98SSadaf Ebrahimi 
1662*62c56f98SSadaf Ebrahimi     return ret;
1663*62c56f98SSadaf Ebrahimi }
1664*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V21 */
1665*62c56f98SSadaf Ebrahimi 
1666*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
1667*62c56f98SSadaf Ebrahimi /*
1668*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1669*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,size_t * olen,const unsigned char * input,unsigned char * output,size_t output_max_len)1670*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx,
1671*62c56f98SSadaf Ebrahimi                                         int (*f_rng)(void *, unsigned char *, size_t),
1672*62c56f98SSadaf Ebrahimi                                         void *p_rng,
1673*62c56f98SSadaf Ebrahimi                                         size_t *olen,
1674*62c56f98SSadaf Ebrahimi                                         const unsigned char *input,
1675*62c56f98SSadaf Ebrahimi                                         unsigned char *output,
1676*62c56f98SSadaf Ebrahimi                                         size_t output_max_len)
1677*62c56f98SSadaf Ebrahimi {
1678*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1679*62c56f98SSadaf Ebrahimi     size_t ilen;
1680*62c56f98SSadaf Ebrahimi     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1681*62c56f98SSadaf Ebrahimi 
1682*62c56f98SSadaf Ebrahimi     ilen = ctx->len;
1683*62c56f98SSadaf Ebrahimi 
1684*62c56f98SSadaf Ebrahimi     if (ctx->padding != MBEDTLS_RSA_PKCS_V15) {
1685*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1686*62c56f98SSadaf Ebrahimi     }
1687*62c56f98SSadaf Ebrahimi 
1688*62c56f98SSadaf Ebrahimi     if (ilen < 16 || ilen > sizeof(buf)) {
1689*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1690*62c56f98SSadaf Ebrahimi     }
1691*62c56f98SSadaf Ebrahimi 
1692*62c56f98SSadaf Ebrahimi     ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf);
1693*62c56f98SSadaf Ebrahimi 
1694*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1695*62c56f98SSadaf Ebrahimi         goto cleanup;
1696*62c56f98SSadaf Ebrahimi     }
1697*62c56f98SSadaf Ebrahimi 
1698*62c56f98SSadaf Ebrahimi     ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding(buf, ilen,
1699*62c56f98SSadaf Ebrahimi                                                output, output_max_len, olen);
1700*62c56f98SSadaf Ebrahimi 
1701*62c56f98SSadaf Ebrahimi cleanup:
1702*62c56f98SSadaf Ebrahimi     mbedtls_platform_zeroize(buf, sizeof(buf));
1703*62c56f98SSadaf Ebrahimi 
1704*62c56f98SSadaf Ebrahimi     return ret;
1705*62c56f98SSadaf Ebrahimi }
1706*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V15 */
1707*62c56f98SSadaf Ebrahimi 
1708*62c56f98SSadaf Ebrahimi /*
1709*62c56f98SSadaf Ebrahimi  * Do an RSA operation, then remove the message padding
1710*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,size_t * olen,const unsigned char * input,unsigned char * output,size_t output_max_len)1711*62c56f98SSadaf Ebrahimi int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx,
1712*62c56f98SSadaf Ebrahimi                               int (*f_rng)(void *, unsigned char *, size_t),
1713*62c56f98SSadaf Ebrahimi                               void *p_rng,
1714*62c56f98SSadaf Ebrahimi                               size_t *olen,
1715*62c56f98SSadaf Ebrahimi                               const unsigned char *input,
1716*62c56f98SSadaf Ebrahimi                               unsigned char *output,
1717*62c56f98SSadaf Ebrahimi                               size_t output_max_len)
1718*62c56f98SSadaf Ebrahimi {
1719*62c56f98SSadaf Ebrahimi     switch (ctx->padding) {
1720*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
1721*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V15:
1722*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx, f_rng, p_rng, olen,
1723*62c56f98SSadaf Ebrahimi                                                        input, output, output_max_len);
1724*62c56f98SSadaf Ebrahimi #endif
1725*62c56f98SSadaf Ebrahimi 
1726*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
1727*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V21:
1728*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsaes_oaep_decrypt(ctx, f_rng, p_rng, NULL, 0,
1729*62c56f98SSadaf Ebrahimi                                                   olen, input, output,
1730*62c56f98SSadaf Ebrahimi                                                   output_max_len);
1731*62c56f98SSadaf Ebrahimi #endif
1732*62c56f98SSadaf Ebrahimi 
1733*62c56f98SSadaf Ebrahimi         default:
1734*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_INVALID_PADDING;
1735*62c56f98SSadaf Ebrahimi     }
1736*62c56f98SSadaf Ebrahimi }
1737*62c56f98SSadaf Ebrahimi 
1738*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
rsa_rsassa_pss_sign(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,int saltlen,unsigned char * sig)1739*62c56f98SSadaf Ebrahimi static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
1740*62c56f98SSadaf Ebrahimi                                int (*f_rng)(void *, unsigned char *, size_t),
1741*62c56f98SSadaf Ebrahimi                                void *p_rng,
1742*62c56f98SSadaf Ebrahimi                                mbedtls_md_type_t md_alg,
1743*62c56f98SSadaf Ebrahimi                                unsigned int hashlen,
1744*62c56f98SSadaf Ebrahimi                                const unsigned char *hash,
1745*62c56f98SSadaf Ebrahimi                                int saltlen,
1746*62c56f98SSadaf Ebrahimi                                unsigned char *sig)
1747*62c56f98SSadaf Ebrahimi {
1748*62c56f98SSadaf Ebrahimi     size_t olen;
1749*62c56f98SSadaf Ebrahimi     unsigned char *p = sig;
1750*62c56f98SSadaf Ebrahimi     unsigned char *salt = NULL;
1751*62c56f98SSadaf Ebrahimi     size_t slen, min_slen, hlen, offset = 0;
1752*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1753*62c56f98SSadaf Ebrahimi     size_t msb;
1754*62c56f98SSadaf Ebrahimi 
1755*62c56f98SSadaf Ebrahimi     if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
1756*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1757*62c56f98SSadaf Ebrahimi     }
1758*62c56f98SSadaf Ebrahimi 
1759*62c56f98SSadaf Ebrahimi     if (ctx->padding != MBEDTLS_RSA_PKCS_V21) {
1760*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1761*62c56f98SSadaf Ebrahimi     }
1762*62c56f98SSadaf Ebrahimi 
1763*62c56f98SSadaf Ebrahimi     if (f_rng == NULL) {
1764*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1765*62c56f98SSadaf Ebrahimi     }
1766*62c56f98SSadaf Ebrahimi 
1767*62c56f98SSadaf Ebrahimi     olen = ctx->len;
1768*62c56f98SSadaf Ebrahimi 
1769*62c56f98SSadaf Ebrahimi     if (md_alg != MBEDTLS_MD_NONE) {
1770*62c56f98SSadaf Ebrahimi         /* Gather length of hash to sign */
1771*62c56f98SSadaf Ebrahimi         size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
1772*62c56f98SSadaf Ebrahimi         if (exp_hashlen == 0) {
1773*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1774*62c56f98SSadaf Ebrahimi         }
1775*62c56f98SSadaf Ebrahimi 
1776*62c56f98SSadaf Ebrahimi         if (hashlen != exp_hashlen) {
1777*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1778*62c56f98SSadaf Ebrahimi         }
1779*62c56f98SSadaf Ebrahimi     }
1780*62c56f98SSadaf Ebrahimi 
1781*62c56f98SSadaf Ebrahimi     hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
1782*62c56f98SSadaf Ebrahimi     if (hlen == 0) {
1783*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1784*62c56f98SSadaf Ebrahimi     }
1785*62c56f98SSadaf Ebrahimi 
1786*62c56f98SSadaf Ebrahimi     if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY) {
1787*62c56f98SSadaf Ebrahimi         /* Calculate the largest possible salt length, up to the hash size.
1788*62c56f98SSadaf Ebrahimi          * Normally this is the hash length, which is the maximum salt length
1789*62c56f98SSadaf Ebrahimi          * according to FIPS 185-4 §5.5 (e) and common practice. If there is not
1790*62c56f98SSadaf Ebrahimi          * enough room, use the maximum salt length that fits. The constraint is
1791*62c56f98SSadaf Ebrahimi          * that the hash length plus the salt length plus 2 bytes must be at most
1792*62c56f98SSadaf Ebrahimi          * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
1793*62c56f98SSadaf Ebrahimi          * (PKCS#1 v2.2) §9.1.1 step 3. */
1794*62c56f98SSadaf Ebrahimi         min_slen = hlen - 2;
1795*62c56f98SSadaf Ebrahimi         if (olen < hlen + min_slen + 2) {
1796*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1797*62c56f98SSadaf Ebrahimi         } else if (olen >= hlen + hlen + 2) {
1798*62c56f98SSadaf Ebrahimi             slen = hlen;
1799*62c56f98SSadaf Ebrahimi         } else {
1800*62c56f98SSadaf Ebrahimi             slen = olen - hlen - 2;
1801*62c56f98SSadaf Ebrahimi         }
1802*62c56f98SSadaf Ebrahimi     } else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) {
1803*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1804*62c56f98SSadaf Ebrahimi     } else {
1805*62c56f98SSadaf Ebrahimi         slen = (size_t) saltlen;
1806*62c56f98SSadaf Ebrahimi     }
1807*62c56f98SSadaf Ebrahimi 
1808*62c56f98SSadaf Ebrahimi     memset(sig, 0, olen);
1809*62c56f98SSadaf Ebrahimi 
1810*62c56f98SSadaf Ebrahimi     /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
1811*62c56f98SSadaf Ebrahimi     msb = mbedtls_mpi_bitlen(&ctx->N) - 1;
1812*62c56f98SSadaf Ebrahimi     p += olen - hlen - slen - 2;
1813*62c56f98SSadaf Ebrahimi     *p++ = 0x01;
1814*62c56f98SSadaf Ebrahimi 
1815*62c56f98SSadaf Ebrahimi     /* Generate salt of length slen in place in the encoded message */
1816*62c56f98SSadaf Ebrahimi     salt = p;
1817*62c56f98SSadaf Ebrahimi     if ((ret = f_rng(p_rng, salt, slen)) != 0) {
1818*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret);
1819*62c56f98SSadaf Ebrahimi     }
1820*62c56f98SSadaf Ebrahimi 
1821*62c56f98SSadaf Ebrahimi     p += slen;
1822*62c56f98SSadaf Ebrahimi 
1823*62c56f98SSadaf Ebrahimi     /* Generate H = Hash( M' ) */
1824*62c56f98SSadaf Ebrahimi     ret = hash_mprime(hash, hashlen, salt, slen, p, (mbedtls_md_type_t) ctx->hash_id);
1825*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1826*62c56f98SSadaf Ebrahimi         return ret;
1827*62c56f98SSadaf Ebrahimi     }
1828*62c56f98SSadaf Ebrahimi 
1829*62c56f98SSadaf Ebrahimi     /* Compensate for boundary condition when applying mask */
1830*62c56f98SSadaf Ebrahimi     if (msb % 8 == 0) {
1831*62c56f98SSadaf Ebrahimi         offset = 1;
1832*62c56f98SSadaf Ebrahimi     }
1833*62c56f98SSadaf Ebrahimi 
1834*62c56f98SSadaf Ebrahimi     /* maskedDB: Apply dbMask to DB */
1835*62c56f98SSadaf Ebrahimi     ret = mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen,
1836*62c56f98SSadaf Ebrahimi                    (mbedtls_md_type_t) ctx->hash_id);
1837*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1838*62c56f98SSadaf Ebrahimi         return ret;
1839*62c56f98SSadaf Ebrahimi     }
1840*62c56f98SSadaf Ebrahimi 
1841*62c56f98SSadaf Ebrahimi     msb = mbedtls_mpi_bitlen(&ctx->N) - 1;
1842*62c56f98SSadaf Ebrahimi     sig[0] &= 0xFF >> (olen * 8 - msb);
1843*62c56f98SSadaf Ebrahimi 
1844*62c56f98SSadaf Ebrahimi     p += hlen;
1845*62c56f98SSadaf Ebrahimi     *p++ = 0xBC;
1846*62c56f98SSadaf Ebrahimi 
1847*62c56f98SSadaf Ebrahimi     return mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig);
1848*62c56f98SSadaf Ebrahimi }
1849*62c56f98SSadaf Ebrahimi 
1850*62c56f98SSadaf Ebrahimi /*
1851*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with
1852*62c56f98SSadaf Ebrahimi  * the option to pass in the salt length.
1853*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,int saltlen,unsigned char * sig)1854*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx,
1855*62c56f98SSadaf Ebrahimi                                     int (*f_rng)(void *, unsigned char *, size_t),
1856*62c56f98SSadaf Ebrahimi                                     void *p_rng,
1857*62c56f98SSadaf Ebrahimi                                     mbedtls_md_type_t md_alg,
1858*62c56f98SSadaf Ebrahimi                                     unsigned int hashlen,
1859*62c56f98SSadaf Ebrahimi                                     const unsigned char *hash,
1860*62c56f98SSadaf Ebrahimi                                     int saltlen,
1861*62c56f98SSadaf Ebrahimi                                     unsigned char *sig)
1862*62c56f98SSadaf Ebrahimi {
1863*62c56f98SSadaf Ebrahimi     return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg,
1864*62c56f98SSadaf Ebrahimi                                hashlen, hash, saltlen, sig);
1865*62c56f98SSadaf Ebrahimi }
1866*62c56f98SSadaf Ebrahimi 
1867*62c56f98SSadaf Ebrahimi 
1868*62c56f98SSadaf Ebrahimi /*
1869*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1870*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,unsigned char * sig)1871*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
1872*62c56f98SSadaf Ebrahimi                                 int (*f_rng)(void *, unsigned char *, size_t),
1873*62c56f98SSadaf Ebrahimi                                 void *p_rng,
1874*62c56f98SSadaf Ebrahimi                                 mbedtls_md_type_t md_alg,
1875*62c56f98SSadaf Ebrahimi                                 unsigned int hashlen,
1876*62c56f98SSadaf Ebrahimi                                 const unsigned char *hash,
1877*62c56f98SSadaf Ebrahimi                                 unsigned char *sig)
1878*62c56f98SSadaf Ebrahimi {
1879*62c56f98SSadaf Ebrahimi     return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg,
1880*62c56f98SSadaf Ebrahimi                                hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig);
1881*62c56f98SSadaf Ebrahimi }
1882*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V21 */
1883*62c56f98SSadaf Ebrahimi 
1884*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
1885*62c56f98SSadaf Ebrahimi /*
1886*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1887*62c56f98SSadaf Ebrahimi  */
1888*62c56f98SSadaf Ebrahimi 
1889*62c56f98SSadaf Ebrahimi /* Construct a PKCS v1.5 encoding of a hashed message
1890*62c56f98SSadaf Ebrahimi  *
1891*62c56f98SSadaf Ebrahimi  * This is used both for signature generation and verification.
1892*62c56f98SSadaf Ebrahimi  *
1893*62c56f98SSadaf Ebrahimi  * Parameters:
1894*62c56f98SSadaf Ebrahimi  * - md_alg:  Identifies the hash algorithm used to generate the given hash;
1895*62c56f98SSadaf Ebrahimi  *            MBEDTLS_MD_NONE if raw data is signed.
1896*62c56f98SSadaf Ebrahimi  * - hashlen: Length of hash. Must match md_alg if that's not NONE.
1897*62c56f98SSadaf Ebrahimi  * - hash:    Buffer containing the hashed message or the raw data.
1898*62c56f98SSadaf Ebrahimi  * - dst_len: Length of the encoded message.
1899*62c56f98SSadaf Ebrahimi  * - dst:     Buffer to hold the encoded message.
1900*62c56f98SSadaf Ebrahimi  *
1901*62c56f98SSadaf Ebrahimi  * Assumptions:
1902*62c56f98SSadaf Ebrahimi  * - hash has size hashlen.
1903*62c56f98SSadaf Ebrahimi  * - dst points to a buffer of size at least dst_len.
1904*62c56f98SSadaf Ebrahimi  *
1905*62c56f98SSadaf Ebrahimi  */
rsa_rsassa_pkcs1_v15_encode(mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,size_t dst_len,unsigned char * dst)1906*62c56f98SSadaf Ebrahimi static int rsa_rsassa_pkcs1_v15_encode(mbedtls_md_type_t md_alg,
1907*62c56f98SSadaf Ebrahimi                                        unsigned int hashlen,
1908*62c56f98SSadaf Ebrahimi                                        const unsigned char *hash,
1909*62c56f98SSadaf Ebrahimi                                        size_t dst_len,
1910*62c56f98SSadaf Ebrahimi                                        unsigned char *dst)
1911*62c56f98SSadaf Ebrahimi {
1912*62c56f98SSadaf Ebrahimi     size_t oid_size  = 0;
1913*62c56f98SSadaf Ebrahimi     size_t nb_pad    = dst_len;
1914*62c56f98SSadaf Ebrahimi     unsigned char *p = dst;
1915*62c56f98SSadaf Ebrahimi     const char *oid  = NULL;
1916*62c56f98SSadaf Ebrahimi 
1917*62c56f98SSadaf Ebrahimi     /* Are we signing hashed or raw data? */
1918*62c56f98SSadaf Ebrahimi     if (md_alg != MBEDTLS_MD_NONE) {
1919*62c56f98SSadaf Ebrahimi         unsigned char md_size = mbedtls_md_get_size_from_type(md_alg);
1920*62c56f98SSadaf Ebrahimi         if (md_size == 0) {
1921*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1922*62c56f98SSadaf Ebrahimi         }
1923*62c56f98SSadaf Ebrahimi 
1924*62c56f98SSadaf Ebrahimi         if (mbedtls_oid_get_oid_by_md(md_alg, &oid, &oid_size) != 0) {
1925*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1926*62c56f98SSadaf Ebrahimi         }
1927*62c56f98SSadaf Ebrahimi 
1928*62c56f98SSadaf Ebrahimi         if (hashlen != md_size) {
1929*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1930*62c56f98SSadaf Ebrahimi         }
1931*62c56f98SSadaf Ebrahimi 
1932*62c56f98SSadaf Ebrahimi         /* Double-check that 8 + hashlen + oid_size can be used as a
1933*62c56f98SSadaf Ebrahimi          * 1-byte ASN.1 length encoding and that there's no overflow. */
1934*62c56f98SSadaf Ebrahimi         if (8 + hashlen + oid_size  >= 0x80         ||
1935*62c56f98SSadaf Ebrahimi             10 + hashlen            <  hashlen      ||
1936*62c56f98SSadaf Ebrahimi             10 + hashlen + oid_size <  10 + hashlen) {
1937*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1938*62c56f98SSadaf Ebrahimi         }
1939*62c56f98SSadaf Ebrahimi 
1940*62c56f98SSadaf Ebrahimi         /*
1941*62c56f98SSadaf Ebrahimi          * Static bounds check:
1942*62c56f98SSadaf Ebrahimi          * - Need 10 bytes for five tag-length pairs.
1943*62c56f98SSadaf Ebrahimi          *   (Insist on 1-byte length encodings to protect against variants of
1944*62c56f98SSadaf Ebrahimi          *    Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
1945*62c56f98SSadaf Ebrahimi          * - Need hashlen bytes for hash
1946*62c56f98SSadaf Ebrahimi          * - Need oid_size bytes for hash alg OID.
1947*62c56f98SSadaf Ebrahimi          */
1948*62c56f98SSadaf Ebrahimi         if (nb_pad < 10 + hashlen + oid_size) {
1949*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1950*62c56f98SSadaf Ebrahimi         }
1951*62c56f98SSadaf Ebrahimi         nb_pad -= 10 + hashlen + oid_size;
1952*62c56f98SSadaf Ebrahimi     } else {
1953*62c56f98SSadaf Ebrahimi         if (nb_pad < hashlen) {
1954*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1955*62c56f98SSadaf Ebrahimi         }
1956*62c56f98SSadaf Ebrahimi 
1957*62c56f98SSadaf Ebrahimi         nb_pad -= hashlen;
1958*62c56f98SSadaf Ebrahimi     }
1959*62c56f98SSadaf Ebrahimi 
1960*62c56f98SSadaf Ebrahimi     /* Need space for signature header and padding delimiter (3 bytes),
1961*62c56f98SSadaf Ebrahimi      * and 8 bytes for the minimal padding */
1962*62c56f98SSadaf Ebrahimi     if (nb_pad < 3 + 8) {
1963*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1964*62c56f98SSadaf Ebrahimi     }
1965*62c56f98SSadaf Ebrahimi     nb_pad -= 3;
1966*62c56f98SSadaf Ebrahimi 
1967*62c56f98SSadaf Ebrahimi     /* Now nb_pad is the amount of memory to be filled
1968*62c56f98SSadaf Ebrahimi      * with padding, and at least 8 bytes long. */
1969*62c56f98SSadaf Ebrahimi 
1970*62c56f98SSadaf Ebrahimi     /* Write signature header and padding */
1971*62c56f98SSadaf Ebrahimi     *p++ = 0;
1972*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_RSA_SIGN;
1973*62c56f98SSadaf Ebrahimi     memset(p, 0xFF, nb_pad);
1974*62c56f98SSadaf Ebrahimi     p += nb_pad;
1975*62c56f98SSadaf Ebrahimi     *p++ = 0;
1976*62c56f98SSadaf Ebrahimi 
1977*62c56f98SSadaf Ebrahimi     /* Are we signing raw data? */
1978*62c56f98SSadaf Ebrahimi     if (md_alg == MBEDTLS_MD_NONE) {
1979*62c56f98SSadaf Ebrahimi         memcpy(p, hash, hashlen);
1980*62c56f98SSadaf Ebrahimi         return 0;
1981*62c56f98SSadaf Ebrahimi     }
1982*62c56f98SSadaf Ebrahimi 
1983*62c56f98SSadaf Ebrahimi     /* Signing hashed data, add corresponding ASN.1 structure
1984*62c56f98SSadaf Ebrahimi      *
1985*62c56f98SSadaf Ebrahimi      * DigestInfo ::= SEQUENCE {
1986*62c56f98SSadaf Ebrahimi      *   digestAlgorithm DigestAlgorithmIdentifier,
1987*62c56f98SSadaf Ebrahimi      *   digest Digest }
1988*62c56f98SSadaf Ebrahimi      * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1989*62c56f98SSadaf Ebrahimi      * Digest ::= OCTET STRING
1990*62c56f98SSadaf Ebrahimi      *
1991*62c56f98SSadaf Ebrahimi      * Schematic:
1992*62c56f98SSadaf Ebrahimi      * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID  + LEN [ OID  ]
1993*62c56f98SSadaf Ebrahimi      *                                 TAG-NULL + LEN [ NULL ] ]
1994*62c56f98SSadaf Ebrahimi      *                 TAG-OCTET + LEN [ HASH ] ]
1995*62c56f98SSadaf Ebrahimi      */
1996*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
1997*62c56f98SSadaf Ebrahimi     *p++ = (unsigned char) (0x08 + oid_size + hashlen);
1998*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
1999*62c56f98SSadaf Ebrahimi     *p++ = (unsigned char) (0x04 + oid_size);
2000*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_ASN1_OID;
2001*62c56f98SSadaf Ebrahimi     *p++ = (unsigned char) oid_size;
2002*62c56f98SSadaf Ebrahimi     memcpy(p, oid, oid_size);
2003*62c56f98SSadaf Ebrahimi     p += oid_size;
2004*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_ASN1_NULL;
2005*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
2006*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_ASN1_OCTET_STRING;
2007*62c56f98SSadaf Ebrahimi     *p++ = (unsigned char) hashlen;
2008*62c56f98SSadaf Ebrahimi     memcpy(p, hash, hashlen);
2009*62c56f98SSadaf Ebrahimi     p += hashlen;
2010*62c56f98SSadaf Ebrahimi 
2011*62c56f98SSadaf Ebrahimi     /* Just a sanity-check, should be automatic
2012*62c56f98SSadaf Ebrahimi      * after the initial bounds check. */
2013*62c56f98SSadaf Ebrahimi     if (p != dst + dst_len) {
2014*62c56f98SSadaf Ebrahimi         mbedtls_platform_zeroize(dst, dst_len);
2015*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2016*62c56f98SSadaf Ebrahimi     }
2017*62c56f98SSadaf Ebrahimi 
2018*62c56f98SSadaf Ebrahimi     return 0;
2019*62c56f98SSadaf Ebrahimi }
2020*62c56f98SSadaf Ebrahimi 
2021*62c56f98SSadaf Ebrahimi /*
2022*62c56f98SSadaf Ebrahimi  * Do an RSA operation to sign the message digest
2023*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,unsigned char * sig)2024*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
2025*62c56f98SSadaf Ebrahimi                                       int (*f_rng)(void *, unsigned char *, size_t),
2026*62c56f98SSadaf Ebrahimi                                       void *p_rng,
2027*62c56f98SSadaf Ebrahimi                                       mbedtls_md_type_t md_alg,
2028*62c56f98SSadaf Ebrahimi                                       unsigned int hashlen,
2029*62c56f98SSadaf Ebrahimi                                       const unsigned char *hash,
2030*62c56f98SSadaf Ebrahimi                                       unsigned char *sig)
2031*62c56f98SSadaf Ebrahimi {
2032*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2033*62c56f98SSadaf Ebrahimi     unsigned char *sig_try = NULL, *verif = NULL;
2034*62c56f98SSadaf Ebrahimi 
2035*62c56f98SSadaf Ebrahimi     if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2036*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2037*62c56f98SSadaf Ebrahimi     }
2038*62c56f98SSadaf Ebrahimi 
2039*62c56f98SSadaf Ebrahimi     if (ctx->padding != MBEDTLS_RSA_PKCS_V15) {
2040*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2041*62c56f98SSadaf Ebrahimi     }
2042*62c56f98SSadaf Ebrahimi 
2043*62c56f98SSadaf Ebrahimi     /*
2044*62c56f98SSadaf Ebrahimi      * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
2045*62c56f98SSadaf Ebrahimi      */
2046*62c56f98SSadaf Ebrahimi 
2047*62c56f98SSadaf Ebrahimi     if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash,
2048*62c56f98SSadaf Ebrahimi                                            ctx->len, sig)) != 0) {
2049*62c56f98SSadaf Ebrahimi         return ret;
2050*62c56f98SSadaf Ebrahimi     }
2051*62c56f98SSadaf Ebrahimi 
2052*62c56f98SSadaf Ebrahimi     /* Private key operation
2053*62c56f98SSadaf Ebrahimi      *
2054*62c56f98SSadaf Ebrahimi      * In order to prevent Lenstra's attack, make the signature in a
2055*62c56f98SSadaf Ebrahimi      * temporary buffer and check it before returning it.
2056*62c56f98SSadaf Ebrahimi      */
2057*62c56f98SSadaf Ebrahimi 
2058*62c56f98SSadaf Ebrahimi     sig_try = mbedtls_calloc(1, ctx->len);
2059*62c56f98SSadaf Ebrahimi     if (sig_try == NULL) {
2060*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
2061*62c56f98SSadaf Ebrahimi     }
2062*62c56f98SSadaf Ebrahimi 
2063*62c56f98SSadaf Ebrahimi     verif = mbedtls_calloc(1, ctx->len);
2064*62c56f98SSadaf Ebrahimi     if (verif == NULL) {
2065*62c56f98SSadaf Ebrahimi         mbedtls_free(sig_try);
2066*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
2067*62c56f98SSadaf Ebrahimi     }
2068*62c56f98SSadaf Ebrahimi 
2069*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig_try));
2070*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_public(ctx, sig_try, verif));
2071*62c56f98SSadaf Ebrahimi 
2072*62c56f98SSadaf Ebrahimi     if (mbedtls_ct_memcmp(verif, sig, ctx->len) != 0) {
2073*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2074*62c56f98SSadaf Ebrahimi         goto cleanup;
2075*62c56f98SSadaf Ebrahimi     }
2076*62c56f98SSadaf Ebrahimi 
2077*62c56f98SSadaf Ebrahimi     memcpy(sig, sig_try, ctx->len);
2078*62c56f98SSadaf Ebrahimi 
2079*62c56f98SSadaf Ebrahimi cleanup:
2080*62c56f98SSadaf Ebrahimi     mbedtls_zeroize_and_free(sig_try, ctx->len);
2081*62c56f98SSadaf Ebrahimi     mbedtls_zeroize_and_free(verif, ctx->len);
2082*62c56f98SSadaf Ebrahimi 
2083*62c56f98SSadaf Ebrahimi     if (ret != 0) {
2084*62c56f98SSadaf Ebrahimi         memset(sig, '!', ctx->len);
2085*62c56f98SSadaf Ebrahimi     }
2086*62c56f98SSadaf Ebrahimi     return ret;
2087*62c56f98SSadaf Ebrahimi }
2088*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V15 */
2089*62c56f98SSadaf Ebrahimi 
2090*62c56f98SSadaf Ebrahimi /*
2091*62c56f98SSadaf Ebrahimi  * Do an RSA operation to sign the message digest
2092*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,unsigned char * sig)2093*62c56f98SSadaf Ebrahimi int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx,
2094*62c56f98SSadaf Ebrahimi                            int (*f_rng)(void *, unsigned char *, size_t),
2095*62c56f98SSadaf Ebrahimi                            void *p_rng,
2096*62c56f98SSadaf Ebrahimi                            mbedtls_md_type_t md_alg,
2097*62c56f98SSadaf Ebrahimi                            unsigned int hashlen,
2098*62c56f98SSadaf Ebrahimi                            const unsigned char *hash,
2099*62c56f98SSadaf Ebrahimi                            unsigned char *sig)
2100*62c56f98SSadaf Ebrahimi {
2101*62c56f98SSadaf Ebrahimi     if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2102*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2103*62c56f98SSadaf Ebrahimi     }
2104*62c56f98SSadaf Ebrahimi 
2105*62c56f98SSadaf Ebrahimi     switch (ctx->padding) {
2106*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
2107*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V15:
2108*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx, f_rng, p_rng,
2109*62c56f98SSadaf Ebrahimi                                                      md_alg, hashlen, hash, sig);
2110*62c56f98SSadaf Ebrahimi #endif
2111*62c56f98SSadaf Ebrahimi 
2112*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
2113*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V21:
2114*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg,
2115*62c56f98SSadaf Ebrahimi                                                hashlen, hash, sig);
2116*62c56f98SSadaf Ebrahimi #endif
2117*62c56f98SSadaf Ebrahimi 
2118*62c56f98SSadaf Ebrahimi         default:
2119*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_INVALID_PADDING;
2120*62c56f98SSadaf Ebrahimi     }
2121*62c56f98SSadaf Ebrahimi }
2122*62c56f98SSadaf Ebrahimi 
2123*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
2124*62c56f98SSadaf Ebrahimi /*
2125*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2126*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context * ctx,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,mbedtls_md_type_t mgf1_hash_id,int expected_salt_len,const unsigned char * sig)2127*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx,
2128*62c56f98SSadaf Ebrahimi                                       mbedtls_md_type_t md_alg,
2129*62c56f98SSadaf Ebrahimi                                       unsigned int hashlen,
2130*62c56f98SSadaf Ebrahimi                                       const unsigned char *hash,
2131*62c56f98SSadaf Ebrahimi                                       mbedtls_md_type_t mgf1_hash_id,
2132*62c56f98SSadaf Ebrahimi                                       int expected_salt_len,
2133*62c56f98SSadaf Ebrahimi                                       const unsigned char *sig)
2134*62c56f98SSadaf Ebrahimi {
2135*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2136*62c56f98SSadaf Ebrahimi     size_t siglen;
2137*62c56f98SSadaf Ebrahimi     unsigned char *p;
2138*62c56f98SSadaf Ebrahimi     unsigned char *hash_start;
2139*62c56f98SSadaf Ebrahimi     unsigned char result[MBEDTLS_MD_MAX_SIZE];
2140*62c56f98SSadaf Ebrahimi     unsigned int hlen;
2141*62c56f98SSadaf Ebrahimi     size_t observed_salt_len, msb;
2142*62c56f98SSadaf Ebrahimi     unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = { 0 };
2143*62c56f98SSadaf Ebrahimi 
2144*62c56f98SSadaf Ebrahimi     if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2145*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2146*62c56f98SSadaf Ebrahimi     }
2147*62c56f98SSadaf Ebrahimi 
2148*62c56f98SSadaf Ebrahimi     siglen = ctx->len;
2149*62c56f98SSadaf Ebrahimi 
2150*62c56f98SSadaf Ebrahimi     if (siglen < 16 || siglen > sizeof(buf)) {
2151*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2152*62c56f98SSadaf Ebrahimi     }
2153*62c56f98SSadaf Ebrahimi 
2154*62c56f98SSadaf Ebrahimi     ret = mbedtls_rsa_public(ctx, sig, buf);
2155*62c56f98SSadaf Ebrahimi 
2156*62c56f98SSadaf Ebrahimi     if (ret != 0) {
2157*62c56f98SSadaf Ebrahimi         return ret;
2158*62c56f98SSadaf Ebrahimi     }
2159*62c56f98SSadaf Ebrahimi 
2160*62c56f98SSadaf Ebrahimi     p = buf;
2161*62c56f98SSadaf Ebrahimi 
2162*62c56f98SSadaf Ebrahimi     if (buf[siglen - 1] != 0xBC) {
2163*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_INVALID_PADDING;
2164*62c56f98SSadaf Ebrahimi     }
2165*62c56f98SSadaf Ebrahimi 
2166*62c56f98SSadaf Ebrahimi     if (md_alg != MBEDTLS_MD_NONE) {
2167*62c56f98SSadaf Ebrahimi         /* Gather length of hash to sign */
2168*62c56f98SSadaf Ebrahimi         size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
2169*62c56f98SSadaf Ebrahimi         if (exp_hashlen == 0) {
2170*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2171*62c56f98SSadaf Ebrahimi         }
2172*62c56f98SSadaf Ebrahimi 
2173*62c56f98SSadaf Ebrahimi         if (hashlen != exp_hashlen) {
2174*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2175*62c56f98SSadaf Ebrahimi         }
2176*62c56f98SSadaf Ebrahimi     }
2177*62c56f98SSadaf Ebrahimi 
2178*62c56f98SSadaf Ebrahimi     hlen = mbedtls_md_get_size_from_type(mgf1_hash_id);
2179*62c56f98SSadaf Ebrahimi     if (hlen == 0) {
2180*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2181*62c56f98SSadaf Ebrahimi     }
2182*62c56f98SSadaf Ebrahimi 
2183*62c56f98SSadaf Ebrahimi     /*
2184*62c56f98SSadaf Ebrahimi      * Note: EMSA-PSS verification is over the length of N - 1 bits
2185*62c56f98SSadaf Ebrahimi      */
2186*62c56f98SSadaf Ebrahimi     msb = mbedtls_mpi_bitlen(&ctx->N) - 1;
2187*62c56f98SSadaf Ebrahimi 
2188*62c56f98SSadaf Ebrahimi     if (buf[0] >> (8 - siglen * 8 + msb)) {
2189*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2190*62c56f98SSadaf Ebrahimi     }
2191*62c56f98SSadaf Ebrahimi 
2192*62c56f98SSadaf Ebrahimi     /* Compensate for boundary condition when applying mask */
2193*62c56f98SSadaf Ebrahimi     if (msb % 8 == 0) {
2194*62c56f98SSadaf Ebrahimi         p++;
2195*62c56f98SSadaf Ebrahimi         siglen -= 1;
2196*62c56f98SSadaf Ebrahimi     }
2197*62c56f98SSadaf Ebrahimi 
2198*62c56f98SSadaf Ebrahimi     if (siglen < hlen + 2) {
2199*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2200*62c56f98SSadaf Ebrahimi     }
2201*62c56f98SSadaf Ebrahimi     hash_start = p + siglen - hlen - 1;
2202*62c56f98SSadaf Ebrahimi 
2203*62c56f98SSadaf Ebrahimi     ret = mgf_mask(p, siglen - hlen - 1, hash_start, hlen, mgf1_hash_id);
2204*62c56f98SSadaf Ebrahimi     if (ret != 0) {
2205*62c56f98SSadaf Ebrahimi         return ret;
2206*62c56f98SSadaf Ebrahimi     }
2207*62c56f98SSadaf Ebrahimi 
2208*62c56f98SSadaf Ebrahimi     buf[0] &= 0xFF >> (siglen * 8 - msb);
2209*62c56f98SSadaf Ebrahimi 
2210*62c56f98SSadaf Ebrahimi     while (p < hash_start - 1 && *p == 0) {
2211*62c56f98SSadaf Ebrahimi         p++;
2212*62c56f98SSadaf Ebrahimi     }
2213*62c56f98SSadaf Ebrahimi 
2214*62c56f98SSadaf Ebrahimi     if (*p++ != 0x01) {
2215*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_INVALID_PADDING;
2216*62c56f98SSadaf Ebrahimi     }
2217*62c56f98SSadaf Ebrahimi 
2218*62c56f98SSadaf Ebrahimi     observed_salt_len = hash_start - p;
2219*62c56f98SSadaf Ebrahimi 
2220*62c56f98SSadaf Ebrahimi     if (expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
2221*62c56f98SSadaf Ebrahimi         observed_salt_len != (size_t) expected_salt_len) {
2222*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_INVALID_PADDING;
2223*62c56f98SSadaf Ebrahimi     }
2224*62c56f98SSadaf Ebrahimi 
2225*62c56f98SSadaf Ebrahimi     /*
2226*62c56f98SSadaf Ebrahimi      * Generate H = Hash( M' )
2227*62c56f98SSadaf Ebrahimi      */
2228*62c56f98SSadaf Ebrahimi     ret = hash_mprime(hash, hashlen, p, observed_salt_len,
2229*62c56f98SSadaf Ebrahimi                       result, mgf1_hash_id);
2230*62c56f98SSadaf Ebrahimi     if (ret != 0) {
2231*62c56f98SSadaf Ebrahimi         return ret;
2232*62c56f98SSadaf Ebrahimi     }
2233*62c56f98SSadaf Ebrahimi 
2234*62c56f98SSadaf Ebrahimi     if (memcmp(hash_start, result, hlen) != 0) {
2235*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_VERIFY_FAILED;
2236*62c56f98SSadaf Ebrahimi     }
2237*62c56f98SSadaf Ebrahimi 
2238*62c56f98SSadaf Ebrahimi     return 0;
2239*62c56f98SSadaf Ebrahimi }
2240*62c56f98SSadaf Ebrahimi 
2241*62c56f98SSadaf Ebrahimi /*
2242*62c56f98SSadaf Ebrahimi  * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2243*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context * ctx,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,const unsigned char * sig)2244*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context *ctx,
2245*62c56f98SSadaf Ebrahimi                                   mbedtls_md_type_t md_alg,
2246*62c56f98SSadaf Ebrahimi                                   unsigned int hashlen,
2247*62c56f98SSadaf Ebrahimi                                   const unsigned char *hash,
2248*62c56f98SSadaf Ebrahimi                                   const unsigned char *sig)
2249*62c56f98SSadaf Ebrahimi {
2250*62c56f98SSadaf Ebrahimi     mbedtls_md_type_t mgf1_hash_id;
2251*62c56f98SSadaf Ebrahimi     if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2252*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2253*62c56f98SSadaf Ebrahimi     }
2254*62c56f98SSadaf Ebrahimi 
2255*62c56f98SSadaf Ebrahimi     mgf1_hash_id = (ctx->hash_id != MBEDTLS_MD_NONE)
2256*62c56f98SSadaf Ebrahimi                              ? (mbedtls_md_type_t) ctx->hash_id
2257*62c56f98SSadaf Ebrahimi                              : md_alg;
2258*62c56f98SSadaf Ebrahimi 
2259*62c56f98SSadaf Ebrahimi     return mbedtls_rsa_rsassa_pss_verify_ext(ctx,
2260*62c56f98SSadaf Ebrahimi                                              md_alg, hashlen, hash,
2261*62c56f98SSadaf Ebrahimi                                              mgf1_hash_id,
2262*62c56f98SSadaf Ebrahimi                                              MBEDTLS_RSA_SALT_LEN_ANY,
2263*62c56f98SSadaf Ebrahimi                                              sig);
2264*62c56f98SSadaf Ebrahimi 
2265*62c56f98SSadaf Ebrahimi }
2266*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V21 */
2267*62c56f98SSadaf Ebrahimi 
2268*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
2269*62c56f98SSadaf Ebrahimi /*
2270*62c56f98SSadaf Ebrahimi  * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2271*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context * ctx,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,const unsigned char * sig)2272*62c56f98SSadaf Ebrahimi int mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context *ctx,
2273*62c56f98SSadaf Ebrahimi                                         mbedtls_md_type_t md_alg,
2274*62c56f98SSadaf Ebrahimi                                         unsigned int hashlen,
2275*62c56f98SSadaf Ebrahimi                                         const unsigned char *hash,
2276*62c56f98SSadaf Ebrahimi                                         const unsigned char *sig)
2277*62c56f98SSadaf Ebrahimi {
2278*62c56f98SSadaf Ebrahimi     int ret = 0;
2279*62c56f98SSadaf Ebrahimi     size_t sig_len;
2280*62c56f98SSadaf Ebrahimi     unsigned char *encoded = NULL, *encoded_expected = NULL;
2281*62c56f98SSadaf Ebrahimi 
2282*62c56f98SSadaf Ebrahimi     if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2283*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2284*62c56f98SSadaf Ebrahimi     }
2285*62c56f98SSadaf Ebrahimi 
2286*62c56f98SSadaf Ebrahimi     sig_len = ctx->len;
2287*62c56f98SSadaf Ebrahimi 
2288*62c56f98SSadaf Ebrahimi     /*
2289*62c56f98SSadaf Ebrahimi      * Prepare expected PKCS1 v1.5 encoding of hash.
2290*62c56f98SSadaf Ebrahimi      */
2291*62c56f98SSadaf Ebrahimi 
2292*62c56f98SSadaf Ebrahimi     if ((encoded          = mbedtls_calloc(1, sig_len)) == NULL ||
2293*62c56f98SSadaf Ebrahimi         (encoded_expected = mbedtls_calloc(1, sig_len)) == NULL) {
2294*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
2295*62c56f98SSadaf Ebrahimi         goto cleanup;
2296*62c56f98SSadaf Ebrahimi     }
2297*62c56f98SSadaf Ebrahimi 
2298*62c56f98SSadaf Ebrahimi     if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, sig_len,
2299*62c56f98SSadaf Ebrahimi                                            encoded_expected)) != 0) {
2300*62c56f98SSadaf Ebrahimi         goto cleanup;
2301*62c56f98SSadaf Ebrahimi     }
2302*62c56f98SSadaf Ebrahimi 
2303*62c56f98SSadaf Ebrahimi     /*
2304*62c56f98SSadaf Ebrahimi      * Apply RSA primitive to get what should be PKCS1 encoded hash.
2305*62c56f98SSadaf Ebrahimi      */
2306*62c56f98SSadaf Ebrahimi 
2307*62c56f98SSadaf Ebrahimi     ret = mbedtls_rsa_public(ctx, sig, encoded);
2308*62c56f98SSadaf Ebrahimi     if (ret != 0) {
2309*62c56f98SSadaf Ebrahimi         goto cleanup;
2310*62c56f98SSadaf Ebrahimi     }
2311*62c56f98SSadaf Ebrahimi 
2312*62c56f98SSadaf Ebrahimi     /*
2313*62c56f98SSadaf Ebrahimi      * Compare
2314*62c56f98SSadaf Ebrahimi      */
2315*62c56f98SSadaf Ebrahimi 
2316*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ct_memcmp(encoded, encoded_expected,
2317*62c56f98SSadaf Ebrahimi                                  sig_len)) != 0) {
2318*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
2319*62c56f98SSadaf Ebrahimi         goto cleanup;
2320*62c56f98SSadaf Ebrahimi     }
2321*62c56f98SSadaf Ebrahimi 
2322*62c56f98SSadaf Ebrahimi cleanup:
2323*62c56f98SSadaf Ebrahimi 
2324*62c56f98SSadaf Ebrahimi     if (encoded != NULL) {
2325*62c56f98SSadaf Ebrahimi         mbedtls_zeroize_and_free(encoded, sig_len);
2326*62c56f98SSadaf Ebrahimi     }
2327*62c56f98SSadaf Ebrahimi 
2328*62c56f98SSadaf Ebrahimi     if (encoded_expected != NULL) {
2329*62c56f98SSadaf Ebrahimi         mbedtls_zeroize_and_free(encoded_expected, sig_len);
2330*62c56f98SSadaf Ebrahimi     }
2331*62c56f98SSadaf Ebrahimi 
2332*62c56f98SSadaf Ebrahimi     return ret;
2333*62c56f98SSadaf Ebrahimi }
2334*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V15 */
2335*62c56f98SSadaf Ebrahimi 
2336*62c56f98SSadaf Ebrahimi /*
2337*62c56f98SSadaf Ebrahimi  * Do an RSA operation and check the message digest
2338*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context * ctx,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,const unsigned char * sig)2339*62c56f98SSadaf Ebrahimi int mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context *ctx,
2340*62c56f98SSadaf Ebrahimi                              mbedtls_md_type_t md_alg,
2341*62c56f98SSadaf Ebrahimi                              unsigned int hashlen,
2342*62c56f98SSadaf Ebrahimi                              const unsigned char *hash,
2343*62c56f98SSadaf Ebrahimi                              const unsigned char *sig)
2344*62c56f98SSadaf Ebrahimi {
2345*62c56f98SSadaf Ebrahimi     if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2346*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2347*62c56f98SSadaf Ebrahimi     }
2348*62c56f98SSadaf Ebrahimi 
2349*62c56f98SSadaf Ebrahimi     switch (ctx->padding) {
2350*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
2351*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V15:
2352*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsassa_pkcs1_v15_verify(ctx, md_alg,
2353*62c56f98SSadaf Ebrahimi                                                        hashlen, hash, sig);
2354*62c56f98SSadaf Ebrahimi #endif
2355*62c56f98SSadaf Ebrahimi 
2356*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V21)
2357*62c56f98SSadaf Ebrahimi         case MBEDTLS_RSA_PKCS_V21:
2358*62c56f98SSadaf Ebrahimi             return mbedtls_rsa_rsassa_pss_verify(ctx, md_alg,
2359*62c56f98SSadaf Ebrahimi                                                  hashlen, hash, sig);
2360*62c56f98SSadaf Ebrahimi #endif
2361*62c56f98SSadaf Ebrahimi 
2362*62c56f98SSadaf Ebrahimi         default:
2363*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_RSA_INVALID_PADDING;
2364*62c56f98SSadaf Ebrahimi     }
2365*62c56f98SSadaf Ebrahimi }
2366*62c56f98SSadaf Ebrahimi 
2367*62c56f98SSadaf Ebrahimi /*
2368*62c56f98SSadaf Ebrahimi  * Copy the components of an RSA key
2369*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_copy(mbedtls_rsa_context * dst,const mbedtls_rsa_context * src)2370*62c56f98SSadaf Ebrahimi int mbedtls_rsa_copy(mbedtls_rsa_context *dst, const mbedtls_rsa_context *src)
2371*62c56f98SSadaf Ebrahimi {
2372*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2373*62c56f98SSadaf Ebrahimi 
2374*62c56f98SSadaf Ebrahimi     dst->len = src->len;
2375*62c56f98SSadaf Ebrahimi 
2376*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->N, &src->N));
2377*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->E, &src->E));
2378*62c56f98SSadaf Ebrahimi 
2379*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->D, &src->D));
2380*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->P, &src->P));
2381*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Q, &src->Q));
2382*62c56f98SSadaf Ebrahimi 
2383*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
2384*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DP, &src->DP));
2385*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DQ, &src->DQ));
2386*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->QP, &src->QP));
2387*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RP, &src->RP));
2388*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RQ, &src->RQ));
2389*62c56f98SSadaf Ebrahimi #endif
2390*62c56f98SSadaf Ebrahimi 
2391*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RN, &src->RN));
2392*62c56f98SSadaf Ebrahimi 
2393*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vi, &src->Vi));
2394*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vf, &src->Vf));
2395*62c56f98SSadaf Ebrahimi 
2396*62c56f98SSadaf Ebrahimi     dst->padding = src->padding;
2397*62c56f98SSadaf Ebrahimi     dst->hash_id = src->hash_id;
2398*62c56f98SSadaf Ebrahimi 
2399*62c56f98SSadaf Ebrahimi cleanup:
2400*62c56f98SSadaf Ebrahimi     if (ret != 0) {
2401*62c56f98SSadaf Ebrahimi         mbedtls_rsa_free(dst);
2402*62c56f98SSadaf Ebrahimi     }
2403*62c56f98SSadaf Ebrahimi 
2404*62c56f98SSadaf Ebrahimi     return ret;
2405*62c56f98SSadaf Ebrahimi }
2406*62c56f98SSadaf Ebrahimi 
2407*62c56f98SSadaf Ebrahimi /*
2408*62c56f98SSadaf Ebrahimi  * Free the components of an RSA key
2409*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_free(mbedtls_rsa_context * ctx)2410*62c56f98SSadaf Ebrahimi void mbedtls_rsa_free(mbedtls_rsa_context *ctx)
2411*62c56f98SSadaf Ebrahimi {
2412*62c56f98SSadaf Ebrahimi     if (ctx == NULL) {
2413*62c56f98SSadaf Ebrahimi         return;
2414*62c56f98SSadaf Ebrahimi     }
2415*62c56f98SSadaf Ebrahimi 
2416*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->Vi);
2417*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->Vf);
2418*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->RN);
2419*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->D);
2420*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->Q);
2421*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->P);
2422*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->E);
2423*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->N);
2424*62c56f98SSadaf Ebrahimi 
2425*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_RSA_NO_CRT)
2426*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->RQ);
2427*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->RP);
2428*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->QP);
2429*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->DQ);
2430*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&ctx->DP);
2431*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_NO_CRT */
2432*62c56f98SSadaf Ebrahimi 
2433*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
2434*62c56f98SSadaf Ebrahimi     /* Free the mutex, but only if it hasn't been freed already. */
2435*62c56f98SSadaf Ebrahimi     if (ctx->ver != 0) {
2436*62c56f98SSadaf Ebrahimi         mbedtls_mutex_free(&ctx->mutex);
2437*62c56f98SSadaf Ebrahimi         ctx->ver = 0;
2438*62c56f98SSadaf Ebrahimi     }
2439*62c56f98SSadaf Ebrahimi #endif
2440*62c56f98SSadaf Ebrahimi }
2441*62c56f98SSadaf Ebrahimi 
2442*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_RSA_ALT */
2443*62c56f98SSadaf Ebrahimi 
2444*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SELF_TEST)
2445*62c56f98SSadaf Ebrahimi 
2446*62c56f98SSadaf Ebrahimi #include "mbedtls/md.h"
2447*62c56f98SSadaf Ebrahimi 
2448*62c56f98SSadaf Ebrahimi /*
2449*62c56f98SSadaf Ebrahimi  * Example RSA-1024 keypair, for test purposes
2450*62c56f98SSadaf Ebrahimi  */
2451*62c56f98SSadaf Ebrahimi #define KEY_LEN 128
2452*62c56f98SSadaf Ebrahimi 
2453*62c56f98SSadaf Ebrahimi #define RSA_N   "9292758453063D803DD603D5E777D788" \
2454*62c56f98SSadaf Ebrahimi                 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2455*62c56f98SSadaf Ebrahimi                 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2456*62c56f98SSadaf Ebrahimi                 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2457*62c56f98SSadaf Ebrahimi                 "93A89813FBF3C4F8066D2D800F7C38A8" \
2458*62c56f98SSadaf Ebrahimi                 "1AE31942917403FF4946B0A83D3D3E05" \
2459*62c56f98SSadaf Ebrahimi                 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2460*62c56f98SSadaf Ebrahimi                 "5E94BB77B07507233A0BC7BAC8F90F79"
2461*62c56f98SSadaf Ebrahimi 
2462*62c56f98SSadaf Ebrahimi #define RSA_E   "10001"
2463*62c56f98SSadaf Ebrahimi 
2464*62c56f98SSadaf Ebrahimi #define RSA_D   "24BF6185468786FDD303083D25E64EFC" \
2465*62c56f98SSadaf Ebrahimi                 "66CA472BC44D253102F8B4A9D3BFA750" \
2466*62c56f98SSadaf Ebrahimi                 "91386C0077937FE33FA3252D28855837" \
2467*62c56f98SSadaf Ebrahimi                 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2468*62c56f98SSadaf Ebrahimi                 "DF79C5CE07EE72C7F123142198164234" \
2469*62c56f98SSadaf Ebrahimi                 "CABB724CF78B8173B9F880FC86322407" \
2470*62c56f98SSadaf Ebrahimi                 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2471*62c56f98SSadaf Ebrahimi                 "071513A1E85B5DFA031F21ECAE91A34D"
2472*62c56f98SSadaf Ebrahimi 
2473*62c56f98SSadaf Ebrahimi #define RSA_P   "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2474*62c56f98SSadaf Ebrahimi                 "2C01CAD19EA484A87EA4377637E75500" \
2475*62c56f98SSadaf Ebrahimi                 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2476*62c56f98SSadaf Ebrahimi                 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2477*62c56f98SSadaf Ebrahimi 
2478*62c56f98SSadaf Ebrahimi #define RSA_Q   "C000DF51A7C77AE8D7C7370C1FF55B69" \
2479*62c56f98SSadaf Ebrahimi                 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2480*62c56f98SSadaf Ebrahimi                 "910E4168387E3C30AA1E00C339A79508" \
2481*62c56f98SSadaf Ebrahimi                 "8452DD96A9A5EA5D9DCA68DA636032AF"
2482*62c56f98SSadaf Ebrahimi 
2483*62c56f98SSadaf Ebrahimi #define PT_LEN  24
2484*62c56f98SSadaf Ebrahimi #define RSA_PT  "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2485*62c56f98SSadaf Ebrahimi                 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2486*62c56f98SSadaf Ebrahimi 
2487*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
myrand(void * rng_state,unsigned char * output,size_t len)2488*62c56f98SSadaf Ebrahimi static int myrand(void *rng_state, unsigned char *output, size_t len)
2489*62c56f98SSadaf Ebrahimi {
2490*62c56f98SSadaf Ebrahimi #if !defined(__OpenBSD__) && !defined(__NetBSD__)
2491*62c56f98SSadaf Ebrahimi     size_t i;
2492*62c56f98SSadaf Ebrahimi 
2493*62c56f98SSadaf Ebrahimi     if (rng_state != NULL) {
2494*62c56f98SSadaf Ebrahimi         rng_state  = NULL;
2495*62c56f98SSadaf Ebrahimi     }
2496*62c56f98SSadaf Ebrahimi 
2497*62c56f98SSadaf Ebrahimi     for (i = 0; i < len; ++i) {
2498*62c56f98SSadaf Ebrahimi         output[i] = rand();
2499*62c56f98SSadaf Ebrahimi     }
2500*62c56f98SSadaf Ebrahimi #else
2501*62c56f98SSadaf Ebrahimi     if (rng_state != NULL) {
2502*62c56f98SSadaf Ebrahimi         rng_state = NULL;
2503*62c56f98SSadaf Ebrahimi     }
2504*62c56f98SSadaf Ebrahimi 
2505*62c56f98SSadaf Ebrahimi     arc4random_buf(output, len);
2506*62c56f98SSadaf Ebrahimi #endif /* !OpenBSD && !NetBSD */
2507*62c56f98SSadaf Ebrahimi 
2508*62c56f98SSadaf Ebrahimi     return 0;
2509*62c56f98SSadaf Ebrahimi }
2510*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V15 */
2511*62c56f98SSadaf Ebrahimi 
2512*62c56f98SSadaf Ebrahimi /*
2513*62c56f98SSadaf Ebrahimi  * Checkup routine
2514*62c56f98SSadaf Ebrahimi  */
mbedtls_rsa_self_test(int verbose)2515*62c56f98SSadaf Ebrahimi int mbedtls_rsa_self_test(int verbose)
2516*62c56f98SSadaf Ebrahimi {
2517*62c56f98SSadaf Ebrahimi     int ret = 0;
2518*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PKCS1_V15)
2519*62c56f98SSadaf Ebrahimi     size_t len;
2520*62c56f98SSadaf Ebrahimi     mbedtls_rsa_context rsa;
2521*62c56f98SSadaf Ebrahimi     unsigned char rsa_plaintext[PT_LEN];
2522*62c56f98SSadaf Ebrahimi     unsigned char rsa_decrypted[PT_LEN];
2523*62c56f98SSadaf Ebrahimi     unsigned char rsa_ciphertext[KEY_LEN];
2524*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_MD_CAN_SHA1)
2525*62c56f98SSadaf Ebrahimi     unsigned char sha1sum[20];
2526*62c56f98SSadaf Ebrahimi #endif
2527*62c56f98SSadaf Ebrahimi 
2528*62c56f98SSadaf Ebrahimi     mbedtls_mpi K;
2529*62c56f98SSadaf Ebrahimi 
2530*62c56f98SSadaf Ebrahimi     mbedtls_mpi_init(&K);
2531*62c56f98SSadaf Ebrahimi     mbedtls_rsa_init(&rsa);
2532*62c56f98SSadaf Ebrahimi 
2533*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_N));
2534*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, &K, NULL, NULL, NULL, NULL));
2535*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_P));
2536*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, &K, NULL, NULL, NULL));
2537*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_Q));
2538*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, &K, NULL, NULL));
2539*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_D));
2540*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, &K, NULL));
2541*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_E));
2542*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, NULL, &K));
2543*62c56f98SSadaf Ebrahimi 
2544*62c56f98SSadaf Ebrahimi     MBEDTLS_MPI_CHK(mbedtls_rsa_complete(&rsa));
2545*62c56f98SSadaf Ebrahimi 
2546*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2547*62c56f98SSadaf Ebrahimi         mbedtls_printf("  RSA key validation: ");
2548*62c56f98SSadaf Ebrahimi     }
2549*62c56f98SSadaf Ebrahimi 
2550*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_check_pubkey(&rsa) != 0 ||
2551*62c56f98SSadaf Ebrahimi         mbedtls_rsa_check_privkey(&rsa) != 0) {
2552*62c56f98SSadaf Ebrahimi         if (verbose != 0) {
2553*62c56f98SSadaf Ebrahimi             mbedtls_printf("failed\n");
2554*62c56f98SSadaf Ebrahimi         }
2555*62c56f98SSadaf Ebrahimi 
2556*62c56f98SSadaf Ebrahimi         ret = 1;
2557*62c56f98SSadaf Ebrahimi         goto cleanup;
2558*62c56f98SSadaf Ebrahimi     }
2559*62c56f98SSadaf Ebrahimi 
2560*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2561*62c56f98SSadaf Ebrahimi         mbedtls_printf("passed\n  PKCS#1 encryption : ");
2562*62c56f98SSadaf Ebrahimi     }
2563*62c56f98SSadaf Ebrahimi 
2564*62c56f98SSadaf Ebrahimi     memcpy(rsa_plaintext, RSA_PT, PT_LEN);
2565*62c56f98SSadaf Ebrahimi 
2566*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_pkcs1_encrypt(&rsa, myrand, NULL,
2567*62c56f98SSadaf Ebrahimi                                   PT_LEN, rsa_plaintext,
2568*62c56f98SSadaf Ebrahimi                                   rsa_ciphertext) != 0) {
2569*62c56f98SSadaf Ebrahimi         if (verbose != 0) {
2570*62c56f98SSadaf Ebrahimi             mbedtls_printf("failed\n");
2571*62c56f98SSadaf Ebrahimi         }
2572*62c56f98SSadaf Ebrahimi 
2573*62c56f98SSadaf Ebrahimi         ret = 1;
2574*62c56f98SSadaf Ebrahimi         goto cleanup;
2575*62c56f98SSadaf Ebrahimi     }
2576*62c56f98SSadaf Ebrahimi 
2577*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2578*62c56f98SSadaf Ebrahimi         mbedtls_printf("passed\n  PKCS#1 decryption : ");
2579*62c56f98SSadaf Ebrahimi     }
2580*62c56f98SSadaf Ebrahimi 
2581*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_pkcs1_decrypt(&rsa, myrand, NULL,
2582*62c56f98SSadaf Ebrahimi                                   &len, rsa_ciphertext, rsa_decrypted,
2583*62c56f98SSadaf Ebrahimi                                   sizeof(rsa_decrypted)) != 0) {
2584*62c56f98SSadaf Ebrahimi         if (verbose != 0) {
2585*62c56f98SSadaf Ebrahimi             mbedtls_printf("failed\n");
2586*62c56f98SSadaf Ebrahimi         }
2587*62c56f98SSadaf Ebrahimi 
2588*62c56f98SSadaf Ebrahimi         ret = 1;
2589*62c56f98SSadaf Ebrahimi         goto cleanup;
2590*62c56f98SSadaf Ebrahimi     }
2591*62c56f98SSadaf Ebrahimi 
2592*62c56f98SSadaf Ebrahimi     if (memcmp(rsa_decrypted, rsa_plaintext, len) != 0) {
2593*62c56f98SSadaf Ebrahimi         if (verbose != 0) {
2594*62c56f98SSadaf Ebrahimi             mbedtls_printf("failed\n");
2595*62c56f98SSadaf Ebrahimi         }
2596*62c56f98SSadaf Ebrahimi 
2597*62c56f98SSadaf Ebrahimi         ret = 1;
2598*62c56f98SSadaf Ebrahimi         goto cleanup;
2599*62c56f98SSadaf Ebrahimi     }
2600*62c56f98SSadaf Ebrahimi 
2601*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2602*62c56f98SSadaf Ebrahimi         mbedtls_printf("passed\n");
2603*62c56f98SSadaf Ebrahimi     }
2604*62c56f98SSadaf Ebrahimi 
2605*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_MD_CAN_SHA1)
2606*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2607*62c56f98SSadaf Ebrahimi         mbedtls_printf("  PKCS#1 data sign  : ");
2608*62c56f98SSadaf Ebrahimi     }
2609*62c56f98SSadaf Ebrahimi 
2610*62c56f98SSadaf Ebrahimi     if (mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
2611*62c56f98SSadaf Ebrahimi                    rsa_plaintext, PT_LEN, sha1sum) != 0) {
2612*62c56f98SSadaf Ebrahimi         if (verbose != 0) {
2613*62c56f98SSadaf Ebrahimi             mbedtls_printf("failed\n");
2614*62c56f98SSadaf Ebrahimi         }
2615*62c56f98SSadaf Ebrahimi 
2616*62c56f98SSadaf Ebrahimi         return 1;
2617*62c56f98SSadaf Ebrahimi     }
2618*62c56f98SSadaf Ebrahimi 
2619*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_pkcs1_sign(&rsa, myrand, NULL,
2620*62c56f98SSadaf Ebrahimi                                MBEDTLS_MD_SHA1, 20,
2621*62c56f98SSadaf Ebrahimi                                sha1sum, rsa_ciphertext) != 0) {
2622*62c56f98SSadaf Ebrahimi         if (verbose != 0) {
2623*62c56f98SSadaf Ebrahimi             mbedtls_printf("failed\n");
2624*62c56f98SSadaf Ebrahimi         }
2625*62c56f98SSadaf Ebrahimi 
2626*62c56f98SSadaf Ebrahimi         ret = 1;
2627*62c56f98SSadaf Ebrahimi         goto cleanup;
2628*62c56f98SSadaf Ebrahimi     }
2629*62c56f98SSadaf Ebrahimi 
2630*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2631*62c56f98SSadaf Ebrahimi         mbedtls_printf("passed\n  PKCS#1 sig. verify: ");
2632*62c56f98SSadaf Ebrahimi     }
2633*62c56f98SSadaf Ebrahimi 
2634*62c56f98SSadaf Ebrahimi     if (mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA1, 20,
2635*62c56f98SSadaf Ebrahimi                                  sha1sum, rsa_ciphertext) != 0) {
2636*62c56f98SSadaf Ebrahimi         if (verbose != 0) {
2637*62c56f98SSadaf Ebrahimi             mbedtls_printf("failed\n");
2638*62c56f98SSadaf Ebrahimi         }
2639*62c56f98SSadaf Ebrahimi 
2640*62c56f98SSadaf Ebrahimi         ret = 1;
2641*62c56f98SSadaf Ebrahimi         goto cleanup;
2642*62c56f98SSadaf Ebrahimi     }
2643*62c56f98SSadaf Ebrahimi 
2644*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2645*62c56f98SSadaf Ebrahimi         mbedtls_printf("passed\n");
2646*62c56f98SSadaf Ebrahimi     }
2647*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_MD_CAN_SHA1 */
2648*62c56f98SSadaf Ebrahimi 
2649*62c56f98SSadaf Ebrahimi     if (verbose != 0) {
2650*62c56f98SSadaf Ebrahimi         mbedtls_printf("\n");
2651*62c56f98SSadaf Ebrahimi     }
2652*62c56f98SSadaf Ebrahimi 
2653*62c56f98SSadaf Ebrahimi cleanup:
2654*62c56f98SSadaf Ebrahimi     mbedtls_mpi_free(&K);
2655*62c56f98SSadaf Ebrahimi     mbedtls_rsa_free(&rsa);
2656*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_PKCS1_V15 */
2657*62c56f98SSadaf Ebrahimi     ((void) verbose);
2658*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PKCS1_V15 */
2659*62c56f98SSadaf Ebrahimi     return ret;
2660*62c56f98SSadaf Ebrahimi }
2661*62c56f98SSadaf Ebrahimi 
2662*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SELF_TEST */
2663*62c56f98SSadaf Ebrahimi 
2664*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_C */
2665