/src/libgcrypt/cipher/rsa.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* rsa.c - RSA implementation |
2 | | * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn) |
3 | | * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc. |
4 | | * |
5 | | * This file is part of Libgcrypt. |
6 | | * |
7 | | * Libgcrypt is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as |
9 | | * published by the Free Software Foundation; either version 2.1 of |
10 | | * the License, or (at your option) any later version. |
11 | | * |
12 | | * Libgcrypt is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with this program; if not, see <http://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | /* This code uses an algorithm protected by U.S. Patent #4,405,829 |
22 | | which expired on September 20, 2000. The patent holder placed that |
23 | | patent into the public domain on Sep 6th, 2000. |
24 | | */ |
25 | | |
26 | | #include <config.h> |
27 | | #include <stdio.h> |
28 | | #include <stdlib.h> |
29 | | #include <string.h> |
30 | | #include <errno.h> |
31 | | |
32 | | #include "g10lib.h" |
33 | | #include "mpi.h" |
34 | | #include "cipher.h" |
35 | | #include "pubkey-internal.h" |
36 | | |
37 | | |
38 | | typedef struct |
39 | | { |
40 | | gcry_mpi_t n; /* modulus */ |
41 | | gcry_mpi_t e; /* exponent */ |
42 | | } RSA_public_key; |
43 | | |
44 | | |
45 | | typedef struct |
46 | | { |
47 | | gcry_mpi_t n; /* public modulus */ |
48 | | gcry_mpi_t e; /* public exponent */ |
49 | | gcry_mpi_t d; /* exponent */ |
50 | | gcry_mpi_t p; /* prime p. */ |
51 | | gcry_mpi_t q; /* prime q. */ |
52 | | gcry_mpi_t u; /* inverse of p mod q. */ |
53 | | } RSA_secret_key; |
54 | | |
55 | | |
56 | | static const char *rsa_names[] = |
57 | | { |
58 | | "rsa", |
59 | | "openpgp-rsa", |
60 | | "oid.1.2.840.113549.1.1.1", |
61 | | NULL, |
62 | | }; |
63 | | |
64 | | |
65 | | /* A sample 2048 bit RSA key used for the selftests. */ |
66 | | static const char sample_secret_key[] = |
67 | | " (private-key" |
68 | | " (rsa" |
69 | | " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" |
70 | | " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" |
71 | | " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" |
72 | | " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" |
73 | | " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" |
74 | | " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" |
75 | | " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" |
76 | | " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6CB#)" |
77 | | " (e #010001#)" |
78 | | " (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19" |
79 | | " 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93" |
80 | | " 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12" |
81 | | " 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F" |
82 | | " 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48" |
83 | | " EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD" |
84 | | " 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84" |
85 | | " 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401#)" |
86 | | " (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0" |
87 | | " 79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B" |
88 | | " 441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF" |
89 | | " 54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F1783#)" |
90 | | " (q #00D1984135231CB243FE959C0CBEF551EDD986AD7BEDF71EDF447BE3DA27AF46" |
91 | | " 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77" |
92 | | " 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E" |
93 | | " 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B919#)" |
94 | | " (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04" |
95 | | " 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4" |
96 | | " A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9" |
97 | | " AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7#)))"; |
98 | | |
99 | | /* A sample 2048 bit RSA key used for the selftests (public only). */ |
100 | | static const char sample_public_key[] = |
101 | | " (public-key" |
102 | | " (rsa" |
103 | | " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" |
104 | | " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" |
105 | | " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" |
106 | | " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" |
107 | | " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" |
108 | | " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" |
109 | | " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" |
110 | | " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6CB#)" |
111 | | " (e #010001#)))"; |
112 | | |
113 | | |
114 | | static int test_keys (RSA_secret_key *sk, unsigned nbits); |
115 | | static int check_secret_key (RSA_secret_key *sk); |
116 | | static void public (gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *skey); |
117 | | static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey); |
118 | | static unsigned int rsa_get_nbits (gcry_sexp_t parms); |
119 | | |
120 | | |
121 | | /* Check that a freshly generated key actually works. Returns 0 on success. */ |
122 | | static int |
123 | | test_keys (RSA_secret_key *sk, unsigned int nbits) |
124 | 0 | { |
125 | 0 | int result = -1; /* Default to failure. */ |
126 | 0 | RSA_public_key pk; |
127 | 0 | gcry_mpi_t plaintext = mpi_new (nbits); |
128 | 0 | gcry_mpi_t ciphertext = mpi_new (nbits); |
129 | 0 | gcry_mpi_t decr_plaintext = mpi_new (nbits); |
130 | 0 | gcry_mpi_t signature = mpi_new (nbits); |
131 | | |
132 | | /* Put the relevant parameters into a public key structure. */ |
133 | 0 | pk.n = sk->n; |
134 | 0 | pk.e = sk->e; |
135 | | |
136 | | /* Create a random plaintext. */ |
137 | 0 | _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM); |
138 | | |
139 | | /* Encrypt using the public key. */ |
140 | 0 | public (ciphertext, plaintext, &pk); |
141 | | |
142 | | /* Check that the cipher text does not match the plaintext. */ |
143 | 0 | if (!mpi_cmp (ciphertext, plaintext)) |
144 | 0 | goto leave; /* Ciphertext is identical to the plaintext. */ |
145 | | |
146 | | /* Decrypt using the secret key. */ |
147 | 0 | secret (decr_plaintext, ciphertext, sk); |
148 | | |
149 | | /* Check that the decrypted plaintext matches the original plaintext. */ |
150 | 0 | if (mpi_cmp (decr_plaintext, plaintext)) |
151 | 0 | goto leave; /* Plaintext does not match. */ |
152 | | |
153 | | /* Create another random plaintext as data for signature checking. */ |
154 | 0 | _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM); |
155 | | |
156 | | /* Use the RSA secret function to create a signature of the plaintext. */ |
157 | 0 | secret (signature, plaintext, sk); |
158 | | |
159 | | /* Use the RSA public function to verify this signature. */ |
160 | 0 | public (decr_plaintext, signature, &pk); |
161 | 0 | if (mpi_cmp (decr_plaintext, plaintext)) |
162 | 0 | goto leave; /* Signature does not match. */ |
163 | | |
164 | | /* Modify the signature and check that the signing fails. */ |
165 | 0 | mpi_add_ui (signature, signature, 1); |
166 | 0 | public (decr_plaintext, signature, &pk); |
167 | 0 | if (!mpi_cmp (decr_plaintext, plaintext)) |
168 | 0 | goto leave; /* Signature matches but should not. */ |
169 | | |
170 | 0 | result = 0; /* All tests succeeded. */ |
171 | |
|
172 | 0 | leave: |
173 | 0 | _gcry_mpi_release (signature); |
174 | 0 | _gcry_mpi_release (decr_plaintext); |
175 | 0 | _gcry_mpi_release (ciphertext); |
176 | 0 | _gcry_mpi_release (plaintext); |
177 | 0 | return result; |
178 | 0 | } |
179 | | |
180 | | static int |
181 | | test_keys_fips (gcry_sexp_t skey) |
182 | 0 | { |
183 | 0 | int result = -1; /* Default to failure. */ |
184 | 0 | char plaintext[128]; |
185 | 0 | gcry_sexp_t sig = NULL; |
186 | 0 | const char *data_tmpl = "(data (flags pkcs1) (hash %s %b))"; |
187 | 0 | gcry_md_hd_t hd = NULL; |
188 | 0 | int ec; |
189 | | |
190 | | /* Create a random plaintext. */ |
191 | 0 | _gcry_randomize (plaintext, sizeof plaintext, GCRY_WEAK_RANDOM); |
192 | | |
193 | | /* Open MD context and feed the random data in */ |
194 | 0 | ec = _gcry_md_open (&hd, GCRY_MD_SHA256, 0); |
195 | 0 | if (ec) |
196 | 0 | goto leave; |
197 | 0 | _gcry_md_write (hd, plaintext, sizeof(plaintext)); |
198 | | |
199 | | /* Use the RSA secret function to create a signature of the plaintext. */ |
200 | 0 | ec = _gcry_pk_sign_md (&sig, data_tmpl, hd, skey, NULL); |
201 | 0 | if (ec) |
202 | 0 | goto leave; |
203 | | |
204 | | /* Use the RSA public function to verify this signature. */ |
205 | 0 | ec = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL); |
206 | 0 | if (ec) |
207 | 0 | goto leave; |
208 | | |
209 | | /* Modify the data and check that the signing fails. */ |
210 | 0 | _gcry_md_reset(hd); |
211 | 0 | plaintext[sizeof plaintext / 2] ^= 1; |
212 | 0 | _gcry_md_write (hd, plaintext, sizeof(plaintext)); |
213 | 0 | ec = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL); |
214 | 0 | if (ec != GPG_ERR_BAD_SIGNATURE) |
215 | 0 | goto leave; /* Signature verification worked on modified data */ |
216 | | |
217 | 0 | result = 0; /* All tests succeeded. */ |
218 | 0 | leave: |
219 | 0 | sexp_release (sig); |
220 | 0 | _gcry_md_close (hd); |
221 | 0 | return result; |
222 | 0 | } |
223 | | |
224 | | /* Callback used by the prime generation to test whether the exponent |
225 | | is suitable. Returns 0 if the test has been passed. */ |
226 | | static int |
227 | | check_exponent (void *arg, gcry_mpi_t a) |
228 | 0 | { |
229 | 0 | gcry_mpi_t e = arg; |
230 | 0 | gcry_mpi_t tmp; |
231 | 0 | int result; |
232 | |
|
233 | 0 | mpi_sub_ui (a, a, 1); |
234 | 0 | tmp = _gcry_mpi_alloc_like (a); |
235 | 0 | result = !mpi_gcd(tmp, e, a); /* GCD is not 1. */ |
236 | 0 | _gcry_mpi_release (tmp); |
237 | 0 | mpi_add_ui (a, a, 1); |
238 | 0 | return result; |
239 | 0 | } |
240 | | |
241 | | /**************** |
242 | | * Generate a key pair with a key of size NBITS. |
243 | | * USE_E = 0 let Libcgrypt decide what exponent to use. |
244 | | * = 1 request the use of a "secure" exponent; this is required by some |
245 | | * specification to be 65537. |
246 | | * > 2 Use this public exponent. If the given exponent |
247 | | * is not odd one is internally added to it. |
248 | | * TRANSIENT_KEY: If true, generate the primes using the standard RNG. |
249 | | * Returns: 2 structures filled with all needed values |
250 | | */ |
251 | | static gpg_err_code_t |
252 | | generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, |
253 | | int transient_key) |
254 | 0 | { |
255 | 0 | gcry_mpi_t p, q; /* the two primes */ |
256 | 0 | gcry_mpi_t d; /* the private key */ |
257 | 0 | gcry_mpi_t u; |
258 | 0 | gcry_mpi_t t1, t2; |
259 | 0 | gcry_mpi_t n; /* the public key */ |
260 | 0 | gcry_mpi_t e; /* the exponent */ |
261 | 0 | gcry_mpi_t phi; /* helper: (p-1)(q-1) */ |
262 | 0 | gcry_mpi_t g; |
263 | 0 | gcry_mpi_t f; |
264 | 0 | gcry_random_level_t random_level; |
265 | | |
266 | | /* The random quality depends on the transient_key flag. */ |
267 | 0 | random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; |
268 | | |
269 | | /* Make sure that nbits is even so that we generate p, q of equal size. */ |
270 | 0 | if ( (nbits&1) ) |
271 | 0 | nbits++; |
272 | |
|
273 | 0 | if (use_e == 1) /* Alias for a secure value */ |
274 | 0 | use_e = 65537; /* as demanded by Sphinx. */ |
275 | | |
276 | | /* Public exponent: |
277 | | In general we use 41 as this is quite fast and more secure than the |
278 | | commonly used 17. Benchmarking the RSA verify function |
279 | | with a 1024 bit key yields (2001-11-08): |
280 | | e=17 0.54 ms |
281 | | e=41 0.75 ms |
282 | | e=257 0.95 ms |
283 | | e=65537 1.80 ms |
284 | | */ |
285 | 0 | e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB ); |
286 | 0 | if (!use_e) |
287 | 0 | mpi_set_ui (e, 41); /* This is a reasonable secure and fast value */ |
288 | 0 | else |
289 | 0 | { |
290 | 0 | use_e |= 1; /* make sure this is odd */ |
291 | 0 | mpi_set_ui (e, use_e); |
292 | 0 | } |
293 | |
|
294 | 0 | n = mpi_new (nbits); |
295 | |
|
296 | 0 | p = q = NULL; |
297 | 0 | do |
298 | 0 | { |
299 | | /* select two (very secret) primes */ |
300 | 0 | if (p) |
301 | 0 | _gcry_mpi_release (p); |
302 | 0 | if (q) |
303 | 0 | _gcry_mpi_release (q); |
304 | 0 | if (use_e) |
305 | 0 | { /* Do an extra test to ensure that the given exponent is |
306 | | suitable. */ |
307 | 0 | p = _gcry_generate_secret_prime (nbits/2, random_level, |
308 | 0 | check_exponent, e); |
309 | 0 | q = _gcry_generate_secret_prime (nbits/2, random_level, |
310 | 0 | check_exponent, e); |
311 | 0 | } |
312 | 0 | else |
313 | 0 | { /* We check the exponent later. */ |
314 | 0 | p = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL); |
315 | 0 | q = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL); |
316 | 0 | } |
317 | 0 | if (mpi_cmp (p, q) > 0 ) /* p shall be smaller than q (for calc of u)*/ |
318 | 0 | mpi_swap(p,q); |
319 | | /* calculate the modulus */ |
320 | 0 | mpi_mul( n, p, q ); |
321 | 0 | } |
322 | 0 | while ( mpi_get_nbits(n) != nbits ); |
323 | | |
324 | | /* calculate Euler totient: phi = (p-1)(q-1) */ |
325 | 0 | t1 = mpi_alloc_secure( mpi_get_nlimbs(p) ); |
326 | 0 | t2 = mpi_alloc_secure( mpi_get_nlimbs(p) ); |
327 | 0 | phi = mpi_snew ( nbits ); |
328 | 0 | g = mpi_snew ( nbits ); |
329 | 0 | f = mpi_snew ( nbits ); |
330 | 0 | mpi_sub_ui( t1, p, 1 ); |
331 | 0 | mpi_sub_ui( t2, q, 1 ); |
332 | 0 | mpi_mul( phi, t1, t2 ); |
333 | 0 | mpi_gcd (g, t1, t2); |
334 | 0 | mpi_fdiv_q(f, phi, g); |
335 | |
|
336 | 0 | while (!mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */ |
337 | 0 | { |
338 | 0 | if (use_e) |
339 | 0 | BUG (); /* The prime generator already made sure that we |
340 | | never can get to here. */ |
341 | 0 | mpi_add_ui (e, e, 2); |
342 | 0 | } |
343 | | |
344 | | /* calculate the secret key d = e^-1 mod phi */ |
345 | 0 | d = mpi_snew ( nbits ); |
346 | 0 | mpi_invm (d, e, f ); |
347 | | /* calculate the inverse of p and q (used for chinese remainder theorem)*/ |
348 | 0 | u = mpi_snew ( nbits ); |
349 | 0 | mpi_invm(u, p, q ); |
350 | |
|
351 | 0 | if( DBG_CIPHER ) |
352 | 0 | { |
353 | 0 | log_mpidump(" p= ", p ); |
354 | 0 | log_mpidump(" q= ", q ); |
355 | 0 | log_mpidump("phi= ", phi ); |
356 | 0 | log_mpidump(" g= ", g ); |
357 | 0 | log_mpidump(" f= ", f ); |
358 | 0 | log_mpidump(" n= ", n ); |
359 | 0 | log_mpidump(" e= ", e ); |
360 | 0 | log_mpidump(" d= ", d ); |
361 | 0 | log_mpidump(" u= ", u ); |
362 | 0 | } |
363 | |
|
364 | 0 | _gcry_mpi_release (t1); |
365 | 0 | _gcry_mpi_release (t2); |
366 | 0 | _gcry_mpi_release (phi); |
367 | 0 | _gcry_mpi_release (f); |
368 | 0 | _gcry_mpi_release (g); |
369 | |
|
370 | 0 | sk->n = n; |
371 | 0 | sk->e = e; |
372 | 0 | sk->p = p; |
373 | 0 | sk->q = q; |
374 | 0 | sk->d = d; |
375 | 0 | sk->u = u; |
376 | | |
377 | | /* Now we can test our keys. */ |
378 | 0 | if (test_keys (sk, nbits - 64)) |
379 | 0 | { |
380 | 0 | _gcry_mpi_release (sk->n); sk->n = NULL; |
381 | 0 | _gcry_mpi_release (sk->e); sk->e = NULL; |
382 | 0 | _gcry_mpi_release (sk->p); sk->p = NULL; |
383 | 0 | _gcry_mpi_release (sk->q); sk->q = NULL; |
384 | 0 | _gcry_mpi_release (sk->d); sk->d = NULL; |
385 | 0 | _gcry_mpi_release (sk->u); sk->u = NULL; |
386 | 0 | fips_signal_error ("self-test after key generation failed"); |
387 | 0 | return GPG_ERR_SELFTEST_FAILED; |
388 | 0 | } |
389 | | |
390 | 0 | return 0; |
391 | 0 | } |
392 | | |
393 | | |
394 | | /* Check the RSA key length is acceptable for key generation or usage */ |
395 | | static gpg_err_code_t |
396 | | rsa_check_keysize (unsigned int nbits) |
397 | 0 | { |
398 | 0 | if (fips_mode () && nbits < 2048) |
399 | 0 | return GPG_ERR_INV_VALUE; |
400 | | |
401 | 0 | return GPG_ERR_NO_ERROR; |
402 | 0 | } |
403 | | |
404 | | |
405 | | /* Check the RSA key length is acceptable for signature verification |
406 | | * |
407 | | * FIPS allows signature verification with RSA keys of size |
408 | | * 1024, 1280, 1536 and 1792 in legacy mode, but this is up to the |
409 | | * calling application to decide if the signature is legacy and |
410 | | * should be accepted. |
411 | | */ |
412 | | static gpg_err_code_t |
413 | | rsa_check_verify_keysize (unsigned int nbits) |
414 | 0 | { |
415 | 0 | if (fips_mode ()) |
416 | 0 | { |
417 | 0 | if ((nbits >= 1024 && (nbits % 256) == 0) || nbits >= 2048) |
418 | 0 | return GPG_ERR_NO_ERROR; |
419 | | |
420 | 0 | return GPG_ERR_INV_VALUE; |
421 | 0 | } |
422 | | |
423 | 0 | return GPG_ERR_NO_ERROR; |
424 | 0 | } |
425 | | |
426 | | |
427 | | /**************** |
428 | | * Generate a key pair with a key of size NBITS. |
429 | | * USE_E = 0 let Libcgrypt decide what exponent to use. |
430 | | * = 1 request the use of a "secure" exponent; this is required by some |
431 | | * specification to be 65537. |
432 | | * > 2 Use this public exponent. If the given exponent |
433 | | * is not odd one is internally added to it. |
434 | | * TESTPARMS: If set, do not generate but test whether the p,q is probably prime |
435 | | * Returns key with zeroes to not break code calling this function. |
436 | | * TRANSIENT_KEY: If true, generate the primes using the standard RNG. |
437 | | * Returns: 2 structures filled with all needed values |
438 | | */ |
439 | | static gpg_err_code_t |
440 | | generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, |
441 | | gcry_sexp_t testparms, int transient_key) |
442 | 0 | { |
443 | 0 | gcry_mpi_t p, q; /* the two primes */ |
444 | 0 | gcry_mpi_t d; /* the private key */ |
445 | 0 | gcry_mpi_t u; |
446 | 0 | gcry_mpi_t p1, q1; |
447 | 0 | gcry_mpi_t n; /* the public key */ |
448 | 0 | gcry_mpi_t e; /* the exponent */ |
449 | 0 | gcry_mpi_t g; |
450 | 0 | gcry_mpi_t minp; |
451 | 0 | gcry_mpi_t diff, mindiff; |
452 | 0 | gcry_random_level_t random_level; |
453 | 0 | unsigned int pbits = nbits/2; |
454 | 0 | unsigned int i; |
455 | 0 | int pqswitch; |
456 | 0 | gpg_err_code_t ec; |
457 | |
|
458 | 0 | if (nbits <= 1024 || (nbits & 0x1FF)) |
459 | 0 | return GPG_ERR_INV_VALUE; |
460 | 0 | ec = rsa_check_keysize (nbits); |
461 | 0 | if (ec) |
462 | 0 | return ec; |
463 | | |
464 | | /* Set default error code. */ |
465 | 0 | ec = GPG_ERR_NO_PRIME; |
466 | | |
467 | | /* The random quality depends on the transient_key flag. */ |
468 | 0 | random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; |
469 | |
|
470 | 0 | if (testparms) |
471 | 0 | { |
472 | | /* Parameters to derive the key are given. */ |
473 | | /* Note that we explicitly need to setup the values of tbl |
474 | | because some compilers (e.g. OpenWatcom, IRIX) don't allow to |
475 | | initialize a structure with automatic variables. */ |
476 | 0 | struct { const char *name; gcry_mpi_t *value; } tbl[] = { |
477 | 0 | { "e" }, |
478 | 0 | { "p" }, |
479 | 0 | { "q" }, |
480 | 0 | { NULL } |
481 | 0 | }; |
482 | 0 | int idx; |
483 | 0 | gcry_sexp_t oneparm; |
484 | |
|
485 | 0 | tbl[0].value = &e; |
486 | 0 | tbl[1].value = &p; |
487 | 0 | tbl[2].value = &q; |
488 | |
|
489 | 0 | for (idx=0; tbl[idx].name; idx++) |
490 | 0 | { |
491 | 0 | oneparm = sexp_find_token (testparms, tbl[idx].name, 0); |
492 | 0 | if (oneparm) |
493 | 0 | { |
494 | 0 | *tbl[idx].value = sexp_nth_mpi (oneparm, 1, GCRYMPI_FMT_USG); |
495 | 0 | sexp_release (oneparm); |
496 | 0 | } |
497 | 0 | } |
498 | 0 | for (idx=0; tbl[idx].name; idx++) |
499 | 0 | if (!*tbl[idx].value) |
500 | 0 | break; |
501 | 0 | if (tbl[idx].name) |
502 | 0 | { |
503 | | /* At least one parameter is missing. */ |
504 | 0 | for (idx=0; tbl[idx].name; idx++) |
505 | 0 | _gcry_mpi_release (*tbl[idx].value); |
506 | 0 | return GPG_ERR_MISSING_VALUE; |
507 | 0 | } |
508 | 0 | } |
509 | 0 | else |
510 | 0 | { |
511 | 0 | if (use_e < 65537) |
512 | 0 | use_e = 65537; /* This is the smallest value allowed by FIPS */ |
513 | |
|
514 | 0 | e = mpi_alloc ((32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB); |
515 | |
|
516 | 0 | use_e |= 1; /* make sure this is odd */ |
517 | 0 | mpi_set_ui (e, use_e); |
518 | |
|
519 | 0 | p = mpi_snew (pbits); |
520 | 0 | q = mpi_snew (pbits); |
521 | 0 | } |
522 | | |
523 | 0 | n = mpi_new (nbits); |
524 | 0 | d = mpi_snew (nbits); |
525 | 0 | u = mpi_snew (nbits); |
526 | | |
527 | | /* prepare approximate minimum p and q */ |
528 | 0 | minp = mpi_new (pbits); |
529 | 0 | mpi_set_ui (minp, 0xB504F334); |
530 | 0 | mpi_lshift (minp, minp, pbits - 32); |
531 | | |
532 | | /* prepare minimum p and q difference */ |
533 | 0 | diff = mpi_new (pbits); |
534 | 0 | mindiff = mpi_new (pbits - 99); |
535 | 0 | mpi_set_ui (mindiff, 1); |
536 | 0 | mpi_lshift (mindiff, mindiff, pbits - 100); |
537 | |
|
538 | 0 | p1 = mpi_snew (pbits); |
539 | 0 | q1 = mpi_snew (pbits); |
540 | 0 | g = mpi_snew (pbits); |
541 | |
|
542 | 0 | retry: |
543 | | /* generate p and q */ |
544 | 0 | for (i = 0; i < 10 * pbits; i++) |
545 | 0 | { |
546 | 0 | ploop: |
547 | 0 | if (!testparms) |
548 | 0 | { |
549 | 0 | _gcry_mpi_randomize (p, pbits, random_level); |
550 | 0 | mpi_set_bit (p, 0); |
551 | 0 | } |
552 | 0 | if (mpi_cmp (p, minp) < 0) |
553 | 0 | { |
554 | 0 | if (testparms) |
555 | 0 | goto err; |
556 | 0 | goto ploop; |
557 | 0 | } |
558 | | |
559 | 0 | mpi_sub_ui (p1, p, 1); |
560 | 0 | if (mpi_gcd (g, p1, e)) |
561 | 0 | { |
562 | 0 | if (_gcry_fips186_4_prime_check (p, pbits) != GPG_ERR_NO_ERROR) |
563 | 0 | { |
564 | | /* not a prime */ |
565 | 0 | if (testparms) |
566 | 0 | goto err; |
567 | 0 | } |
568 | 0 | else |
569 | 0 | break; |
570 | 0 | } |
571 | 0 | else if (testparms) |
572 | 0 | goto err; |
573 | 0 | } |
574 | 0 | if (i >= 10 * pbits) |
575 | 0 | goto err; |
576 | | |
577 | 0 | for (i = 0; i < 20 * pbits; i++) |
578 | 0 | { |
579 | 0 | qloop: |
580 | 0 | if (!testparms) |
581 | 0 | { |
582 | 0 | _gcry_mpi_randomize (q, pbits, random_level); |
583 | 0 | mpi_set_bit (q, 0); |
584 | 0 | } |
585 | 0 | if (mpi_cmp (q, minp) < 0) |
586 | 0 | { |
587 | 0 | if (testparms) |
588 | 0 | goto err; |
589 | 0 | goto qloop; |
590 | 0 | } |
591 | 0 | if (mpi_cmp (p, q) > 0) |
592 | 0 | { |
593 | 0 | pqswitch = 1; |
594 | 0 | mpi_sub (diff, p, q); |
595 | 0 | } |
596 | 0 | else |
597 | 0 | { |
598 | 0 | pqswitch = 0; |
599 | 0 | mpi_sub (diff, q, p); |
600 | 0 | } |
601 | 0 | if (mpi_cmp (diff, mindiff) < 0) |
602 | 0 | { |
603 | 0 | if (testparms) |
604 | 0 | goto err; |
605 | 0 | goto qloop; |
606 | 0 | } |
607 | | |
608 | 0 | mpi_sub_ui (q1, q, 1); |
609 | 0 | if (mpi_gcd (g, q1, e)) |
610 | 0 | { |
611 | 0 | if (_gcry_fips186_4_prime_check (q, pbits) != GPG_ERR_NO_ERROR) |
612 | 0 | { |
613 | | /* not a prime */ |
614 | 0 | if (testparms) |
615 | 0 | goto err; |
616 | 0 | } |
617 | 0 | else |
618 | 0 | break; |
619 | 0 | } |
620 | 0 | else if (testparms) |
621 | 0 | goto err; |
622 | 0 | } |
623 | 0 | if (i >= 20 * pbits) |
624 | 0 | goto err; |
625 | | |
626 | 0 | if (testparms) |
627 | 0 | { |
628 | 0 | mpi_clear (p); |
629 | 0 | mpi_clear (q); |
630 | 0 | } |
631 | 0 | else |
632 | 0 | { |
633 | 0 | gcry_mpi_t f; |
634 | |
|
635 | 0 | if (pqswitch) |
636 | 0 | { |
637 | 0 | gcry_mpi_t tmp; |
638 | |
|
639 | 0 | tmp = p; |
640 | 0 | p = q; |
641 | 0 | q = tmp; |
642 | 0 | } |
643 | |
|
644 | 0 | f = mpi_snew (nbits); |
645 | | |
646 | | /* calculate the modulus */ |
647 | 0 | mpi_mul (n, p, q); |
648 | | |
649 | | /* calculate the secret key d = e^1 mod phi */ |
650 | 0 | mpi_gcd (g, p1, q1); |
651 | 0 | mpi_fdiv_q (f, p1, g); |
652 | 0 | mpi_mul (f, f, q1); |
653 | |
|
654 | 0 | mpi_invm (d, e, f); |
655 | |
|
656 | 0 | _gcry_mpi_release (f); |
657 | |
|
658 | 0 | if (mpi_get_nbits (d) < pbits) |
659 | 0 | goto retry; |
660 | | |
661 | | /* calculate the inverse of p and q (used for chinese remainder theorem)*/ |
662 | 0 | mpi_invm (u, p, q ); |
663 | 0 | } |
664 | | |
665 | 0 | ec = 0; /* Success. */ |
666 | |
|
667 | 0 | if (DBG_CIPHER) |
668 | 0 | { |
669 | 0 | log_mpidump(" p= ", p ); |
670 | 0 | log_mpidump(" q= ", q ); |
671 | 0 | log_mpidump(" n= ", n ); |
672 | 0 | log_mpidump(" e= ", e ); |
673 | 0 | log_mpidump(" d= ", d ); |
674 | 0 | log_mpidump(" u= ", u ); |
675 | 0 | } |
676 | |
|
677 | 0 | err: |
678 | |
|
679 | 0 | _gcry_mpi_release (p1); |
680 | 0 | _gcry_mpi_release (q1); |
681 | 0 | _gcry_mpi_release (g); |
682 | 0 | _gcry_mpi_release (minp); |
683 | 0 | _gcry_mpi_release (mindiff); |
684 | 0 | _gcry_mpi_release (diff); |
685 | |
|
686 | 0 | sk->n = n; |
687 | 0 | sk->e = e; |
688 | 0 | sk->p = p; |
689 | 0 | sk->q = q; |
690 | 0 | sk->d = d; |
691 | 0 | sk->u = u; |
692 | |
|
693 | 0 | if (ec) |
694 | 0 | { |
695 | 0 | _gcry_mpi_release (sk->n); sk->n = NULL; |
696 | 0 | _gcry_mpi_release (sk->e); sk->e = NULL; |
697 | 0 | _gcry_mpi_release (sk->p); sk->p = NULL; |
698 | 0 | _gcry_mpi_release (sk->q); sk->q = NULL; |
699 | 0 | _gcry_mpi_release (sk->d); sk->d = NULL; |
700 | 0 | _gcry_mpi_release (sk->u); sk->u = NULL; |
701 | 0 | } |
702 | |
|
703 | 0 | return ec; |
704 | 0 | } |
705 | | |
706 | | |
707 | | /* Helper for generate_x931. */ |
708 | | static gcry_mpi_t |
709 | | gen_x931_parm_xp (unsigned int nbits) |
710 | 0 | { |
711 | 0 | gcry_mpi_t xp; |
712 | |
|
713 | 0 | xp = mpi_snew (nbits); |
714 | 0 | _gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM); |
715 | | |
716 | | /* The requirement for Xp is: |
717 | | |
718 | | sqrt{2}*2^{nbits-1} <= xp <= 2^{nbits} - 1 |
719 | | |
720 | | We set the two high order bits to 1 to satisfy the lower bound. |
721 | | By using mpi_set_highbit we make sure that the upper bound is |
722 | | satisfied as well. */ |
723 | 0 | mpi_set_highbit (xp, nbits-1); |
724 | 0 | mpi_set_bit (xp, nbits-2); |
725 | 0 | gcry_assert ( mpi_get_nbits (xp) == nbits ); |
726 | | |
727 | 0 | return xp; |
728 | 0 | } |
729 | | |
730 | | |
731 | | /* Helper for generate_x931. */ |
732 | | static gcry_mpi_t |
733 | | gen_x931_parm_xi (void) |
734 | 0 | { |
735 | 0 | gcry_mpi_t xi; |
736 | |
|
737 | 0 | xi = mpi_snew (101); |
738 | 0 | _gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM); |
739 | 0 | mpi_set_highbit (xi, 100); |
740 | 0 | gcry_assert ( mpi_get_nbits (xi) == 101 ); |
741 | | |
742 | 0 | return xi; |
743 | 0 | } |
744 | | |
745 | | |
746 | | |
747 | | /* Variant of the standard key generation code using the algorithm |
748 | | from X9.31. Using this algorithm has the advantage that the |
749 | | generation can be made deterministic which is required for CAVS |
750 | | testing. */ |
751 | | static gpg_err_code_t |
752 | | generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value, |
753 | | gcry_sexp_t deriveparms, int *swapped) |
754 | 0 | { |
755 | 0 | gcry_mpi_t p, q; /* The two primes. */ |
756 | 0 | gcry_mpi_t e; /* The public exponent. */ |
757 | 0 | gcry_mpi_t n; /* The public key. */ |
758 | 0 | gcry_mpi_t d; /* The private key */ |
759 | 0 | gcry_mpi_t u; /* The inverse of p and q. */ |
760 | 0 | gcry_mpi_t pm1; /* p - 1 */ |
761 | 0 | gcry_mpi_t qm1; /* q - 1 */ |
762 | 0 | gcry_mpi_t phi; /* Euler totient. */ |
763 | 0 | gcry_mpi_t f, g; /* Helper. */ |
764 | |
|
765 | 0 | *swapped = 0; |
766 | |
|
767 | 0 | if (e_value == 0) /* 65537 is the libgcrypt's selection. */ |
768 | 0 | e_value = 65537; |
769 | 0 | else if (e_value == 1) /* Alias for a secure value. */ |
770 | 0 | e_value = 65537; |
771 | | |
772 | | /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ |
773 | 0 | if (nbits < 1024 || (nbits % 256)) |
774 | 0 | return GPG_ERR_INV_VALUE; |
775 | | |
776 | | /* Point 2: 2 <= bitlength(e) < 2^{k-2} |
777 | | Note that we do not need to check the upper bound because we use |
778 | | an unsigned long for E and thus there is no way for E to reach |
779 | | that limit. */ |
780 | 0 | if (e_value < 3) |
781 | 0 | return GPG_ERR_INV_VALUE; |
782 | | |
783 | | /* Our implementation requires E to be odd. */ |
784 | 0 | if (!(e_value & 1)) |
785 | 0 | return GPG_ERR_INV_VALUE; |
786 | | |
787 | | /* Point 3: e > 0 or e 0 if it is to be randomly generated. |
788 | | We support only a fixed E and thus there is no need for an extra test. */ |
789 | | |
790 | | |
791 | | /* Compute or extract the derive parameters. */ |
792 | 0 | { |
793 | 0 | gcry_mpi_t xp1 = NULL; |
794 | 0 | gcry_mpi_t xp2 = NULL; |
795 | 0 | gcry_mpi_t xp = NULL; |
796 | 0 | gcry_mpi_t xq1 = NULL; |
797 | 0 | gcry_mpi_t xq2 = NULL; |
798 | 0 | gcry_mpi_t xq = NULL; |
799 | 0 | gcry_mpi_t tmpval; |
800 | |
|
801 | 0 | if (!deriveparms) |
802 | 0 | { |
803 | | /* Not given: Generate them. */ |
804 | 0 | xp = gen_x931_parm_xp (nbits/2); |
805 | | /* Make sure that |xp - xq| > 2^{nbits - 100} holds. */ |
806 | 0 | tmpval = mpi_snew (nbits/2); |
807 | 0 | do |
808 | 0 | { |
809 | 0 | _gcry_mpi_release (xq); |
810 | 0 | xq = gen_x931_parm_xp (nbits/2); |
811 | 0 | mpi_sub (tmpval, xp, xq); |
812 | 0 | } |
813 | 0 | while (mpi_get_nbits (tmpval) <= (nbits/2 - 100)); |
814 | 0 | _gcry_mpi_release (tmpval); |
815 | |
|
816 | 0 | xp1 = gen_x931_parm_xi (); |
817 | 0 | xp2 = gen_x931_parm_xi (); |
818 | 0 | xq1 = gen_x931_parm_xi (); |
819 | 0 | xq2 = gen_x931_parm_xi (); |
820 | |
|
821 | 0 | } |
822 | 0 | else |
823 | 0 | { |
824 | | /* Parameters to derive the key are given. */ |
825 | | /* Note that we explicitly need to setup the values of tbl |
826 | | because some compilers (e.g. OpenWatcom, IRIX) don't allow |
827 | | to initialize a structure with automatic variables. */ |
828 | 0 | struct { const char *name; gcry_mpi_t *value; } tbl[] = { |
829 | 0 | { "Xp1" }, |
830 | 0 | { "Xp2" }, |
831 | 0 | { "Xp" }, |
832 | 0 | { "Xq1" }, |
833 | 0 | { "Xq2" }, |
834 | 0 | { "Xq" }, |
835 | 0 | { NULL } |
836 | 0 | }; |
837 | 0 | int idx; |
838 | 0 | gcry_sexp_t oneparm; |
839 | |
|
840 | 0 | tbl[0].value = &xp1; |
841 | 0 | tbl[1].value = &xp2; |
842 | 0 | tbl[2].value = &xp; |
843 | 0 | tbl[3].value = &xq1; |
844 | 0 | tbl[4].value = &xq2; |
845 | 0 | tbl[5].value = &xq; |
846 | |
|
847 | 0 | for (idx=0; tbl[idx].name; idx++) |
848 | 0 | { |
849 | 0 | oneparm = sexp_find_token (deriveparms, tbl[idx].name, 0); |
850 | 0 | if (oneparm) |
851 | 0 | { |
852 | 0 | *tbl[idx].value = sexp_nth_mpi (oneparm, 1, GCRYMPI_FMT_USG); |
853 | 0 | sexp_release (oneparm); |
854 | 0 | } |
855 | 0 | } |
856 | 0 | for (idx=0; tbl[idx].name; idx++) |
857 | 0 | if (!*tbl[idx].value) |
858 | 0 | break; |
859 | 0 | if (tbl[idx].name) |
860 | 0 | { |
861 | | /* At least one parameter is missing. */ |
862 | 0 | for (idx=0; tbl[idx].name; idx++) |
863 | 0 | _gcry_mpi_release (*tbl[idx].value); |
864 | 0 | return GPG_ERR_MISSING_VALUE; |
865 | 0 | } |
866 | 0 | } |
867 | | |
868 | 0 | e = mpi_alloc_set_ui (e_value); |
869 | | |
870 | | /* Find two prime numbers. */ |
871 | 0 | p = _gcry_derive_x931_prime (xp, xp1, xp2, e, NULL, NULL); |
872 | 0 | q = _gcry_derive_x931_prime (xq, xq1, xq2, e, NULL, NULL); |
873 | 0 | _gcry_mpi_release (xp); xp = NULL; |
874 | 0 | _gcry_mpi_release (xp1); xp1 = NULL; |
875 | 0 | _gcry_mpi_release (xp2); xp2 = NULL; |
876 | 0 | _gcry_mpi_release (xq); xq = NULL; |
877 | 0 | _gcry_mpi_release (xq1); xq1 = NULL; |
878 | 0 | _gcry_mpi_release (xq2); xq2 = NULL; |
879 | 0 | if (!p || !q) |
880 | 0 | { |
881 | 0 | _gcry_mpi_release (p); |
882 | 0 | _gcry_mpi_release (q); |
883 | 0 | _gcry_mpi_release (e); |
884 | 0 | return GPG_ERR_NO_PRIME; |
885 | 0 | } |
886 | 0 | } |
887 | | |
888 | | |
889 | | /* Compute the public modulus. We make sure that p is smaller than |
890 | | q to allow the use of the CRT. */ |
891 | 0 | if (mpi_cmp (p, q) > 0 ) |
892 | 0 | { |
893 | 0 | mpi_swap (p, q); |
894 | 0 | *swapped = 1; |
895 | 0 | } |
896 | 0 | n = mpi_new (nbits); |
897 | 0 | mpi_mul (n, p, q); |
898 | | |
899 | | /* Compute the Euler totient: phi = (p-1)(q-1) */ |
900 | 0 | pm1 = mpi_snew (nbits/2); |
901 | 0 | qm1 = mpi_snew (nbits/2); |
902 | 0 | phi = mpi_snew (nbits); |
903 | 0 | mpi_sub_ui (pm1, p, 1); |
904 | 0 | mpi_sub_ui (qm1, q, 1); |
905 | 0 | mpi_mul (phi, pm1, qm1); |
906 | |
|
907 | 0 | g = mpi_snew (nbits); |
908 | 0 | gcry_assert (mpi_gcd (g, e, phi)); |
909 | | |
910 | | /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */ |
911 | 0 | mpi_gcd (g, pm1, qm1); |
912 | 0 | f = pm1; pm1 = NULL; |
913 | 0 | _gcry_mpi_release (qm1); qm1 = NULL; |
914 | 0 | mpi_fdiv_q (f, phi, g); |
915 | 0 | _gcry_mpi_release (phi); phi = NULL; |
916 | 0 | d = g; g = NULL; |
917 | | /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */ |
918 | 0 | mpi_invm (d, e, f); |
919 | | |
920 | | /* Compute the inverse of p and q. */ |
921 | 0 | u = f; f = NULL; |
922 | 0 | mpi_invm (u, p, q ); |
923 | |
|
924 | 0 | if( DBG_CIPHER ) |
925 | 0 | { |
926 | 0 | if (*swapped) |
927 | 0 | log_debug ("p and q are swapped\n"); |
928 | 0 | log_mpidump(" p", p ); |
929 | 0 | log_mpidump(" q", q ); |
930 | 0 | log_mpidump(" n", n ); |
931 | 0 | log_mpidump(" e", e ); |
932 | 0 | log_mpidump(" d", d ); |
933 | 0 | log_mpidump(" u", u ); |
934 | 0 | } |
935 | | |
936 | |
|
937 | 0 | sk->n = n; |
938 | 0 | sk->e = e; |
939 | 0 | sk->p = p; |
940 | 0 | sk->q = q; |
941 | 0 | sk->d = d; |
942 | 0 | sk->u = u; |
943 | | |
944 | | /* Now we can test our keys. */ |
945 | 0 | if (test_keys (sk, nbits - 64)) |
946 | 0 | { |
947 | 0 | _gcry_mpi_release (sk->n); sk->n = NULL; |
948 | 0 | _gcry_mpi_release (sk->e); sk->e = NULL; |
949 | 0 | _gcry_mpi_release (sk->p); sk->p = NULL; |
950 | 0 | _gcry_mpi_release (sk->q); sk->q = NULL; |
951 | 0 | _gcry_mpi_release (sk->d); sk->d = NULL; |
952 | 0 | _gcry_mpi_release (sk->u); sk->u = NULL; |
953 | 0 | fips_signal_error ("self-test after key generation failed"); |
954 | 0 | return GPG_ERR_SELFTEST_FAILED; |
955 | 0 | } |
956 | | |
957 | 0 | return 0; |
958 | 0 | } |
959 | | |
960 | | |
961 | | /**************** |
962 | | * Test whether the secret key is valid. |
963 | | * Returns: true if this is a valid key. |
964 | | */ |
965 | | static int |
966 | | check_secret_key( RSA_secret_key *sk ) |
967 | 0 | { |
968 | 0 | int rc; |
969 | 0 | gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 ); |
970 | |
|
971 | 0 | mpi_mul(temp, sk->p, sk->q ); |
972 | 0 | rc = mpi_cmp( temp, sk->n ); |
973 | 0 | mpi_free(temp); |
974 | 0 | return !rc; |
975 | 0 | } |
976 | | |
977 | | |
978 | | |
979 | | /**************** |
980 | | * Public key operation. Encrypt INPUT with PKEY and put result into OUTPUT. |
981 | | * |
982 | | * c = m^e mod n |
983 | | * |
984 | | * Where c is OUTPUT, m is INPUT and e,n are elements of PKEY. |
985 | | */ |
986 | | static void |
987 | | public(gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *pkey ) |
988 | 0 | { |
989 | 0 | if( output == input ) /* powm doesn't like output and input the same */ |
990 | 0 | { |
991 | 0 | gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs(input)*2 ); |
992 | 0 | mpi_powm( x, input, pkey->e, pkey->n ); |
993 | 0 | mpi_set(output, x); |
994 | 0 | mpi_free(x); |
995 | 0 | } |
996 | 0 | else |
997 | 0 | mpi_powm( output, input, pkey->e, pkey->n ); |
998 | 0 | } |
999 | | |
1000 | | #if 0 |
1001 | | static void |
1002 | | stronger_key_check ( RSA_secret_key *skey ) |
1003 | | { |
1004 | | gcry_mpi_t t = mpi_alloc_secure ( 0 ); |
1005 | | gcry_mpi_t t1 = mpi_alloc_secure ( 0 ); |
1006 | | gcry_mpi_t t2 = mpi_alloc_secure ( 0 ); |
1007 | | gcry_mpi_t phi = mpi_alloc_secure ( 0 ); |
1008 | | |
1009 | | /* check that n == p * q */ |
1010 | | mpi_mul( t, skey->p, skey->q); |
1011 | | if (mpi_cmp( t, skey->n) ) |
1012 | | log_info ( "RSA Oops: n != p * q\n" ); |
1013 | | |
1014 | | /* check that p is less than q */ |
1015 | | if( mpi_cmp( skey->p, skey->q ) > 0 ) |
1016 | | { |
1017 | | log_info ("RSA Oops: p >= q - fixed\n"); |
1018 | | _gcry_mpi_swap ( skey->p, skey->q); |
1019 | | } |
1020 | | |
1021 | | /* check that e divides neither p-1 nor q-1 */ |
1022 | | mpi_sub_ui(t, skey->p, 1 ); |
1023 | | mpi_fdiv_r(t, t, skey->e ); |
1024 | | if ( !mpi_cmp_ui( t, 0) ) |
1025 | | log_info ( "RSA Oops: e divides p-1\n" ); |
1026 | | mpi_sub_ui(t, skey->q, 1 ); |
1027 | | mpi_fdiv_r(t, t, skey->e ); |
1028 | | if ( !mpi_cmp_ui( t, 0) ) |
1029 | | log_info ( "RSA Oops: e divides q-1\n" ); |
1030 | | |
1031 | | /* check that d is correct */ |
1032 | | mpi_sub_ui( t1, skey->p, 1 ); |
1033 | | mpi_sub_ui( t2, skey->q, 1 ); |
1034 | | mpi_mul( phi, t1, t2 ); |
1035 | | gcry_mpi_gcd(t, t1, t2); |
1036 | | mpi_fdiv_q(t, phi, t); |
1037 | | mpi_invm(t, skey->e, t ); |
1038 | | if ( mpi_cmp(t, skey->d ) ) |
1039 | | { |
1040 | | log_info ( "RSA Oops: d is wrong - fixed\n"); |
1041 | | mpi_set (skey->d, t); |
1042 | | log_printmpi (" fixed d", skey->d); |
1043 | | } |
1044 | | |
1045 | | /* check for correctness of u */ |
1046 | | mpi_invm(t, skey->p, skey->q ); |
1047 | | if ( mpi_cmp(t, skey->u ) ) |
1048 | | { |
1049 | | log_info ( "RSA Oops: u is wrong - fixed\n"); |
1050 | | mpi_set (skey->u, t); |
1051 | | log_printmpi (" fixed u", skey->u); |
1052 | | } |
1053 | | |
1054 | | log_info ( "RSA secret key check finished\n"); |
1055 | | |
1056 | | mpi_free (t); |
1057 | | mpi_free (t1); |
1058 | | mpi_free (t2); |
1059 | | mpi_free (phi); |
1060 | | } |
1061 | | #endif |
1062 | | |
1063 | | |
1064 | | |
1065 | | /* Secret key operation - standard version. |
1066 | | * |
1067 | | * m = c^d mod n |
1068 | | */ |
1069 | | static void |
1070 | | secret_core_std (gcry_mpi_t M, gcry_mpi_t C, |
1071 | | gcry_mpi_t D, gcry_mpi_t N) |
1072 | 0 | { |
1073 | 0 | mpi_powm (M, C, D, N); |
1074 | 0 | } |
1075 | | |
1076 | | |
1077 | | /* Secret key operation - using the CRT. |
1078 | | * |
1079 | | * m1 = c ^ (d mod (p-1)) mod p |
1080 | | * m2 = c ^ (d mod (q-1)) mod q |
1081 | | * h = u * (m2 - m1) mod q |
1082 | | * m = m1 + h * p |
1083 | | */ |
1084 | | static void |
1085 | | secret_core_crt (gcry_mpi_t M, gcry_mpi_t C, |
1086 | | gcry_mpi_t D, unsigned int Nlimbs, |
1087 | | gcry_mpi_t P, gcry_mpi_t Q, gcry_mpi_t U) |
1088 | 0 | { |
1089 | 0 | gcry_mpi_t m1 = mpi_alloc_secure ( Nlimbs + 1 ); |
1090 | 0 | gcry_mpi_t m2 = mpi_alloc_secure ( Nlimbs + 1 ); |
1091 | 0 | gcry_mpi_t h = mpi_alloc_secure ( Nlimbs + 1 ); |
1092 | 0 | gcry_mpi_t D_blind = mpi_alloc_secure ( Nlimbs + 1 ); |
1093 | 0 | gcry_mpi_t r; |
1094 | 0 | unsigned int r_nbits; |
1095 | |
|
1096 | 0 | r_nbits = mpi_get_nbits (P) / 4; |
1097 | 0 | if (r_nbits < 96) |
1098 | 0 | r_nbits = 96; |
1099 | 0 | r = mpi_secure_new (r_nbits); |
1100 | | |
1101 | | /* d_blind = (d mod (p-1)) + (p-1) * r */ |
1102 | | /* m1 = c ^ d_blind mod p */ |
1103 | 0 | _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM); |
1104 | 0 | mpi_set_highbit (r, r_nbits - 1); |
1105 | 0 | mpi_sub_ui ( h, P, 1 ); |
1106 | 0 | mpi_mul ( D_blind, h, r ); |
1107 | 0 | mpi_fdiv_r ( h, D, h ); |
1108 | 0 | mpi_add ( D_blind, D_blind, h ); |
1109 | 0 | mpi_powm ( m1, C, D_blind, P ); |
1110 | | |
1111 | | /* d_blind = (d mod (q-1)) + (q-1) * r */ |
1112 | | /* m2 = c ^ d_blind mod q */ |
1113 | 0 | _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM); |
1114 | 0 | mpi_set_highbit (r, r_nbits - 1); |
1115 | 0 | mpi_sub_ui ( h, Q, 1 ); |
1116 | 0 | mpi_mul ( D_blind, h, r ); |
1117 | 0 | mpi_fdiv_r ( h, D, h ); |
1118 | 0 | mpi_add ( D_blind, D_blind, h ); |
1119 | 0 | mpi_powm ( m2, C, D_blind, Q ); |
1120 | |
|
1121 | 0 | mpi_free ( r ); |
1122 | 0 | mpi_free ( D_blind ); |
1123 | | |
1124 | | /* h = u * ( m2 - m1 ) mod q */ |
1125 | 0 | mpi_sub ( h, m2, m1 ); |
1126 | 0 | if ( mpi_has_sign ( h ) ) |
1127 | 0 | mpi_add ( h, h, Q ); |
1128 | 0 | mpi_mulm ( h, U, h, Q ); |
1129 | | |
1130 | | /* m = m1 + h * p */ |
1131 | 0 | mpi_mul ( h, h, P ); |
1132 | 0 | mpi_add ( M, m1, h ); |
1133 | |
|
1134 | 0 | mpi_free ( h ); |
1135 | 0 | mpi_free ( m1 ); |
1136 | 0 | mpi_free ( m2 ); |
1137 | 0 | } |
1138 | | |
1139 | | |
1140 | | /* Secret key operation. |
1141 | | * Encrypt INPUT with SKEY and put result into |
1142 | | * OUTPUT. SKEY has the secret key parameters. |
1143 | | */ |
1144 | | static void |
1145 | | secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey ) |
1146 | 0 | { |
1147 | | /* Remove superfluous leading zeroes from INPUT. */ |
1148 | 0 | mpi_normalize (input); |
1149 | |
|
1150 | 0 | if (!skey->p || !skey->q || !skey->u) |
1151 | 0 | { |
1152 | 0 | secret_core_std (output, input, skey->d, skey->n); |
1153 | 0 | } |
1154 | 0 | else |
1155 | 0 | { |
1156 | 0 | secret_core_crt (output, input, skey->d, mpi_get_nlimbs (skey->n), |
1157 | 0 | skey->p, skey->q, skey->u); |
1158 | 0 | } |
1159 | 0 | } |
1160 | | |
1161 | | |
1162 | | static void |
1163 | | secret_blinded (gcry_mpi_t output, gcry_mpi_t input, |
1164 | | RSA_secret_key *sk, unsigned int nbits) |
1165 | 0 | { |
1166 | 0 | gcry_mpi_t r; /* Random number needed for blinding. */ |
1167 | 0 | gcry_mpi_t ri; /* Modular multiplicative inverse of r. */ |
1168 | 0 | gcry_mpi_t bldata; /* Blinded data to decrypt. */ |
1169 | | |
1170 | | /* First, we need a random number r between 0 and n - 1, which is |
1171 | | * relatively prime to n (i.e. it is neither p nor q). The random |
1172 | | * number needs to be only unpredictable, thus we employ the |
1173 | | * gcry_create_nonce function by using GCRY_WEAK_RANDOM with |
1174 | | * gcry_mpi_randomize. */ |
1175 | 0 | r = mpi_snew (nbits); |
1176 | 0 | ri = mpi_snew (nbits); |
1177 | 0 | bldata = mpi_snew (nbits); |
1178 | |
|
1179 | 0 | do |
1180 | 0 | { |
1181 | 0 | _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM); |
1182 | 0 | mpi_mod (r, r, sk->n); |
1183 | 0 | } |
1184 | 0 | while (!mpi_invm (ri, r, sk->n)); |
1185 | | |
1186 | | /* Do blinding. We calculate: y = (x * r^e) mod n, where r is the |
1187 | | * random number, e is the public exponent, x is the non-blinded |
1188 | | * input data and n is the RSA modulus. */ |
1189 | 0 | mpi_powm (bldata, r, sk->e, sk->n); |
1190 | 0 | mpi_mulm (bldata, bldata, input, sk->n); |
1191 | | |
1192 | | /* Perform decryption. */ |
1193 | 0 | secret (output, bldata, sk); |
1194 | 0 | _gcry_mpi_release (bldata); |
1195 | | |
1196 | | /* Undo blinding. Here we calculate: y = (x * r^-1) mod n, where x |
1197 | | * is the blinded decrypted data, ri is the modular multiplicative |
1198 | | * inverse of r and n is the RSA modulus. */ |
1199 | 0 | mpi_mulm (output, output, ri, sk->n); |
1200 | |
|
1201 | 0 | _gcry_mpi_release (r); |
1202 | 0 | _gcry_mpi_release (ri); |
1203 | 0 | } |
1204 | | |
1205 | | |
1206 | | /********************************************* |
1207 | | ************** interface ****************** |
1208 | | *********************************************/ |
1209 | | |
1210 | | static gcry_err_code_t |
1211 | | rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) |
1212 | 0 | { |
1213 | 0 | gpg_err_code_t ec; |
1214 | 0 | unsigned int nbits; |
1215 | 0 | unsigned long evalue; |
1216 | 0 | RSA_secret_key sk; |
1217 | 0 | gcry_sexp_t deriveparms; |
1218 | 0 | int flags = 0; |
1219 | 0 | gcry_sexp_t l1; |
1220 | 0 | gcry_sexp_t swap_info = NULL; |
1221 | 0 | int testparms = 0; |
1222 | |
|
1223 | 0 | memset (&sk, 0, sizeof sk); |
1224 | |
|
1225 | 0 | ec = _gcry_pk_util_get_nbits (genparms, &nbits); |
1226 | 0 | if (ec) |
1227 | 0 | return ec; |
1228 | | |
1229 | 0 | ec = _gcry_pk_util_get_rsa_use_e (genparms, &evalue); |
1230 | 0 | if (ec) |
1231 | 0 | return ec; |
1232 | | |
1233 | | /* Parse the optional flags list. */ |
1234 | 0 | l1 = sexp_find_token (genparms, "flags", 0); |
1235 | 0 | if (l1) |
1236 | 0 | { |
1237 | 0 | ec = _gcry_pk_util_parse_flaglist (l1, &flags, NULL); |
1238 | 0 | sexp_release (l1); |
1239 | 0 | if (ec) |
1240 | 0 | return ec; |
1241 | 0 | } |
1242 | | |
1243 | 0 | deriveparms = (genparms? |
1244 | 0 | sexp_find_token (genparms, "derive-parms", 0) : NULL); |
1245 | 0 | if (!deriveparms) |
1246 | 0 | { |
1247 | | /* Parse the optional "use-x931" flag. */ |
1248 | 0 | l1 = sexp_find_token (genparms, "use-x931", 0); |
1249 | 0 | if (l1) |
1250 | 0 | { |
1251 | 0 | flags |= PUBKEY_FLAG_USE_X931; |
1252 | 0 | sexp_release (l1); |
1253 | 0 | } |
1254 | 0 | } |
1255 | |
|
1256 | 0 | if (deriveparms || (flags & PUBKEY_FLAG_USE_X931)) |
1257 | 0 | { |
1258 | 0 | int swapped; |
1259 | 0 | if (fips_mode ()) |
1260 | 0 | { |
1261 | 0 | sexp_release (deriveparms); |
1262 | 0 | return GPG_ERR_INV_SEXP; |
1263 | 0 | } |
1264 | 0 | ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped); |
1265 | 0 | sexp_release (deriveparms); |
1266 | 0 | if (!ec && swapped) |
1267 | 0 | ec = sexp_new (&swap_info, "(misc-key-info(p-q-swapped))", 0, 1); |
1268 | 0 | } |
1269 | 0 | else |
1270 | 0 | { |
1271 | | /* Parse the optional "transient-key" flag. */ |
1272 | 0 | if (!(flags & PUBKEY_FLAG_TRANSIENT_KEY)) |
1273 | 0 | { |
1274 | 0 | l1 = sexp_find_token (genparms, "transient-key", 0); |
1275 | 0 | if (l1) |
1276 | 0 | { |
1277 | 0 | flags |= PUBKEY_FLAG_TRANSIENT_KEY; |
1278 | 0 | sexp_release (l1); |
1279 | 0 | } |
1280 | 0 | } |
1281 | 0 | deriveparms = (genparms? sexp_find_token (genparms, "test-parms", 0) |
1282 | 0 | /**/ : NULL); |
1283 | 0 | if (deriveparms) |
1284 | 0 | testparms = 1; |
1285 | | |
1286 | | /* Generate. */ |
1287 | 0 | if (deriveparms || fips_mode ()) |
1288 | 0 | { |
1289 | 0 | ec = generate_fips (&sk, nbits, evalue, deriveparms, |
1290 | 0 | !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); |
1291 | 0 | } |
1292 | 0 | else |
1293 | 0 | { |
1294 | 0 | ec = generate_std (&sk, nbits, evalue, |
1295 | 0 | !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); |
1296 | 0 | } |
1297 | 0 | sexp_release (deriveparms); |
1298 | 0 | } |
1299 | | |
1300 | 0 | if (!ec) |
1301 | 0 | { |
1302 | 0 | ec = sexp_build (r_skey, NULL, |
1303 | 0 | "(key-data" |
1304 | 0 | " (public-key" |
1305 | 0 | " (rsa(n%m)(e%m)))" |
1306 | 0 | " (private-key" |
1307 | 0 | " (rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))" |
1308 | 0 | " %S)", |
1309 | 0 | sk.n, sk.e, |
1310 | 0 | sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, |
1311 | 0 | swap_info); |
1312 | 0 | } |
1313 | |
|
1314 | 0 | mpi_free (sk.n); |
1315 | 0 | mpi_free (sk.e); |
1316 | 0 | mpi_free (sk.p); |
1317 | 0 | mpi_free (sk.q); |
1318 | 0 | mpi_free (sk.d); |
1319 | 0 | mpi_free (sk.u); |
1320 | 0 | sexp_release (swap_info); |
1321 | |
|
1322 | 0 | if (!ec && !testparms && fips_mode () && test_keys_fips (*r_skey)) |
1323 | 0 | { |
1324 | 0 | sexp_release (*r_skey); *r_skey = NULL; |
1325 | 0 | fips_signal_error ("self-test after key generation failed"); |
1326 | 0 | return GPG_ERR_SELFTEST_FAILED; |
1327 | 0 | } |
1328 | | |
1329 | 0 | return ec; |
1330 | 0 | } |
1331 | | |
1332 | | |
1333 | | static gcry_err_code_t |
1334 | | rsa_check_secret_key (gcry_sexp_t keyparms) |
1335 | 0 | { |
1336 | 0 | gcry_err_code_t rc; |
1337 | 0 | RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL}; |
1338 | | |
1339 | | /* To check the key we need the optional parameters. */ |
1340 | 0 | rc = sexp_extract_param (keyparms, NULL, "nedpqu", |
1341 | 0 | &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u, |
1342 | 0 | NULL); |
1343 | 0 | if (rc) |
1344 | 0 | goto leave; |
1345 | | |
1346 | 0 | if (!check_secret_key (&sk)) |
1347 | 0 | rc = GPG_ERR_BAD_SECKEY; |
1348 | |
|
1349 | 0 | leave: |
1350 | 0 | _gcry_mpi_release (sk.n); |
1351 | 0 | _gcry_mpi_release (sk.e); |
1352 | 0 | _gcry_mpi_release (sk.d); |
1353 | 0 | _gcry_mpi_release (sk.p); |
1354 | 0 | _gcry_mpi_release (sk.q); |
1355 | 0 | _gcry_mpi_release (sk.u); |
1356 | 0 | if (DBG_CIPHER) |
1357 | 0 | log_debug ("rsa_testkey => %s\n", gpg_strerror (rc)); |
1358 | 0 | return rc; |
1359 | 0 | } |
1360 | | |
1361 | | |
1362 | | static gcry_err_code_t |
1363 | | rsa_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) |
1364 | 0 | { |
1365 | 0 | gcry_err_code_t rc; |
1366 | 0 | struct pk_encoding_ctx ctx; |
1367 | 0 | gcry_mpi_t data = NULL; |
1368 | 0 | RSA_public_key pk = {NULL, NULL}; |
1369 | 0 | gcry_mpi_t ciph = NULL; |
1370 | 0 | unsigned int nbits = rsa_get_nbits (keyparms); |
1371 | |
|
1372 | 0 | rc = rsa_check_keysize (nbits); |
1373 | 0 | if (rc) |
1374 | 0 | return rc; |
1375 | | |
1376 | 0 | _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, nbits); |
1377 | | |
1378 | | /* Extract the data. */ |
1379 | 0 | rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx); |
1380 | 0 | if (rc) |
1381 | 0 | goto leave; |
1382 | 0 | if (DBG_CIPHER) |
1383 | 0 | log_mpidump ("rsa_encrypt data", data); |
1384 | 0 | if (!data || mpi_is_opaque (data)) |
1385 | 0 | { |
1386 | 0 | rc = GPG_ERR_INV_DATA; |
1387 | 0 | goto leave; |
1388 | 0 | } |
1389 | | |
1390 | | /* Extract the key. */ |
1391 | 0 | rc = sexp_extract_param (keyparms, NULL, "ne", &pk.n, &pk.e, NULL); |
1392 | 0 | if (rc) |
1393 | 0 | goto leave; |
1394 | 0 | if (DBG_CIPHER) |
1395 | 0 | { |
1396 | 0 | log_mpidump ("rsa_encrypt n", pk.n); |
1397 | 0 | log_mpidump ("rsa_encrypt e", pk.e); |
1398 | 0 | } |
1399 | | |
1400 | | /* Do RSA computation and build result. */ |
1401 | 0 | ciph = mpi_new (0); |
1402 | 0 | public (ciph, data, &pk); |
1403 | 0 | if (DBG_CIPHER) |
1404 | 0 | log_mpidump ("rsa_encrypt res", ciph); |
1405 | 0 | if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN)) |
1406 | 0 | { |
1407 | | /* We need to make sure to return the correct length to avoid |
1408 | | problems with missing leading zeroes. */ |
1409 | 0 | unsigned char *em; |
1410 | 0 | size_t emlen = (mpi_get_nbits (pk.n)+7)/8; |
1411 | |
|
1412 | 0 | rc = _gcry_mpi_to_octet_string (&em, NULL, ciph, emlen); |
1413 | 0 | if (!rc) |
1414 | 0 | { |
1415 | 0 | rc = sexp_build (r_ciph, NULL, "(enc-val(rsa(a%b)))", (int)emlen, em); |
1416 | 0 | xfree (em); |
1417 | 0 | } |
1418 | 0 | } |
1419 | 0 | else |
1420 | 0 | rc = sexp_build (r_ciph, NULL, "(enc-val(rsa(a%m)))", ciph); |
1421 | |
|
1422 | 0 | leave: |
1423 | 0 | _gcry_mpi_release (ciph); |
1424 | 0 | _gcry_mpi_release (pk.n); |
1425 | 0 | _gcry_mpi_release (pk.e); |
1426 | 0 | _gcry_mpi_release (data); |
1427 | 0 | _gcry_pk_util_free_encoding_ctx (&ctx); |
1428 | 0 | if (DBG_CIPHER) |
1429 | 0 | log_debug ("rsa_encrypt => %s\n", gpg_strerror (rc)); |
1430 | 0 | return rc; |
1431 | 0 | } |
1432 | | |
1433 | | |
1434 | | static gcry_err_code_t |
1435 | | rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) |
1436 | | |
1437 | 0 | { |
1438 | 0 | gpg_err_code_t rc; |
1439 | 0 | struct pk_encoding_ctx ctx; |
1440 | 0 | gcry_sexp_t l1 = NULL; |
1441 | 0 | gcry_mpi_t data = NULL; |
1442 | 0 | RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL}; |
1443 | 0 | gcry_mpi_t plain = NULL; |
1444 | 0 | unsigned char *unpad = NULL; |
1445 | 0 | size_t unpadlen = 0; |
1446 | 0 | unsigned int nbits = rsa_get_nbits (keyparms); |
1447 | |
|
1448 | 0 | rc = rsa_check_keysize (nbits); |
1449 | 0 | if (rc) |
1450 | 0 | return rc; |
1451 | | |
1452 | 0 | _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, nbits); |
1453 | | |
1454 | | /* Extract the data. */ |
1455 | 0 | rc = _gcry_pk_util_preparse_encval (s_data, rsa_names, &l1, &ctx); |
1456 | 0 | if (rc) |
1457 | 0 | goto leave; |
1458 | 0 | rc = sexp_extract_param (l1, NULL, "a", &data, NULL); |
1459 | 0 | if (rc) |
1460 | 0 | goto leave; |
1461 | 0 | if (DBG_CIPHER) |
1462 | 0 | log_printmpi ("rsa_decrypt data", data); |
1463 | 0 | if (mpi_is_opaque (data)) |
1464 | 0 | { |
1465 | 0 | rc = GPG_ERR_INV_DATA; |
1466 | 0 | goto leave; |
1467 | 0 | } |
1468 | | |
1469 | | /* Extract the key. */ |
1470 | 0 | rc = sexp_extract_param (keyparms, NULL, "nedp?q?u?", |
1471 | 0 | &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u, |
1472 | 0 | NULL); |
1473 | 0 | if (rc) |
1474 | 0 | goto leave; |
1475 | 0 | if (DBG_CIPHER) |
1476 | 0 | { |
1477 | 0 | log_printmpi ("rsa_decrypt n", sk.n); |
1478 | 0 | log_printmpi ("rsa_decrypt e", sk.e); |
1479 | 0 | if (!fips_mode ()) |
1480 | 0 | { |
1481 | 0 | log_printmpi ("rsa_decrypt d", sk.d); |
1482 | 0 | log_printmpi ("rsa_decrypt p", sk.p); |
1483 | 0 | log_printmpi ("rsa_decrypt q", sk.q); |
1484 | 0 | log_printmpi ("rsa_decrypt u", sk.u); |
1485 | 0 | } |
1486 | 0 | } |
1487 | | |
1488 | | /* Better make sure that there are no superfluous leading zeroes in |
1489 | | the input and it has not been "padded" using multiples of N. |
1490 | | This mitigates side-channel attacks (CVE-2013-4576). */ |
1491 | 0 | mpi_normalize (data); |
1492 | 0 | mpi_fdiv_r (data, data, sk.n); |
1493 | | |
1494 | | /* Allocate MPI for the plaintext. */ |
1495 | 0 | plain = mpi_snew (nbits); |
1496 | | |
1497 | | /* We use blinding by default to mitigate timing attacks which can |
1498 | | be practically mounted over the network as shown by Brumley and |
1499 | | Boney in 2003. */ |
1500 | 0 | if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING)) |
1501 | 0 | secret (plain, data, &sk); |
1502 | 0 | else |
1503 | 0 | secret_blinded (plain, data, &sk, nbits); |
1504 | |
|
1505 | 0 | if (DBG_CIPHER) |
1506 | 0 | log_printmpi ("rsa_decrypt res", plain); |
1507 | | |
1508 | | /* Reverse the encoding and build the s-expression. */ |
1509 | 0 | switch (ctx.encoding) |
1510 | 0 | { |
1511 | 0 | case PUBKEY_ENC_PKCS1: |
1512 | 0 | rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain); |
1513 | 0 | mpi_free (plain); |
1514 | 0 | plain = NULL; |
1515 | 0 | if (!rc) |
1516 | 0 | rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad); |
1517 | 0 | break; |
1518 | | |
1519 | 0 | case PUBKEY_ENC_OAEP: |
1520 | 0 | rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen, |
1521 | 0 | nbits, ctx.hash_algo, |
1522 | 0 | plain, ctx.label, ctx.labellen); |
1523 | 0 | mpi_free (plain); |
1524 | 0 | plain = NULL; |
1525 | 0 | if (!rc) |
1526 | 0 | rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad); |
1527 | 0 | break; |
1528 | | |
1529 | 0 | default: |
1530 | | /* Raw format. For backward compatibility we need to assume a |
1531 | | signed mpi by using the sexp format string "%m". */ |
1532 | 0 | rc = sexp_build (r_plain, NULL, |
1533 | 0 | (ctx.flags & PUBKEY_FLAG_LEGACYRESULT) |
1534 | 0 | ? "%m":"(value %m)", plain); |
1535 | 0 | break; |
1536 | 0 | } |
1537 | | |
1538 | 0 | leave: |
1539 | 0 | xfree (unpad); |
1540 | 0 | _gcry_mpi_release (plain); |
1541 | 0 | _gcry_mpi_release (sk.n); |
1542 | 0 | _gcry_mpi_release (sk.e); |
1543 | 0 | _gcry_mpi_release (sk.d); |
1544 | 0 | _gcry_mpi_release (sk.p); |
1545 | 0 | _gcry_mpi_release (sk.q); |
1546 | 0 | _gcry_mpi_release (sk.u); |
1547 | 0 | _gcry_mpi_release (data); |
1548 | 0 | sexp_release (l1); |
1549 | 0 | _gcry_pk_util_free_encoding_ctx (&ctx); |
1550 | 0 | if (DBG_CIPHER) |
1551 | 0 | log_debug ("rsa_decrypt => %s\n", gpg_strerror (rc)); |
1552 | 0 | return rc; |
1553 | 0 | } |
1554 | | |
1555 | | |
1556 | | static gcry_err_code_t |
1557 | | rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) |
1558 | 0 | { |
1559 | 0 | gpg_err_code_t rc; |
1560 | 0 | struct pk_encoding_ctx ctx; |
1561 | 0 | gcry_mpi_t data = NULL; |
1562 | 0 | RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL}; |
1563 | 0 | RSA_public_key pk; |
1564 | 0 | gcry_mpi_t sig = NULL; |
1565 | 0 | gcry_mpi_t result = NULL; |
1566 | 0 | unsigned int nbits = rsa_get_nbits (keyparms); |
1567 | |
|
1568 | 0 | rc = rsa_check_keysize (nbits); |
1569 | 0 | if (rc) |
1570 | 0 | return rc; |
1571 | | |
1572 | 0 | _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, nbits); |
1573 | | |
1574 | | /* Extract the data. */ |
1575 | 0 | rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx); |
1576 | 0 | if (rc) |
1577 | 0 | goto leave; |
1578 | 0 | if (DBG_CIPHER) |
1579 | 0 | log_printmpi ("rsa_sign data", data); |
1580 | 0 | if (mpi_is_opaque (data)) |
1581 | 0 | { |
1582 | 0 | rc = GPG_ERR_INV_DATA; |
1583 | 0 | goto leave; |
1584 | 0 | } |
1585 | | |
1586 | | /* Extract the key. */ |
1587 | 0 | rc = sexp_extract_param (keyparms, NULL, "nedp?q?u?", |
1588 | 0 | &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u, |
1589 | 0 | NULL); |
1590 | 0 | if (rc) |
1591 | 0 | goto leave; |
1592 | 0 | if (DBG_CIPHER) |
1593 | 0 | { |
1594 | 0 | log_printmpi ("rsa_sign n", sk.n); |
1595 | 0 | log_printmpi ("rsa_sign e", sk.e); |
1596 | 0 | if (!fips_mode ()) |
1597 | 0 | { |
1598 | 0 | log_printmpi ("rsa_sign d", sk.d); |
1599 | 0 | log_printmpi ("rsa_sign p", sk.p); |
1600 | 0 | log_printmpi ("rsa_sign q", sk.q); |
1601 | 0 | log_printmpi ("rsa_sign u", sk.u); |
1602 | 0 | } |
1603 | 0 | } |
1604 | | |
1605 | | /* Do RSA computation. */ |
1606 | 0 | sig = mpi_new (0); |
1607 | 0 | if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING)) |
1608 | 0 | secret (sig, data, &sk); |
1609 | 0 | else |
1610 | 0 | secret_blinded (sig, data, &sk, nbits); |
1611 | 0 | if (DBG_CIPHER) |
1612 | 0 | log_printmpi ("rsa_sign res", sig); |
1613 | | |
1614 | | /* Check that the created signature is good. This detects a failure |
1615 | | of the CRT algorithm (Lenstra's attack on RSA's use of the CRT). */ |
1616 | 0 | result = mpi_new (0); |
1617 | 0 | pk.n = sk.n; |
1618 | 0 | pk.e = sk.e; |
1619 | 0 | public (result, sig, &pk); |
1620 | 0 | if (mpi_cmp (result, data)) |
1621 | 0 | { |
1622 | 0 | rc = GPG_ERR_BAD_SIGNATURE; |
1623 | 0 | goto leave; |
1624 | 0 | } |
1625 | | |
1626 | | /* Convert the result. */ |
1627 | 0 | if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN)) |
1628 | 0 | { |
1629 | | /* We need to make sure to return the correct length to avoid |
1630 | | problems with missing leading zeroes. */ |
1631 | 0 | unsigned char *em; |
1632 | 0 | size_t emlen = (mpi_get_nbits (sk.n)+7)/8; |
1633 | |
|
1634 | 0 | rc = _gcry_mpi_to_octet_string (&em, NULL, sig, emlen); |
1635 | 0 | if (!rc) |
1636 | 0 | { |
1637 | 0 | rc = sexp_build (r_sig, NULL, "(sig-val(rsa(s%b)))", (int)emlen, em); |
1638 | 0 | xfree (em); |
1639 | 0 | } |
1640 | 0 | } |
1641 | 0 | else |
1642 | 0 | rc = sexp_build (r_sig, NULL, "(sig-val(rsa(s%M)))", sig); |
1643 | | |
1644 | |
|
1645 | 0 | leave: |
1646 | 0 | _gcry_mpi_release (result); |
1647 | 0 | _gcry_mpi_release (sig); |
1648 | 0 | _gcry_mpi_release (sk.n); |
1649 | 0 | _gcry_mpi_release (sk.e); |
1650 | 0 | _gcry_mpi_release (sk.d); |
1651 | 0 | _gcry_mpi_release (sk.p); |
1652 | 0 | _gcry_mpi_release (sk.q); |
1653 | 0 | _gcry_mpi_release (sk.u); |
1654 | 0 | _gcry_mpi_release (data); |
1655 | 0 | _gcry_pk_util_free_encoding_ctx (&ctx); |
1656 | 0 | if (DBG_CIPHER) |
1657 | 0 | log_debug ("rsa_sign => %s\n", gpg_strerror (rc)); |
1658 | 0 | return rc; |
1659 | 0 | } |
1660 | | |
1661 | | |
1662 | | static gcry_err_code_t |
1663 | | rsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) |
1664 | 0 | { |
1665 | 0 | gcry_err_code_t rc; |
1666 | 0 | struct pk_encoding_ctx ctx; |
1667 | 0 | gcry_sexp_t l1 = NULL; |
1668 | 0 | gcry_mpi_t sig = NULL; |
1669 | 0 | gcry_mpi_t data = NULL; |
1670 | 0 | RSA_public_key pk = { NULL, NULL }; |
1671 | 0 | gcry_mpi_t result = NULL; |
1672 | 0 | unsigned int nbits = rsa_get_nbits (keyparms); |
1673 | |
|
1674 | 0 | rc = rsa_check_verify_keysize (nbits); |
1675 | 0 | if (rc) |
1676 | 0 | return rc; |
1677 | | |
1678 | 0 | _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, nbits); |
1679 | | |
1680 | | /* Extract the data. */ |
1681 | 0 | rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx); |
1682 | 0 | if (rc) |
1683 | 0 | goto leave; |
1684 | 0 | if (DBG_CIPHER) |
1685 | 0 | log_printmpi ("rsa_verify data", data); |
1686 | 0 | if (ctx.encoding != PUBKEY_ENC_PSS && mpi_is_opaque (data)) |
1687 | 0 | { |
1688 | 0 | rc = GPG_ERR_INV_DATA; |
1689 | 0 | goto leave; |
1690 | 0 | } |
1691 | | |
1692 | | /* Extract the signature value. */ |
1693 | 0 | rc = _gcry_pk_util_preparse_sigval (s_sig, rsa_names, &l1, NULL); |
1694 | 0 | if (rc) |
1695 | 0 | goto leave; |
1696 | 0 | rc = sexp_extract_param (l1, NULL, "s", &sig, NULL); |
1697 | 0 | if (rc) |
1698 | 0 | goto leave; |
1699 | 0 | if (DBG_CIPHER) |
1700 | 0 | log_printmpi ("rsa_verify sig", sig); |
1701 | | |
1702 | | /* Extract the key. */ |
1703 | 0 | rc = sexp_extract_param (keyparms, NULL, "ne", &pk.n, &pk.e, NULL); |
1704 | 0 | if (rc) |
1705 | 0 | goto leave; |
1706 | 0 | if (DBG_CIPHER) |
1707 | 0 | { |
1708 | 0 | log_printmpi ("rsa_verify n", pk.n); |
1709 | 0 | log_printmpi ("rsa_verify e", pk.e); |
1710 | 0 | } |
1711 | | |
1712 | | /* Do RSA computation and compare. */ |
1713 | 0 | result = mpi_new (0); |
1714 | 0 | public (result, sig, &pk); |
1715 | 0 | if (DBG_CIPHER) |
1716 | 0 | log_printmpi ("rsa_verify cmp", result); |
1717 | 0 | if (ctx.verify_cmp) |
1718 | 0 | rc = ctx.verify_cmp (&ctx, result); |
1719 | 0 | else |
1720 | 0 | rc = mpi_cmp (result, data) ? GPG_ERR_BAD_SIGNATURE : 0; |
1721 | |
|
1722 | 0 | leave: |
1723 | 0 | _gcry_mpi_release (result); |
1724 | 0 | _gcry_mpi_release (pk.n); |
1725 | 0 | _gcry_mpi_release (pk.e); |
1726 | 0 | _gcry_mpi_release (data); |
1727 | 0 | _gcry_mpi_release (sig); |
1728 | 0 | sexp_release (l1); |
1729 | 0 | _gcry_pk_util_free_encoding_ctx (&ctx); |
1730 | 0 | if (DBG_CIPHER) |
1731 | 0 | log_debug ("rsa_verify => %s\n", rc?gpg_strerror (rc):"Good"); |
1732 | 0 | return rc; |
1733 | 0 | } |
1734 | | |
1735 | | |
1736 | | |
1737 | | /* Return the number of bits for the key described by PARMS. On error |
1738 | | * 0 is returned. The format of PARMS starts with the algorithm name; |
1739 | | * for example: |
1740 | | * |
1741 | | * (rsa |
1742 | | * (n <mpi>) |
1743 | | * (e <mpi>)) |
1744 | | * |
1745 | | * More parameters may be given but we only need N here. |
1746 | | */ |
1747 | | static unsigned int |
1748 | | rsa_get_nbits (gcry_sexp_t parms) |
1749 | 0 | { |
1750 | 0 | gcry_sexp_t l1; |
1751 | 0 | gcry_mpi_t n; |
1752 | 0 | unsigned int nbits; |
1753 | |
|
1754 | 0 | l1 = sexp_find_token (parms, "n", 1); |
1755 | 0 | if (!l1) |
1756 | 0 | return 0; /* Parameter N not found. */ |
1757 | | |
1758 | 0 | n = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); |
1759 | 0 | sexp_release (l1); |
1760 | 0 | nbits = n? mpi_get_nbits (n) : 0; |
1761 | 0 | _gcry_mpi_release (n); |
1762 | 0 | return nbits; |
1763 | 0 | } |
1764 | | |
1765 | | |
1766 | | /* Compute a keygrip. MD is the hash context which we are going to |
1767 | | update. KEYPARAM is an S-expression with the key parameters, this |
1768 | | is usually a public key but may also be a secret key. An example |
1769 | | of such an S-expression is: |
1770 | | |
1771 | | (rsa |
1772 | | (n #00B...#) |
1773 | | (e #010001#)) |
1774 | | |
1775 | | PKCS-15 says that for RSA only the modulus should be hashed - |
1776 | | however, it is not clear whether this is meant to use the raw bytes |
1777 | | (assuming this is an unsigned integer) or whether the DER required |
1778 | | 0 should be prefixed. We hash the raw bytes. */ |
1779 | | static gpg_err_code_t |
1780 | | compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) |
1781 | 0 | { |
1782 | 0 | gcry_sexp_t l1; |
1783 | 0 | const char *data; |
1784 | 0 | size_t datalen; |
1785 | |
|
1786 | 0 | l1 = sexp_find_token (keyparam, "n", 1); |
1787 | 0 | if (!l1) |
1788 | 0 | return GPG_ERR_NO_OBJ; |
1789 | | |
1790 | 0 | data = sexp_nth_data (l1, 1, &datalen); |
1791 | 0 | if (!data) |
1792 | 0 | { |
1793 | 0 | sexp_release (l1); |
1794 | 0 | return GPG_ERR_NO_OBJ; |
1795 | 0 | } |
1796 | | |
1797 | 0 | _gcry_md_write (md, data, datalen); |
1798 | 0 | sexp_release (l1); |
1799 | |
|
1800 | 0 | return 0; |
1801 | 0 | } |
1802 | | |
1803 | | |
1804 | | |
1805 | | |
1806 | | /* |
1807 | | Self-test section. |
1808 | | */ |
1809 | | |
1810 | | static const char * |
1811 | | selftest_hash_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey) |
1812 | 0 | { |
1813 | 0 | int md_algo = GCRY_MD_SHA256; |
1814 | 0 | gcry_md_hd_t hd = NULL; |
1815 | 0 | const char *data_tmpl = "(data (flags pkcs1) (hash %s %b))"; |
1816 | 0 | static const char sample_data[] = |
1817 | 0 | "11223344556677889900aabbccddeeff" |
1818 | 0 | "102030405060708090a0b0c0d0f01121"; |
1819 | 0 | static const char sample_data_bad[] = |
1820 | 0 | "11223344556677889900aabbccddeeff" |
1821 | 0 | "802030405060708090a0b0c0d0f01121"; |
1822 | |
|
1823 | 0 | const char *errtxt = NULL; |
1824 | 0 | gcry_error_t err; |
1825 | 0 | gcry_sexp_t sig = NULL; |
1826 | | /* raw signature data reference */ |
1827 | 0 | const char ref_data[] = |
1828 | 0 | "518f41dea3ad884e93eefff8d7ca68a6f4c30d923632e35673651d675cebd652" |
1829 | 0 | "a44ed66f6879b18f3d48b2d235b1dd78f6189be1440352cc94231a55c1f93109" |
1830 | 0 | "84616b2841c42fe9a6e37be34cd188207209bd028e2fa93e721fbac40c31a068" |
1831 | 0 | "1253b312d4e07addb9c7f3d508fa89f218ea7c7f7b9f6a9b1e522c19fa1cd839" |
1832 | 0 | "93f9d4ca2f16c3d0b9abafe5e63e848152afc72ce7ee19ea45353116f85209ea" |
1833 | 0 | "b9de42129dbccdac8faa461e8e8cc2ae801101cc6add4ba76ccb752030b0e827" |
1834 | 0 | "7352b11cdecebae9cdc9a626c4701cd9c85cd287618888c5fae8b4d0ba48915d" |
1835 | 0 | "e5cc64e3aee2ba2862d04348ea71f65454f74f9fd1e3108005cc367ca41585a4"; |
1836 | 0 | gcry_mpi_t ref_mpi = NULL; |
1837 | 0 | gcry_mpi_t sig_mpi = NULL; |
1838 | |
|
1839 | 0 | err = _gcry_md_open (&hd, md_algo, 0); |
1840 | 0 | if (err) |
1841 | 0 | { |
1842 | 0 | errtxt = "gcry_md_open failed"; |
1843 | 0 | goto leave; |
1844 | 0 | } |
1845 | | |
1846 | 0 | _gcry_md_write (hd, sample_data, sizeof(sample_data)); |
1847 | |
|
1848 | 0 | err = _gcry_pk_sign_md (&sig, data_tmpl, hd, skey, NULL); |
1849 | 0 | if (err) |
1850 | 0 | { |
1851 | 0 | errtxt = "signing failed"; |
1852 | 0 | goto leave; |
1853 | 0 | } |
1854 | | |
1855 | 0 | err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL); |
1856 | 0 | if (err) |
1857 | 0 | { |
1858 | 0 | errtxt = "converting ref_data to mpi failed"; |
1859 | 0 | goto leave; |
1860 | 0 | } |
1861 | | |
1862 | 0 | err = _gcry_sexp_extract_param(sig, "sig-val!rsa", "s", &sig_mpi, NULL); |
1863 | 0 | if (err) |
1864 | 0 | { |
1865 | 0 | errtxt = "extracting signature data failed"; |
1866 | 0 | goto leave; |
1867 | 0 | } |
1868 | | |
1869 | 0 | if (mpi_cmp (sig_mpi, ref_mpi)) |
1870 | 0 | { |
1871 | 0 | errtxt = "signature does not match reference data"; |
1872 | 0 | goto leave; |
1873 | 0 | } |
1874 | | |
1875 | 0 | err = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL); |
1876 | 0 | if (err) |
1877 | 0 | { |
1878 | 0 | errtxt = "verify failed"; |
1879 | 0 | goto leave; |
1880 | 0 | } |
1881 | | |
1882 | 0 | _gcry_md_reset(hd); |
1883 | 0 | _gcry_md_write (hd, sample_data_bad, sizeof(sample_data_bad)); |
1884 | 0 | err = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL); |
1885 | 0 | if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE) |
1886 | 0 | { |
1887 | 0 | errtxt = "bad signature not detected"; |
1888 | 0 | goto leave; |
1889 | 0 | } |
1890 | | |
1891 | | |
1892 | 0 | leave: |
1893 | 0 | sexp_release (sig); |
1894 | 0 | _gcry_md_close (hd); |
1895 | 0 | _gcry_mpi_release (ref_mpi); |
1896 | 0 | _gcry_mpi_release (sig_mpi); |
1897 | 0 | return errtxt; |
1898 | 0 | } |
1899 | | |
1900 | | static const char * |
1901 | | selftest_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey) |
1902 | 0 | { |
1903 | 0 | static const char sample_data[] = |
1904 | 0 | "(data (flags pkcs1)" |
1905 | 0 | " (hash sha256 #11223344556677889900aabbccddeeff" |
1906 | 0 | /**/ "102030405060708090a0b0c0d0f01121#))"; |
1907 | 0 | static const char sample_data_bad[] = |
1908 | 0 | "(data (flags pkcs1)" |
1909 | 0 | " (hash sha256 #11223344556677889900aabbccddeeff" |
1910 | 0 | /**/ "802030405060708090a0b0c0d0f01121#))"; |
1911 | |
|
1912 | 0 | const char *errtxt = NULL; |
1913 | 0 | gcry_error_t err; |
1914 | 0 | gcry_sexp_t data = NULL; |
1915 | 0 | gcry_sexp_t data_bad = NULL; |
1916 | 0 | gcry_sexp_t sig = NULL; |
1917 | | /* raw signature data reference */ |
1918 | 0 | const char ref_data[] = |
1919 | 0 | "6252a19a11e1d5155ed9376036277193d644fa239397fff03e9b92d6f86415d6" |
1920 | 0 | "d30da9273775f290e580d038295ff8ff89522becccfa6ae870bf76b76df402a8" |
1921 | 0 | "54f69347e3db3de8e1e7d4dada281ec556810c7a8ecd0b5f51f9b1c0e7aa7557" |
1922 | 0 | "61aa2b8ba5f811304acc6af0eca41fe49baf33bf34eddaf44e21e036ac7f0b68" |
1923 | 0 | "03cdef1c60021fb7b5b97ebacdd88ab755ce29af568dbc5728cc6e6eff42618d" |
1924 | 0 | "62a0386ca8beed46402bdeeef29b6a3feded906bace411a06a39192bf516ae10" |
1925 | 0 | "67e4320fa8ea113968525f4574d022a3ceeaafdc41079efe1f22cc94bf59d8d3" |
1926 | 0 | "328085da9674857db56de5978a62394aab48aa3b72e23a1b16260cfd9daafe65"; |
1927 | 0 | gcry_mpi_t ref_mpi = NULL; |
1928 | 0 | gcry_mpi_t sig_mpi = NULL; |
1929 | |
|
1930 | 0 | err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data)); |
1931 | 0 | if (!err) |
1932 | 0 | err = sexp_sscan (&data_bad, NULL, |
1933 | 0 | sample_data_bad, strlen (sample_data_bad)); |
1934 | 0 | if (err) |
1935 | 0 | { |
1936 | 0 | errtxt = "converting data failed"; |
1937 | 0 | goto leave; |
1938 | 0 | } |
1939 | | |
1940 | 0 | err = _gcry_pk_sign (&sig, data, skey); |
1941 | 0 | if (err) |
1942 | 0 | { |
1943 | 0 | errtxt = "signing failed"; |
1944 | 0 | goto leave; |
1945 | 0 | } |
1946 | | |
1947 | 0 | err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL); |
1948 | 0 | if (err) |
1949 | 0 | { |
1950 | 0 | errtxt = "converting ref_data to mpi failed"; |
1951 | 0 | goto leave; |
1952 | 0 | } |
1953 | | |
1954 | 0 | err = _gcry_sexp_extract_param(sig, "sig-val!rsa", "s", &sig_mpi, NULL); |
1955 | 0 | if (err) |
1956 | 0 | { |
1957 | 0 | errtxt = "extracting signature data failed"; |
1958 | 0 | goto leave; |
1959 | 0 | } |
1960 | | |
1961 | 0 | if (mpi_cmp (sig_mpi, ref_mpi)) |
1962 | 0 | { |
1963 | 0 | errtxt = "signature does not match reference data"; |
1964 | 0 | goto leave; |
1965 | 0 | } |
1966 | | |
1967 | 0 | err = _gcry_pk_verify (sig, data, pkey); |
1968 | 0 | if (err) |
1969 | 0 | { |
1970 | 0 | errtxt = "verify failed"; |
1971 | 0 | goto leave; |
1972 | 0 | } |
1973 | 0 | err = _gcry_pk_verify (sig, data_bad, pkey); |
1974 | 0 | if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE) |
1975 | 0 | { |
1976 | 0 | errtxt = "bad signature not detected"; |
1977 | 0 | goto leave; |
1978 | 0 | } |
1979 | | |
1980 | | |
1981 | 0 | leave: |
1982 | 0 | sexp_release (sig); |
1983 | 0 | sexp_release (data_bad); |
1984 | 0 | sexp_release (data); |
1985 | 0 | _gcry_mpi_release (ref_mpi); |
1986 | 0 | _gcry_mpi_release (sig_mpi); |
1987 | 0 | return errtxt; |
1988 | 0 | } |
1989 | | |
1990 | | |
1991 | | |
1992 | | /* Given an S-expression ENCR_DATA of the form: |
1993 | | |
1994 | | (enc-val |
1995 | | (rsa |
1996 | | (a a-value))) |
1997 | | |
1998 | | as returned by gcry_pk_decrypt, return the the A-VALUE. On error, |
1999 | | return NULL. */ |
2000 | | static gcry_mpi_t |
2001 | | extract_a_from_sexp (gcry_sexp_t encr_data) |
2002 | 0 | { |
2003 | 0 | gcry_sexp_t l1, l2, l3; |
2004 | 0 | gcry_mpi_t a_value; |
2005 | |
|
2006 | 0 | l1 = sexp_find_token (encr_data, "enc-val", 0); |
2007 | 0 | if (!l1) |
2008 | 0 | return NULL; |
2009 | 0 | l2 = sexp_find_token (l1, "rsa", 0); |
2010 | 0 | sexp_release (l1); |
2011 | 0 | if (!l2) |
2012 | 0 | return NULL; |
2013 | 0 | l3 = sexp_find_token (l2, "a", 0); |
2014 | 0 | sexp_release (l2); |
2015 | 0 | if (!l3) |
2016 | 0 | return NULL; |
2017 | 0 | a_value = sexp_nth_mpi (l3, 1, 0); |
2018 | 0 | sexp_release (l3); |
2019 | |
|
2020 | 0 | return a_value; |
2021 | 0 | } |
2022 | | |
2023 | | |
2024 | | static const char * |
2025 | | selftest_encr_2048 (gcry_sexp_t pkey, gcry_sexp_t skey) |
2026 | 0 | { |
2027 | 0 | const char *errtxt = NULL; |
2028 | 0 | gcry_error_t err; |
2029 | 0 | static const char plaintext[] = |
2030 | 0 | "Jim quickly realized that the beautiful gowns are expensive."; |
2031 | 0 | gcry_sexp_t plain = NULL; |
2032 | 0 | gcry_sexp_t encr = NULL; |
2033 | 0 | gcry_mpi_t ciphertext = NULL; |
2034 | 0 | gcry_sexp_t decr = NULL; |
2035 | 0 | char *decr_plaintext = NULL; |
2036 | 0 | gcry_sexp_t tmplist = NULL; |
2037 | | /* expected result of encrypting the plaintext with sample_secret_key */ |
2038 | 0 | static const char ref_data[] = |
2039 | 0 | "18022e2593a402a737caaa93b4c7e750e20ca265452980e1d6b7710fbd3e" |
2040 | 0 | "7dce72be5c2110fb47691cb38f42170ee3b4a37f2498d4a51567d762585e" |
2041 | 0 | "4cb81d04fbc7df4144f8e5eac2d4b8688521b64011f11d7ad53f4c874004" |
2042 | 0 | "819856f2e2a6f83d1c9c4e73ac26089789c14482b0b8d44139133c88c4a5" |
2043 | 0 | "2dba9dd6d6ffc622666b7d129168333d999706af30a2d7d272db7734e5ed" |
2044 | 0 | "fb8c64ea3018af3ad20f4a013a5060cb0f5e72753967bebe294280a6ed0d" |
2045 | 0 | "dbd3c4f11d0a8696e9d32a0dc03deb0b5e49b2cbd1503392642d4e1211f3" |
2046 | 0 | "e8e2ee38abaa3671ccd57fcde8ca76e85fd2cb77c35706a970a213a27352" |
2047 | 0 | "cec92a9604d543ddb5fc478ff50e0622"; |
2048 | 0 | gcry_mpi_t ref_mpi = NULL; |
2049 | | |
2050 | | /* Put the plaintext into an S-expression. */ |
2051 | 0 | err = sexp_build (&plain, NULL, "(data (flags raw) (value %s))", plaintext); |
2052 | 0 | if (err) |
2053 | 0 | { |
2054 | 0 | errtxt = "converting data failed"; |
2055 | 0 | goto leave; |
2056 | 0 | } |
2057 | | |
2058 | | /* Encrypt. */ |
2059 | 0 | err = _gcry_pk_encrypt (&encr, plain, pkey); |
2060 | 0 | if (err) |
2061 | 0 | { |
2062 | 0 | errtxt = "encrypt failed"; |
2063 | 0 | goto leave; |
2064 | 0 | } |
2065 | | |
2066 | 0 | err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL); |
2067 | 0 | if (err) |
2068 | 0 | { |
2069 | 0 | errtxt = "converting encrydata to mpi failed"; |
2070 | 0 | goto leave; |
2071 | 0 | } |
2072 | | |
2073 | | /* Extraxt the ciphertext from the returned S-expression. */ |
2074 | | /*sexp_dump (encr);*/ |
2075 | 0 | ciphertext = extract_a_from_sexp (encr); |
2076 | 0 | if (!ciphertext) |
2077 | 0 | { |
2078 | 0 | errtxt = "gcry_pk_encrypt returned garbage"; |
2079 | 0 | goto leave; |
2080 | 0 | } |
2081 | | |
2082 | | /* Check that the ciphertext does no match the plaintext. */ |
2083 | | /* _gcry_log_printmpi ("plaintext", plaintext); */ |
2084 | | /* _gcry_log_printmpi ("ciphertxt", ciphertext); */ |
2085 | 0 | if (mpi_cmp (ref_mpi, ciphertext)) |
2086 | 0 | { |
2087 | 0 | errtxt = "ciphertext doesn't match reference data"; |
2088 | 0 | goto leave; |
2089 | 0 | } |
2090 | | |
2091 | | /* Decrypt. */ |
2092 | 0 | err = _gcry_pk_decrypt (&decr, encr, skey); |
2093 | 0 | if (err) |
2094 | 0 | { |
2095 | 0 | errtxt = "decrypt failed"; |
2096 | 0 | goto leave; |
2097 | 0 | } |
2098 | | |
2099 | | /* Extract the decrypted data from the S-expression. Note that the |
2100 | | output of gcry_pk_decrypt depends on whether a flags lists occurs |
2101 | | in its input data. Because we passed the output of |
2102 | | gcry_pk_encrypt directly to gcry_pk_decrypt, such a flag value |
2103 | | won't be there as of today. To be prepared for future changes we |
2104 | | take care of it anyway. */ |
2105 | 0 | tmplist = sexp_find_token (decr, "value", 0); |
2106 | 0 | if (tmplist) |
2107 | 0 | decr_plaintext = sexp_nth_string (tmplist, 1); |
2108 | 0 | else |
2109 | 0 | decr_plaintext = sexp_nth_string (decr, 0); |
2110 | 0 | if (!decr_plaintext) |
2111 | 0 | { |
2112 | 0 | errtxt = "decrypt returned no plaintext"; |
2113 | 0 | goto leave; |
2114 | 0 | } |
2115 | | |
2116 | | /* Check that the decrypted plaintext matches the original plaintext. */ |
2117 | 0 | if (strcmp (plaintext, decr_plaintext)) |
2118 | 0 | { |
2119 | 0 | errtxt = "mismatch"; |
2120 | 0 | goto leave; |
2121 | 0 | } |
2122 | | |
2123 | 0 | leave: |
2124 | 0 | sexp_release (tmplist); |
2125 | 0 | xfree (decr_plaintext); |
2126 | 0 | sexp_release (decr); |
2127 | 0 | _gcry_mpi_release (ciphertext); |
2128 | 0 | _gcry_mpi_release (ref_mpi); |
2129 | 0 | sexp_release (encr); |
2130 | 0 | sexp_release (plain); |
2131 | 0 | return errtxt; |
2132 | 0 | } |
2133 | | |
2134 | | |
2135 | | static gpg_err_code_t |
2136 | | selftests_rsa (selftest_report_func_t report, int extended) |
2137 | 0 | { |
2138 | 0 | const char *what; |
2139 | 0 | const char *errtxt; |
2140 | 0 | gcry_error_t err; |
2141 | 0 | gcry_sexp_t skey = NULL; |
2142 | 0 | gcry_sexp_t pkey = NULL; |
2143 | | |
2144 | | /* Convert the S-expressions into the internal representation. */ |
2145 | 0 | what = "convert"; |
2146 | 0 | err = sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key)); |
2147 | 0 | if (!err) |
2148 | 0 | err = sexp_sscan (&pkey, NULL, |
2149 | 0 | sample_public_key, strlen (sample_public_key)); |
2150 | 0 | if (err) |
2151 | 0 | { |
2152 | 0 | errtxt = _gcry_strerror (err); |
2153 | 0 | goto failed; |
2154 | 0 | } |
2155 | | |
2156 | 0 | what = "key consistency"; |
2157 | 0 | err = _gcry_pk_testkey (skey); |
2158 | 0 | if (err) |
2159 | 0 | { |
2160 | 0 | errtxt = _gcry_strerror (err); |
2161 | 0 | goto failed; |
2162 | 0 | } |
2163 | | |
2164 | 0 | if (extended) |
2165 | 0 | { |
2166 | 0 | what = "sign"; |
2167 | 0 | errtxt = selftest_sign_2048 (pkey, skey); |
2168 | 0 | if (errtxt) |
2169 | 0 | goto failed; |
2170 | 0 | } |
2171 | | |
2172 | 0 | what = "digest sign"; |
2173 | 0 | errtxt = selftest_hash_sign_2048 (pkey, skey); |
2174 | 0 | if (errtxt) |
2175 | 0 | goto failed; |
2176 | | |
2177 | 0 | if (extended) |
2178 | 0 | { |
2179 | 0 | what = "encrypt"; |
2180 | 0 | errtxt = selftest_encr_2048 (pkey, skey); |
2181 | 0 | if (errtxt) |
2182 | 0 | goto failed; |
2183 | 0 | } |
2184 | | |
2185 | 0 | sexp_release (pkey); |
2186 | 0 | sexp_release (skey); |
2187 | 0 | return 0; /* Succeeded. */ |
2188 | | |
2189 | 0 | failed: |
2190 | 0 | sexp_release (pkey); |
2191 | 0 | sexp_release (skey); |
2192 | 0 | if (report) |
2193 | 0 | report ("pubkey", GCRY_PK_RSA, what, errtxt); |
2194 | 0 | return GPG_ERR_SELFTEST_FAILED; |
2195 | 0 | } |
2196 | | |
2197 | | |
2198 | | /* Run a full self-test for ALGO and return 0 on success. */ |
2199 | | static gpg_err_code_t |
2200 | | run_selftests (int algo, int extended, selftest_report_func_t report) |
2201 | 0 | { |
2202 | 0 | gpg_err_code_t ec; |
2203 | |
|
2204 | 0 | switch (algo) |
2205 | 0 | { |
2206 | 0 | case GCRY_PK_RSA: |
2207 | 0 | ec = selftests_rsa (report, extended); |
2208 | 0 | break; |
2209 | 0 | default: |
2210 | 0 | ec = GPG_ERR_PUBKEY_ALGO; |
2211 | 0 | break; |
2212 | |
|
2213 | 0 | } |
2214 | 0 | return ec; |
2215 | 0 | } |
2216 | | |
2217 | | |
2218 | | |
2219 | | |
2220 | | gcry_pk_spec_t _gcry_pubkey_spec_rsa = |
2221 | | { |
2222 | | GCRY_PK_RSA, { 0, 1 }, |
2223 | | (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR), |
2224 | | "RSA", rsa_names, |
2225 | | "ne", "nedpqu", "a", "s", "n", |
2226 | | rsa_generate, |
2227 | | rsa_check_secret_key, |
2228 | | rsa_encrypt, |
2229 | | rsa_decrypt, |
2230 | | rsa_sign, |
2231 | | rsa_verify, |
2232 | | rsa_get_nbits, |
2233 | | run_selftests, |
2234 | | compute_keygrip |
2235 | | }; |