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