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