Coverage Report

Created: 2023-03-26 08:33

/src/nettle/rsa-sign.c
Line
Count
Source (jump to first uncovered line)
1
/* rsa-sign.c
2
3
   Creating RSA signatures.
4
5
   Copyright (C) 2001, 2003 Niels Möller
6
7
   This file is part of GNU Nettle.
8
9
   GNU Nettle is free software: you can redistribute it and/or
10
   modify it under the terms of either:
11
12
     * the GNU Lesser General Public License as published by the Free
13
       Software Foundation; either version 3 of the License, or (at your
14
       option) any later version.
15
16
   or
17
18
     * the GNU General Public License as published by the Free
19
       Software Foundation; either version 2 of the License, or (at your
20
       option) any later version.
21
22
   or both in parallel, as here.
23
24
   GNU Nettle is distributed in the hope that it will be useful,
25
   but WITHOUT ANY WARRANTY; without even the implied warranty of
26
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
   General Public License for more details.
28
29
   You should have received copies of the GNU General Public License and
30
   the GNU Lesser General Public License along with this program.  If
31
   not, see http://www.gnu.org/licenses/.
32
*/
33
34
#if HAVE_CONFIG_H
35
# include "config.h"
36
#endif
37
38
#include <assert.h>
39
40
#include "rsa.h"
41
#include "rsa-internal.h"
42
#include "gmp-glue.h"
43
44
void
45
rsa_private_key_init(struct rsa_private_key *key)
46
0
{
47
0
  mpz_init(key->d);
48
0
  mpz_init(key->p);
49
0
  mpz_init(key->q);
50
0
  mpz_init(key->a);
51
0
  mpz_init(key->b);
52
0
  mpz_init(key->c);
53
54
  /* Not really necessary, but it seems cleaner to initialize all the
55
   * storage. */
56
0
  key->size = 0;
57
0
}
58
59
void
60
rsa_private_key_clear(struct rsa_private_key *key)
61
0
{
62
0
  mpz_clear(key->d);
63
0
  mpz_clear(key->p);
64
0
  mpz_clear(key->q);
65
0
  mpz_clear(key->a);
66
0
  mpz_clear(key->b);
67
0
  mpz_clear(key->c);
68
0
}
69
70
int
71
rsa_private_key_prepare(struct rsa_private_key *key)
72
0
{
73
0
  mpz_t n;
74
75
  /* A key is invalid if the sizes of q and c are smaller than
76
   * the size of n, we rely on that property in calculations so
77
   * fail early if that happens. */
78
0
  if (mpz_size (key->q) + mpz_size (key->c) < mpz_size(key->p))
79
0
    return 0;
80
81
  /* The size of the product is the sum of the sizes of the factors,
82
   * or sometimes one less. It's possible but tricky to compute the
83
   * size without computing the full product. */
84
85
0
  mpz_init(n);
86
0
  mpz_mul(n, key->p, key->q);
87
88
0
  key->size = _rsa_check_size(n);
89
90
0
  mpz_clear(n);
91
92
0
  return (key->size > 0);
93
0
}
94
95
#if NETTLE_USE_MINI_GMP
96
97
/* Computing an rsa root. */
98
void
99
rsa_compute_root(const struct rsa_private_key *key,
100
     mpz_t x, const mpz_t m)
101
0
{
102
0
  mpz_t xp; /* modulo p */
103
0
  mpz_t xq; /* modulo q */
104
105
0
  mpz_init(xp); mpz_init(xq);    
106
107
  /* Compute xq = m^d % q = (m%q)^b % q */
108
0
  mpz_fdiv_r(xq, m, key->q);
109
0
  mpz_powm_sec(xq, xq, key->b, key->q);
110
111
  /* Compute xp = m^d % p = (m%p)^a % p */
112
0
  mpz_fdiv_r(xp, m, key->p);
113
0
  mpz_powm_sec(xp, xp, key->a, key->p);
114
115
  /* Set xp' = (xp - xq) c % p. */
116
0
  mpz_sub(xp, xp, xq);
117
0
  mpz_mul(xp, xp, key->c);
118
0
  mpz_fdiv_r(xp, xp, key->p);
119
120
  /* Finally, compute x = xq + q xp'
121
   *
122
   * To prove that this works, note that
123
   *
124
   *   xp  = x + i p,
125
   *   xq  = x + j q,
126
   *   c q = 1 + k p
127
   *
128
   * for some integers i, j and k. Now, for some integer l,
129
   *
130
   *   xp' = (xp - xq) c + l p
131
   *       = (x + i p - (x + j q)) c + l p
132
   *       = (i p - j q) c + l p
133
   *       = (i c + l) p - j (c q)
134
   *       = (i c + l) p - j (1 + kp)
135
   *       = (i c + l - j k) p - j
136
   *
137
   * which shows that xp' = -j (mod p). We get
138
   *
139
   *   xq + q xp' = x + j q + (i c + l - j k) p q - j q
140
   *              = x + (i c + l - j k) p q
141
   *
142
   * so that
143
   *
144
   *   xq + q xp' = x (mod pq)
145
   *
146
   * We also get 0 <= xq + q xp' < p q, because
147
   *
148
   *   0 <= xq < q and 0 <= xp' < p.
149
   */
150
0
  mpz_mul(x, key->q, xp);
151
0
  mpz_add(x, x, xq);
152
153
0
  mpz_clear(xp); mpz_clear(xq);
154
0
}
155
156
#else /* !NETTLE_USE_MINI_GMP */
157
158
/* Computing an rsa root. */
159
void
160
rsa_compute_root(const struct rsa_private_key *key,
161
     mpz_t x, const mpz_t m)
162
{
163
  TMP_GMP_DECL (scratch, mp_limb_t);
164
  TMP_GMP_DECL (ml, mp_limb_t);
165
  mp_limb_t *xl;
166
  size_t key_size;
167
168
  key_size = NETTLE_OCTET_SIZE_TO_LIMB_SIZE(key->size);
169
  assert(mpz_size (m) <= key_size);
170
171
  /* we need a copy because m can be shorter than key_size,
172
   * but _rsa_sec_compute_root expect all inputs to be
173
   * normalized to a key_size long buffer length */
174
  TMP_GMP_ALLOC (ml, key_size);
175
  mpz_limbs_copy(ml, m, key_size);
176
177
  TMP_GMP_ALLOC (scratch, _rsa_sec_compute_root_itch(key));
178
179
  xl = mpz_limbs_write (x, key_size);
180
  _rsa_sec_compute_root (key, xl, ml, scratch);
181
  mpz_limbs_finish (x, key_size);
182
183
  TMP_GMP_FREE (ml);
184
  TMP_GMP_FREE (scratch);
185
}
186
#endif /* !NETTLE_USE_MINI_GMP */