cc621530398ddaeb83691a212401ca938c4b64a1
[openssl.git] / crypto / rsa / rsa_crpt.c
1 /*
2  * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include <openssl/crypto.h>
12 #include "internal/cryptlib.h"
13 #include <openssl/lhash.h>
14 #include "internal/bn_int.h"
15 #include <openssl/rand.h>
16 #include "rsa_locl.h"
17
18 int RSA_bits(const RSA *r)
19 {
20     return BN_num_bits(r->n);
21 }
22
23 int RSA_size(const RSA *r)
24 {
25     return BN_num_bytes(r->n);
26 }
27
28 int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
29                        RSA *rsa, int padding)
30 {
31     return rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding);
32 }
33
34 int RSA_private_encrypt(int flen, const unsigned char *from,
35                         unsigned char *to, RSA *rsa, int padding)
36 {
37     return rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding);
38 }
39
40 int RSA_private_decrypt(int flen, const unsigned char *from,
41                         unsigned char *to, RSA *rsa, int padding)
42 {
43     return rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding);
44 }
45
46 int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
47                        RSA *rsa, int padding)
48 {
49     return rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding);
50 }
51
52 int RSA_flags(const RSA *r)
53 {
54     return r == NULL ? 0 : r->meth->flags;
55 }
56
57 void RSA_blinding_off(RSA *rsa)
58 {
59     BN_BLINDING_free(rsa->blinding);
60     rsa->blinding = NULL;
61     rsa->flags &= ~RSA_FLAG_BLINDING;
62     rsa->flags |= RSA_FLAG_NO_BLINDING;
63 }
64
65 int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
66 {
67     int ret = 0;
68
69     if (rsa->blinding != NULL)
70         RSA_blinding_off(rsa);
71
72     rsa->blinding = RSA_setup_blinding(rsa, ctx);
73     if (rsa->blinding == NULL)
74         goto err;
75
76     rsa->flags |= RSA_FLAG_BLINDING;
77     rsa->flags &= ~RSA_FLAG_NO_BLINDING;
78     ret = 1;
79  err:
80     return ret;
81 }
82
83 static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
84                                   const BIGNUM *q, BN_CTX *ctx)
85 {
86     BIGNUM *ret = NULL, *r0, *r1, *r2;
87
88     if (d == NULL || p == NULL || q == NULL)
89         return NULL;
90
91     BN_CTX_start(ctx);
92     r0 = BN_CTX_get(ctx);
93     r1 = BN_CTX_get(ctx);
94     r2 = BN_CTX_get(ctx);
95     if (r2 == NULL)
96         goto err;
97
98     if (!BN_sub(r1, p, BN_value_one()))
99         goto err;
100     if (!BN_sub(r2, q, BN_value_one()))
101         goto err;
102     if (!BN_mul(r0, r1, r2, ctx))
103         goto err;
104
105     ret = BN_mod_inverse(NULL, d, r0, ctx);
106  err:
107     BN_CTX_end(ctx);
108     return ret;
109 }
110
111 BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
112 {
113     BIGNUM *e;
114     BN_CTX *ctx;
115     BN_BLINDING *ret = NULL;
116
117     if (in_ctx == NULL) {
118         if ((ctx = BN_CTX_new()) == NULL)
119             return 0;
120     } else {
121         ctx = in_ctx;
122     }
123
124     BN_CTX_start(ctx);
125     e = BN_CTX_get(ctx);
126     if (e == NULL) {
127         RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
128         goto err;
129     }
130
131     if (rsa->e == NULL) {
132         e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
133         if (e == NULL) {
134             RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
135             goto err;
136         }
137     } else {
138         e = rsa->e;
139     }
140
141     {
142         BIGNUM *n = BN_new();
143
144         if (n == NULL) {
145             RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
146             goto err;
147         }
148         BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
149
150         ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
151                                        rsa->_method_mod_n);
152         /* We MUST free n before any further use of rsa->n */
153         BN_free(n);
154     }
155     if (ret == NULL) {
156         RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
157         goto err;
158     }
159
160     BN_BLINDING_set_current_thread(ret);
161
162  err:
163     BN_CTX_end(ctx);
164     if (ctx != in_ctx)
165         BN_CTX_free(ctx);
166     if (e != rsa->e)
167         BN_free(e);
168
169     return ret;
170 }