Coverage Report

Created: 2025-03-18 06:55

/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
{
102
  mpz_t xp; /* modulo p */
103
  mpz_t xq; /* modulo q */
104
105
  mpz_init(xp); mpz_init(xq);    
106
107
  /* Compute xq = m^d % q = (m%q)^b % q */
108
  mpz_fdiv_r(xq, m, key->q);
109
  mpz_powm_sec(xq, xq, key->b, key->q);
110
111
  /* Compute xp = m^d % p = (m%p)^a % p */
112
  mpz_fdiv_r(xp, m, key->p);
113
  mpz_powm_sec(xp, xp, key->a, key->p);
114
115
  /* Set xp' = (xp - xq) c % p. */
116
  mpz_sub(xp, xp, xq);
117
  mpz_mul(xp, xp, key->c);
118
  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
  mpz_mul(x, key->q, xp);
151
  mpz_add(x, x, xq);
152
153
  mpz_clear(xp); mpz_clear(xq);
154
}
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
0
{
163
0
  TMP_GMP_DECL (scratch, mp_limb_t);
164
0
  TMP_GMP_DECL (ml, mp_limb_t);
165
0
  mp_limb_t *xl;
166
0
  size_t key_size;
167
168
0
  key_size = NETTLE_OCTET_SIZE_TO_LIMB_SIZE(key->size);
169
0
  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
0
  TMP_GMP_ALLOC (ml, key_size);
175
0
  mpz_limbs_copy(ml, m, key_size);
176
177
0
  TMP_GMP_ALLOC (scratch, _rsa_sec_compute_root_itch(key));
178
179
0
  xl = mpz_limbs_write (x, key_size);
180
0
  _rsa_sec_compute_root (key, xl, ml, scratch);
181
0
  mpz_limbs_finish (x, key_size);
182
183
0
  TMP_GMP_FREE (ml);
184
0
  TMP_GMP_FREE (scratch);
185
0
}
186
#endif /* !NETTLE_USE_MINI_GMP */