Line data Source code
1 : /* rsa-common.c - Supporting functions for RSA
2 : * Copyright (C) 2011 Free Software Foundation, Inc.
3 : * Copyright (C) 2013 g10 Code GmbH
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 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 :
26 : #include "g10lib.h"
27 : #include "mpi.h"
28 : #include "cipher.h"
29 : #include "pubkey-internal.h"
30 :
31 :
32 : /* Turn VALUE into an octet string and store it in an allocated buffer
33 : at R_FRAME or - if R_RAME is NULL - copy it into the caller
34 : provided buffer SPACE; either SPACE or R_FRAME may be used. If
35 : SPACE if not NULL, the caller must provide a buffer of at least
36 : NBYTES. If the resulting octet string is shorter than NBYTES pad
37 : it to the left with zeroes. If VALUE does not fit into NBYTES
38 : return an error code. */
39 : static gpg_err_code_t
40 0 : octet_string_from_mpi (unsigned char **r_frame, void *space,
41 : gcry_mpi_t value, size_t nbytes)
42 : {
43 0 : return _gcry_mpi_to_octet_string (r_frame, space, value, nbytes);
44 : }
45 :
46 :
47 :
48 : /* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
49 : type 2 padding. On success the result is stored as a new MPI at
50 : R_RESULT. On error the value at R_RESULT is undefined.
51 :
52 : If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
53 : the seed instead of using a random string for it. This feature is
54 : only useful for regression tests. Note that this value may not
55 : contain zero bytes.
56 :
57 : We encode the value in this way:
58 :
59 : 0 2 RND(n bytes) 0 VALUE
60 :
61 : 0 is a marker we unfortunately can't encode because we return an
62 : MPI which strips all leading zeroes.
63 : 2 is the block type.
64 : RND are non-zero random bytes.
65 :
66 : (Note that OpenPGP includes the cipher algorithm and a checksum in
67 : VALUE; the caller needs to prepare the value accordingly.)
68 : */
69 : gpg_err_code_t
70 0 : _gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits,
71 : const unsigned char *value, size_t valuelen,
72 : const unsigned char *random_override,
73 : size_t random_override_len)
74 : {
75 0 : gcry_err_code_t rc = 0;
76 0 : unsigned char *frame = NULL;
77 0 : size_t nframe = (nbits+7) / 8;
78 : int i;
79 : size_t n;
80 : unsigned char *p;
81 :
82 0 : if (valuelen + 7 > nframe || !nframe)
83 : {
84 : /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
85 0 : return GPG_ERR_TOO_SHORT; /* The key is too short. */
86 : }
87 :
88 0 : if ( !(frame = xtrymalloc_secure (nframe)))
89 0 : return gpg_err_code_from_syserror ();
90 :
91 0 : n = 0;
92 0 : frame[n++] = 0;
93 0 : frame[n++] = 2; /* block type */
94 0 : i = nframe - 3 - valuelen;
95 0 : gcry_assert (i > 0);
96 :
97 0 : if (random_override)
98 : {
99 : int j;
100 :
101 0 : if (random_override_len != i)
102 : {
103 0 : xfree (frame);
104 0 : return GPG_ERR_INV_ARG;
105 : }
106 : /* Check that random does not include a zero byte. */
107 0 : for (j=0; j < random_override_len; j++)
108 0 : if (!random_override[j])
109 : {
110 0 : xfree (frame);
111 0 : return GPG_ERR_INV_ARG;
112 : }
113 0 : memcpy (frame + n, random_override, random_override_len);
114 0 : n += random_override_len;
115 : }
116 : else
117 : {
118 0 : p = _gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
119 : /* Replace zero bytes by new values. */
120 : for (;;)
121 0 : {
122 : int j, k;
123 : unsigned char *pp;
124 :
125 : /* Count the zero bytes. */
126 0 : for (j=k=0; j < i; j++)
127 : {
128 0 : if (!p[j])
129 0 : k++;
130 : }
131 0 : if (!k)
132 0 : break; /* Okay: no (more) zero bytes. */
133 :
134 0 : k += k/128 + 3; /* Better get some more. */
135 0 : pp = _gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
136 0 : for (j=0; j < i && k; )
137 : {
138 0 : if (!p[j])
139 0 : p[j] = pp[--k];
140 0 : if (p[j])
141 0 : j++;
142 : }
143 0 : xfree (pp);
144 : }
145 0 : memcpy (frame+n, p, i);
146 0 : n += i;
147 0 : xfree (p);
148 : }
149 :
150 0 : frame[n++] = 0;
151 0 : memcpy (frame+n, value, valuelen);
152 0 : n += valuelen;
153 0 : gcry_assert (n == nframe);
154 :
155 0 : rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
156 0 : if (!rc &&DBG_CIPHER)
157 0 : log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
158 0 : xfree (frame);
159 :
160 0 : return rc;
161 : }
162 :
163 :
164 : /* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
165 : NBITS is the size of the secret key. On success the result is
166 : stored as a newly allocated buffer at R_RESULT and its valid length at
167 : R_RESULTLEN. On error NULL is stored at R_RESULT. */
168 : gpg_err_code_t
169 0 : _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen,
170 : unsigned int nbits, gcry_mpi_t value)
171 : {
172 : gcry_error_t err;
173 0 : unsigned char *frame = NULL;
174 0 : size_t nframe = (nbits+7) / 8;
175 : size_t n;
176 :
177 0 : *r_result = NULL;
178 :
179 0 : if ( !(frame = xtrymalloc_secure (nframe)))
180 0 : return gpg_err_code_from_syserror ();
181 :
182 0 : err = _gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
183 0 : if (err)
184 : {
185 0 : xfree (frame);
186 0 : return gcry_err_code (err);
187 : }
188 :
189 0 : nframe = n; /* Set NFRAME to the actual length. */
190 :
191 : /* FRAME = 0x00 || 0x02 || PS || 0x00 || M
192 :
193 : pkcs#1 requires that the first byte is zero. Our MPIs usually
194 : strip leading zero bytes; thus we are not able to detect them.
195 : However due to the way gcry_mpi_print is implemented we may see
196 : leading zero bytes nevertheless. We handle this by making the
197 : first zero byte optional. */
198 0 : if (nframe < 4)
199 : {
200 0 : xfree (frame);
201 0 : return GPG_ERR_ENCODING_PROBLEM; /* Too short. */
202 : }
203 0 : n = 0;
204 0 : if (!frame[0])
205 0 : n++;
206 0 : if (frame[n++] != 0x02)
207 : {
208 0 : xfree (frame);
209 0 : return GPG_ERR_ENCODING_PROBLEM; /* Wrong block type. */
210 : }
211 :
212 : /* Skip the non-zero random bytes and the terminating zero byte. */
213 0 : for (; n < nframe && frame[n] != 0x00; n++)
214 : ;
215 0 : if (n+1 >= nframe)
216 : {
217 0 : xfree (frame);
218 0 : return GPG_ERR_ENCODING_PROBLEM; /* No zero byte. */
219 : }
220 0 : n++; /* Skip the zero byte. */
221 :
222 : /* To avoid an extra allocation we reuse the frame buffer. The only
223 : caller of this function will anyway free the result soon. */
224 0 : memmove (frame, frame + n, nframe - n);
225 0 : *r_result = frame;
226 0 : *r_resultlen = nframe - n;
227 :
228 0 : if (DBG_CIPHER)
229 0 : log_printhex ("value extracted from PKCS#1 block type 2 encoded data",
230 : *r_result, *r_resultlen);
231 :
232 0 : return 0;
233 : }
234 :
235 :
236 : /* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
237 : using the pkcs#1 block type 1 padding. On success the result is
238 : stored as a new MPI at R_RESULT. On error the value at R_RESULT is
239 : undefined.
240 :
241 : We encode the value in this way:
242 :
243 : 0 1 PAD(n bytes) 0 ASN(asnlen bytes) VALUE(valuelen bytes)
244 :
245 : 0 is a marker we unfortunately can't encode because we return an
246 : MPI which strips all leading zeroes.
247 : 1 is the block type.
248 : PAD consists of 0xff bytes.
249 : 0 marks the end of the padding.
250 : ASN is the DER encoding of the hash algorithm; along with the VALUE
251 : it yields a valid DER encoding.
252 :
253 : (Note that PGP prior to version 2.3 encoded the message digest as:
254 : 0 1 MD(16 bytes) 0 PAD(n bytes) 1
255 : The MD is always 16 bytes here because it's always MD5. GnuPG
256 : does not not support pre-v2.3 signatures, but I'm including this
257 : comment so the information is easily found if needed.)
258 : */
259 : gpg_err_code_t
260 0 : _gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
261 : const unsigned char *value, size_t valuelen,
262 : int algo)
263 : {
264 0 : gcry_err_code_t rc = 0;
265 : byte asn[100];
266 0 : byte *frame = NULL;
267 0 : size_t nframe = (nbits+7) / 8;
268 : int i;
269 : size_t n;
270 : size_t asnlen, dlen;
271 :
272 0 : asnlen = DIM(asn);
273 0 : dlen = _gcry_md_get_algo_dlen (algo);
274 :
275 0 : if (_gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
276 : {
277 : /* We don't have yet all of the above algorithms. */
278 0 : return GPG_ERR_NOT_IMPLEMENTED;
279 : }
280 :
281 0 : if ( valuelen != dlen )
282 : {
283 : /* Hash value does not match the length of digest for
284 : the given algorithm. */
285 0 : return GPG_ERR_CONFLICT;
286 : }
287 :
288 0 : if ( !dlen || dlen + asnlen + 4 > nframe)
289 : {
290 : /* Can't encode an DLEN byte digest MD into an NFRAME byte
291 : frame. */
292 0 : return GPG_ERR_TOO_SHORT;
293 : }
294 :
295 0 : if ( !(frame = xtrymalloc (nframe)) )
296 0 : return gpg_err_code_from_syserror ();
297 :
298 : /* Assemble the pkcs#1 block type 1. */
299 0 : n = 0;
300 0 : frame[n++] = 0;
301 0 : frame[n++] = 1; /* block type */
302 0 : i = nframe - valuelen - asnlen - 3 ;
303 0 : gcry_assert (i > 1);
304 0 : memset (frame+n, 0xff, i );
305 0 : n += i;
306 0 : frame[n++] = 0;
307 0 : memcpy (frame+n, asn, asnlen);
308 0 : n += asnlen;
309 0 : memcpy (frame+n, value, valuelen );
310 0 : n += valuelen;
311 0 : gcry_assert (n == nframe);
312 :
313 : /* Convert it into an MPI. */
314 0 : rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
315 0 : if (!rc && DBG_CIPHER)
316 0 : log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
317 0 : xfree (frame);
318 :
319 0 : return rc;
320 : }
321 :
322 : /* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
323 : type 1 padding. On success the result is stored as a new MPI at
324 : R_RESULT. On error the value at R_RESULT is undefined.
325 :
326 : We encode the value in this way:
327 :
328 : 0 1 PAD(n bytes) 0 VALUE(valuelen bytes)
329 :
330 : 0 is a marker we unfortunately can't encode because we return an
331 : MPI which strips all leading zeroes.
332 : 1 is the block type.
333 : PAD consists of 0xff bytes.
334 : 0 marks the end of the padding.
335 :
336 : (Note that PGP prior to version 2.3 encoded the message digest as:
337 : 0 1 MD(16 bytes) 0 PAD(n bytes) 1
338 : The MD is always 16 bytes here because it's always MD5. GnuPG
339 : does not not support pre-v2.3 signatures, but I'm including this
340 : comment so the information is easily found if needed.)
341 : */
342 : gpg_err_code_t
343 0 : _gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
344 : const unsigned char *value, size_t valuelen)
345 : {
346 0 : gcry_err_code_t rc = 0;
347 : gcry_error_t err;
348 0 : byte *frame = NULL;
349 0 : size_t nframe = (nbits+7) / 8;
350 : int i;
351 : size_t n;
352 :
353 0 : if ( !valuelen || valuelen + 4 > nframe)
354 : {
355 : /* Can't encode an DLEN byte digest MD into an NFRAME byte
356 : frame. */
357 0 : return GPG_ERR_TOO_SHORT;
358 : }
359 :
360 0 : if ( !(frame = xtrymalloc (nframe)) )
361 0 : return gpg_err_code_from_syserror ();
362 :
363 : /* Assemble the pkcs#1 block type 1. */
364 0 : n = 0;
365 0 : frame[n++] = 0;
366 0 : frame[n++] = 1; /* block type */
367 0 : i = nframe - valuelen - 3 ;
368 0 : gcry_assert (i > 1);
369 0 : memset (frame+n, 0xff, i );
370 0 : n += i;
371 0 : frame[n++] = 0;
372 0 : memcpy (frame+n, value, valuelen );
373 0 : n += valuelen;
374 0 : gcry_assert (n == nframe);
375 :
376 : /* Convert it into an MPI. */
377 0 : err = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
378 0 : if (err)
379 0 : rc = gcry_err_code (err);
380 0 : else if (DBG_CIPHER)
381 0 : log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
382 0 : xfree (frame);
383 :
384 0 : return rc;
385 : }
386 :
387 :
388 : /* Mask generation function for OAEP. See RFC-3447 B.2.1. */
389 : static gcry_err_code_t
390 0 : mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
391 : int algo)
392 : {
393 : size_t dlen, nbytes, n;
394 : int idx;
395 : gcry_md_hd_t hd;
396 : gcry_err_code_t err;
397 :
398 0 : err = _gcry_md_open (&hd, algo, 0);
399 0 : if (err)
400 0 : return err;
401 :
402 0 : dlen = _gcry_md_get_algo_dlen (algo);
403 :
404 : /* We skip step 1 which would be assert(OUTLEN <= 2^32). The loop
405 : in step 3 is merged with step 4 by concatenating no more octets
406 : than what would fit into OUTPUT. The ceiling for the counter IDX
407 : is implemented indirectly. */
408 0 : nbytes = 0; /* Step 2. */
409 0 : idx = 0;
410 0 : while ( nbytes < outlen )
411 : {
412 : unsigned char c[4], *digest;
413 :
414 0 : if (idx)
415 0 : _gcry_md_reset (hd);
416 :
417 0 : c[0] = (idx >> 24) & 0xFF;
418 0 : c[1] = (idx >> 16) & 0xFF;
419 0 : c[2] = (idx >> 8) & 0xFF;
420 0 : c[3] = idx & 0xFF;
421 0 : idx++;
422 :
423 0 : _gcry_md_write (hd, seed, seedlen);
424 0 : _gcry_md_write (hd, c, 4);
425 0 : digest = _gcry_md_read (hd, 0);
426 :
427 0 : n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen;
428 0 : memcpy (output+nbytes, digest, n);
429 0 : nbytes += n;
430 : }
431 :
432 0 : _gcry_md_close (hd);
433 0 : return GPG_ERR_NO_ERROR;
434 : }
435 :
436 :
437 : /* RFC-3447 (pkcs#1 v2.1) OAEP encoding. NBITS is the length of the
438 : key measured in bits. ALGO is the hash function; it must be a
439 : valid and usable algorithm. {VALUE,VALUELEN} is the message to
440 : encrypt. {LABEL,LABELLEN} is the optional label to be associated
441 : with the message, if LABEL is NULL the default is to use the empty
442 : string as label. On success the encoded ciphertext is returned at
443 : R_RESULT.
444 :
445 : If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
446 : the seed instead of using a random string for it. This feature is
447 : only useful for regression tests.
448 :
449 : Here is figure 1 from the RFC depicting the process:
450 :
451 : +----------+---------+-------+
452 : DB = | lHash | PS | M |
453 : +----------+---------+-------+
454 : |
455 : +----------+ V
456 : | seed |--> MGF ---> xor
457 : +----------+ |
458 : | |
459 : +--+ V |
460 : |00| xor <----- MGF <-----|
461 : +--+ | |
462 : | | |
463 : V V V
464 : +--+----------+----------------------------+
465 : EM = |00|maskedSeed| maskedDB |
466 : +--+----------+----------------------------+
467 : */
468 : gpg_err_code_t
469 0 : _gcry_rsa_oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
470 : const unsigned char *value, size_t valuelen,
471 : const unsigned char *label, size_t labellen,
472 : const void *random_override, size_t random_override_len)
473 : {
474 0 : gcry_err_code_t rc = 0;
475 0 : unsigned char *frame = NULL;
476 0 : size_t nframe = (nbits+7) / 8;
477 : unsigned char *p;
478 : size_t hlen;
479 : size_t n;
480 :
481 0 : *r_result = NULL;
482 :
483 : /* Set defaults for LABEL. */
484 0 : if (!label || !labellen)
485 : {
486 0 : label = (const unsigned char*)"";
487 0 : labellen = 0;
488 : }
489 :
490 0 : hlen = _gcry_md_get_algo_dlen (algo);
491 :
492 : /* We skip step 1a which would be to check that LABELLEN is not
493 : greater than 2^61-1. See rfc-3447 7.1.1. */
494 :
495 : /* Step 1b. Note that the obsolete rfc-2437 uses the check:
496 : valuelen > nframe - 2 * hlen - 1 . */
497 0 : if (valuelen > nframe - 2 * hlen - 2 || !nframe)
498 : {
499 : /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
500 0 : return GPG_ERR_TOO_SHORT; /* The key is too short. */
501 : }
502 :
503 : /* Allocate the frame. */
504 0 : frame = xtrycalloc_secure (1, nframe);
505 0 : if (!frame)
506 0 : return gpg_err_code_from_syserror ();
507 :
508 : /* Step 2a: Compute the hash of the label. We store it in the frame
509 : where later the maskedDB will commence. */
510 0 : _gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen);
511 :
512 : /* Step 2b: Set octet string to zero. */
513 : /* This has already been done while allocating FRAME. */
514 :
515 : /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M. */
516 0 : n = nframe - valuelen - 1;
517 0 : frame[n] = 0x01;
518 0 : memcpy (frame + n + 1, value, valuelen);
519 :
520 : /* Step 3d: Generate seed. We store it where the maskedSeed will go
521 : later. */
522 0 : if (random_override)
523 : {
524 0 : if (random_override_len != hlen)
525 : {
526 0 : xfree (frame);
527 0 : return GPG_ERR_INV_ARG;
528 : }
529 0 : memcpy (frame + 1, random_override, hlen);
530 : }
531 : else
532 0 : _gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
533 :
534 : /* Step 2e and 2f: Create maskedDB. */
535 : {
536 : unsigned char *dmask;
537 :
538 0 : dmask = xtrymalloc_secure (nframe - hlen - 1);
539 0 : if (!dmask)
540 : {
541 0 : rc = gpg_err_code_from_syserror ();
542 0 : xfree (frame);
543 0 : return rc;
544 : }
545 0 : rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo);
546 0 : if (rc)
547 : {
548 0 : xfree (dmask);
549 0 : xfree (frame);
550 0 : return rc;
551 : }
552 0 : for (n = 1 + hlen, p = dmask; n < nframe; n++)
553 0 : frame[n] ^= *p++;
554 0 : xfree (dmask);
555 : }
556 :
557 : /* Step 2g and 2h: Create maskedSeed. */
558 : {
559 : unsigned char *smask;
560 :
561 0 : smask = xtrymalloc_secure (hlen);
562 0 : if (!smask)
563 : {
564 0 : rc = gpg_err_code_from_syserror ();
565 0 : xfree (frame);
566 0 : return rc;
567 : }
568 0 : rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo);
569 0 : if (rc)
570 : {
571 0 : xfree (smask);
572 0 : xfree (frame);
573 0 : return rc;
574 : }
575 0 : for (n = 1, p = smask; n < 1 + hlen; n++)
576 0 : frame[n] ^= *p++;
577 0 : xfree (smask);
578 : }
579 :
580 : /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB. */
581 : /* This has already been done by using in-place operations. */
582 :
583 : /* Convert the stuff into an MPI as expected by the caller. */
584 0 : rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
585 0 : if (!rc && DBG_CIPHER)
586 0 : log_mpidump ("OAEP encoded data", *r_result);
587 0 : xfree (frame);
588 :
589 0 : return rc;
590 : }
591 :
592 :
593 : /* RFC-3447 (pkcs#1 v2.1) OAEP decoding. NBITS is the length of the
594 : key measured in bits. ALGO is the hash function; it must be a
595 : valid and usable algorithm. VALUE is the raw decrypted message
596 : {LABEL,LABELLEN} is the optional label to be associated with the
597 : message, if LABEL is NULL the default is to use the empty string as
598 : label. On success the plaintext is returned as a newly allocated
599 : buffer at R_RESULT; its valid length is stored at R_RESULTLEN. On
600 : error NULL is stored at R_RESULT. */
601 : gpg_err_code_t
602 0 : _gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen,
603 : unsigned int nbits, int algo,
604 : gcry_mpi_t value,
605 : const unsigned char *label, size_t labellen)
606 : {
607 : gcry_err_code_t rc;
608 0 : unsigned char *frame = NULL; /* Encoded messages (EM). */
609 : unsigned char *masked_seed; /* Points into FRAME. */
610 : unsigned char *masked_db; /* Points into FRAME. */
611 0 : unsigned char *seed = NULL; /* Allocated space for the seed and DB. */
612 : unsigned char *db; /* Points into SEED. */
613 0 : unsigned char *lhash = NULL; /* Hash of the label. */
614 : size_t nframe; /* Length of the ciphertext (EM). */
615 : size_t hlen; /* Length of the hash digest. */
616 : size_t db_len; /* Length of DB and masked_db. */
617 0 : size_t nkey = (nbits+7)/8; /* Length of the key in bytes. */
618 0 : int failed = 0; /* Error indicator. */
619 : size_t n;
620 :
621 0 : *r_result = NULL;
622 :
623 : /* This code is implemented as described by rfc-3447 7.1.2. */
624 :
625 : /* Set defaults for LABEL. */
626 0 : if (!label || !labellen)
627 : {
628 0 : label = (const unsigned char*)"";
629 0 : labellen = 0;
630 : }
631 :
632 : /* Get the length of the digest. */
633 0 : hlen = _gcry_md_get_algo_dlen (algo);
634 :
635 : /* Hash the label right away. */
636 0 : lhash = xtrymalloc (hlen);
637 0 : if (!lhash)
638 0 : return gpg_err_code_from_syserror ();
639 0 : _gcry_md_hash_buffer (algo, lhash, label, labellen);
640 :
641 : /* Turn the MPI into an octet string. If the octet string is
642 : shorter than the key we pad it to the left with zeroes. This may
643 : happen due to the leading zero in OAEP frames and due to the
644 : following random octets (seed^mask) which may have leading zero
645 : bytes. This all is needed to cope with our leading zeroes
646 : suppressing MPI implementation. The code implictly implements
647 : Step 1b (bail out if NFRAME != N). */
648 0 : rc = octet_string_from_mpi (&frame, NULL, value, nkey);
649 0 : if (rc)
650 : {
651 0 : xfree (lhash);
652 0 : return GPG_ERR_ENCODING_PROBLEM;
653 : }
654 0 : nframe = nkey;
655 :
656 : /* Step 1c: Check that the key is long enough. */
657 0 : if ( nframe < 2 * hlen + 2 )
658 : {
659 0 : xfree (frame);
660 0 : xfree (lhash);
661 0 : return GPG_ERR_ENCODING_PROBLEM;
662 : }
663 :
664 : /* Step 2 has already been done by the caller and the
665 : gcry_mpi_aprint above. */
666 :
667 : /* Allocate space for SEED and DB. */
668 0 : seed = xtrymalloc_secure (nframe - 1);
669 0 : if (!seed)
670 : {
671 0 : rc = gpg_err_code_from_syserror ();
672 0 : xfree (frame);
673 0 : xfree (lhash);
674 0 : return rc;
675 : }
676 0 : db = seed + hlen;
677 :
678 : /* To avoid chosen ciphertext attacks from now on we make sure to
679 : run all code even in the error case; this avoids possible timing
680 : attacks as described by Manger. */
681 :
682 : /* Step 3a: Hash the label. */
683 : /* This has already been done. */
684 :
685 : /* Step 3b: Separate the encoded message. */
686 0 : masked_seed = frame + 1;
687 0 : masked_db = frame + 1 + hlen;
688 0 : db_len = nframe - 1 - hlen;
689 :
690 : /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen). */
691 0 : if (mgf1 (seed, hlen, masked_db, db_len, algo))
692 0 : failed = 1;
693 0 : for (n = 0; n < hlen; n++)
694 0 : seed[n] ^= masked_seed[n];
695 :
696 : /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len). */
697 0 : if (mgf1 (db, db_len, seed, hlen, algo))
698 0 : failed = 1;
699 0 : for (n = 0; n < db_len; n++)
700 0 : db[n] ^= masked_db[n];
701 :
702 : /* Step 3g: Check lhash, an possible empty padding string terminated
703 : by 0x01 and the first byte of EM being 0. */
704 0 : if (memcmp (lhash, db, hlen))
705 0 : failed = 1;
706 0 : for (n = hlen; n < db_len; n++)
707 0 : if (db[n] == 0x01)
708 0 : break;
709 0 : if (n == db_len)
710 0 : failed = 1;
711 0 : if (frame[0])
712 0 : failed = 1;
713 :
714 0 : xfree (lhash);
715 0 : xfree (frame);
716 0 : if (failed)
717 : {
718 0 : xfree (seed);
719 0 : return GPG_ERR_ENCODING_PROBLEM;
720 : }
721 :
722 : /* Step 4: Output M. */
723 : /* To avoid an extra allocation we reuse the seed buffer. The only
724 : caller of this function will anyway free the result soon. */
725 0 : n++;
726 0 : memmove (seed, db + n, db_len - n);
727 0 : *r_result = seed;
728 0 : *r_resultlen = db_len - n;
729 0 : seed = NULL;
730 :
731 0 : if (DBG_CIPHER)
732 0 : log_printhex ("value extracted from OAEP encoded data",
733 : *r_result, *r_resultlen);
734 :
735 0 : return 0;
736 : }
737 :
738 :
739 : /* RFC-3447 (pkcs#1 v2.1) PSS encoding. Encode {VALUE,VALUELEN} for
740 : an NBITS key. Note that VALUE is already the mHash from the
741 : picture below. ALGO is a valid hash algorithm and SALTLEN is the
742 : length of salt to be used. On success the result is stored as a
743 : new MPI at R_RESULT. On error the value at R_RESULT is undefined.
744 :
745 : If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
746 : the salt instead of using a random string for the salt. This
747 : feature is only useful for regression tests.
748 :
749 : Here is figure 2 from the RFC (errata 595 applied) depicting the
750 : process:
751 :
752 : +-----------+
753 : | M |
754 : +-----------+
755 : |
756 : V
757 : Hash
758 : |
759 : V
760 : +--------+----------+----------+
761 : M' = |Padding1| mHash | salt |
762 : +--------+----------+----------+
763 : |
764 : +--------+----------+ V
765 : DB = |Padding2| salt | Hash
766 : +--------+----------+ |
767 : | |
768 : V | +----+
769 : xor <--- MGF <---| |0xbc|
770 : | | +----+
771 : | | |
772 : V V V
773 : +-------------------+----------+----+
774 : EM = | maskedDB | H |0xbc|
775 : +-------------------+----------+----+
776 :
777 : */
778 : gpg_err_code_t
779 0 : _gcry_rsa_pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
780 : const unsigned char *value, size_t valuelen, int saltlen,
781 : const void *random_override, size_t random_override_len)
782 : {
783 0 : gcry_err_code_t rc = 0;
784 : size_t hlen; /* Length of the hash digest. */
785 0 : unsigned char *em = NULL; /* Encoded message. */
786 0 : size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
787 : unsigned char *h; /* Points into EM. */
788 0 : unsigned char *buf = NULL; /* Help buffer. */
789 : size_t buflen; /* Length of BUF. */
790 : unsigned char *mhash; /* Points into BUF. */
791 : unsigned char *salt; /* Points into BUF. */
792 : unsigned char *dbmask; /* Points into BUF. */
793 : unsigned char *p;
794 : size_t n;
795 :
796 : /* This code is implemented as described by rfc-3447 9.1.1. */
797 :
798 : /* Get the length of the digest. */
799 0 : hlen = _gcry_md_get_algo_dlen (algo);
800 0 : gcry_assert (hlen); /* We expect a valid ALGO here. */
801 :
802 : /* Allocate a help buffer and setup some pointers. */
803 0 : buflen = 8 + hlen + saltlen + (emlen - hlen - 1);
804 0 : buf = xtrymalloc (buflen);
805 0 : if (!buf)
806 : {
807 0 : rc = gpg_err_code_from_syserror ();
808 0 : goto leave;
809 : }
810 0 : mhash = buf + 8;
811 0 : salt = mhash + hlen;
812 0 : dbmask= salt + saltlen;
813 :
814 : /* Step 2: That would be: mHash = Hash(M) but our input is already
815 : mHash thus we do only a consistency check and copy to MHASH. */
816 0 : if (valuelen != hlen)
817 : {
818 0 : rc = GPG_ERR_INV_LENGTH;
819 0 : goto leave;
820 : }
821 0 : memcpy (mhash, value, hlen);
822 :
823 : /* Step 3: Check length constraints. */
824 0 : if (emlen < hlen + saltlen + 2)
825 : {
826 0 : rc = GPG_ERR_TOO_SHORT;
827 0 : goto leave;
828 : }
829 :
830 : /* Allocate space for EM. */
831 0 : em = xtrymalloc (emlen);
832 0 : if (!em)
833 : {
834 0 : rc = gpg_err_code_from_syserror ();
835 0 : goto leave;
836 : }
837 0 : h = em + emlen - 1 - hlen;
838 :
839 : /* Step 4: Create a salt. */
840 0 : if (saltlen)
841 : {
842 0 : if (random_override)
843 : {
844 0 : if (random_override_len != saltlen)
845 : {
846 0 : rc = GPG_ERR_INV_ARG;
847 0 : goto leave;
848 : }
849 0 : memcpy (salt, random_override, saltlen);
850 : }
851 : else
852 0 : _gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
853 : }
854 :
855 : /* Step 5 and 6: M' = Hash(Padding1 || mHash || salt). */
856 0 : memset (buf, 0, 8); /* Padding. */
857 0 : _gcry_md_hash_buffer (algo, h, buf, 8 + hlen + saltlen);
858 :
859 : /* Step 7 and 8: DB = PS || 0x01 || salt. */
860 : /* Note that we use EM to store DB and later Xor in-place. */
861 0 : p = em + emlen - 1 - hlen - saltlen - 1;
862 0 : memset (em, 0, p - em);
863 0 : *p++ = 0x01;
864 0 : memcpy (p, salt, saltlen);
865 :
866 : /* Step 9: dbmask = MGF(H, emlen - hlen - 1). */
867 0 : mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
868 :
869 : /* Step 10: maskedDB = DB ^ dbMask */
870 0 : for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
871 0 : em[n] ^= *p;
872 :
873 : /* Step 11: Set the leftmost bits to zero. */
874 0 : em[0] &= 0xFF >> (8 * emlen - nbits);
875 :
876 : /* Step 12: EM = maskedDB || H || 0xbc. */
877 0 : em[emlen-1] = 0xbc;
878 :
879 : /* Convert EM into an MPI. */
880 0 : rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, em, emlen, NULL);
881 0 : if (!rc && DBG_CIPHER)
882 0 : log_mpidump ("PSS encoded data", *r_result);
883 :
884 : leave:
885 0 : if (em)
886 : {
887 0 : wipememory (em, emlen);
888 0 : xfree (em);
889 : }
890 0 : if (buf)
891 : {
892 0 : wipememory (buf, buflen);
893 0 : xfree (buf);
894 : }
895 0 : return rc;
896 : }
897 :
898 :
899 : /* Verify a signature assuming PSS padding. VALUE is the hash of the
900 : message (mHash) encoded as an MPI; its length must match the digest
901 : length of ALGO. ENCODED is the output of the RSA public key
902 : function (EM). NBITS is the size of the public key. ALGO is the
903 : hash algorithm and SALTLEN is the length of the used salt. The
904 : function returns 0 on success or on error code. */
905 : gpg_err_code_t
906 0 : _gcry_rsa_pss_verify (gcry_mpi_t value, gcry_mpi_t encoded,
907 : unsigned int nbits, int algo, size_t saltlen)
908 : {
909 0 : gcry_err_code_t rc = 0;
910 : size_t hlen; /* Length of the hash digest. */
911 0 : unsigned char *em = NULL; /* Encoded message. */
912 0 : size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
913 : unsigned char *salt; /* Points into EM. */
914 : unsigned char *h; /* Points into EM. */
915 0 : unsigned char *buf = NULL; /* Help buffer. */
916 : size_t buflen; /* Length of BUF. */
917 : unsigned char *dbmask; /* Points into BUF. */
918 : unsigned char *mhash; /* Points into BUF. */
919 : unsigned char *p;
920 : size_t n;
921 :
922 : /* This code is implemented as described by rfc-3447 9.1.2. */
923 :
924 : /* Get the length of the digest. */
925 0 : hlen = _gcry_md_get_algo_dlen (algo);
926 0 : gcry_assert (hlen); /* We expect a valid ALGO here. */
927 :
928 : /* Allocate a help buffer and setup some pointers.
929 : This buffer is used for two purposes:
930 : +------------------------------+-------+
931 : 1. | dbmask | mHash |
932 : +------------------------------+-------+
933 : emlen - hlen - 1 hlen
934 :
935 : +----------+-------+---------+-+-------+
936 : 2. | padding1 | mHash | salt | | mHash |
937 : +----------+-------+---------+-+-------+
938 : 8 hlen saltlen hlen
939 : */
940 0 : buflen = 8 + hlen + saltlen;
941 0 : if (buflen < emlen - hlen - 1)
942 0 : buflen = emlen - hlen - 1;
943 0 : buflen += hlen;
944 0 : buf = xtrymalloc (buflen);
945 0 : if (!buf)
946 : {
947 0 : rc = gpg_err_code_from_syserror ();
948 0 : goto leave;
949 : }
950 0 : dbmask = buf;
951 0 : mhash = buf + buflen - hlen;
952 :
953 : /* Step 2: That would be: mHash = Hash(M) but our input is already
954 : mHash thus we only need to convert VALUE into MHASH. */
955 0 : rc = octet_string_from_mpi (NULL, mhash, value, hlen);
956 0 : if (rc)
957 0 : goto leave;
958 :
959 : /* Convert the signature into an octet string. */
960 0 : rc = octet_string_from_mpi (&em, NULL, encoded, emlen);
961 0 : if (rc)
962 0 : goto leave;
963 :
964 : /* Step 3: Check length of EM. Because we internally use MPI
965 : functions we can't do this properly; EMLEN is always the length
966 : of the key because octet_string_from_mpi needs to left pad the
967 : result with zero to cope with the fact that our MPIs suppress all
968 : leading zeroes. Thus what we test here are merely the digest and
969 : salt lengths to the key. */
970 0 : if (emlen < hlen + saltlen + 2)
971 : {
972 0 : rc = GPG_ERR_TOO_SHORT; /* For the hash and saltlen. */
973 0 : goto leave;
974 : }
975 :
976 : /* Step 4: Check last octet. */
977 0 : if (em[emlen - 1] != 0xbc)
978 : {
979 0 : rc = GPG_ERR_BAD_SIGNATURE;
980 0 : goto leave;
981 : }
982 :
983 : /* Step 5: Split EM. */
984 0 : h = em + emlen - 1 - hlen;
985 :
986 : /* Step 6: Check the leftmost bits. */
987 0 : if ((em[0] & ~(0xFF >> (8 * emlen - nbits))))
988 : {
989 0 : rc = GPG_ERR_BAD_SIGNATURE;
990 0 : goto leave;
991 : }
992 :
993 : /* Step 7: dbmask = MGF(H, emlen - hlen - 1). */
994 0 : mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
995 :
996 : /* Step 8: maskedDB = DB ^ dbMask. */
997 0 : for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
998 0 : em[n] ^= *p;
999 :
1000 : /* Step 9: Set leftmost bits in DB to zero. */
1001 0 : em[0] &= 0xFF >> (8 * emlen - nbits);
1002 :
1003 : /* Step 10: Check the padding of DB. */
1004 0 : for (n = 0; n < emlen - hlen - saltlen - 2 && !em[n]; n++)
1005 : ;
1006 0 : if (n != emlen - hlen - saltlen - 2 || em[n++] != 1)
1007 : {
1008 0 : rc = GPG_ERR_BAD_SIGNATURE;
1009 0 : goto leave;
1010 : }
1011 :
1012 : /* Step 11: Extract salt from DB. */
1013 0 : salt = em + n;
1014 :
1015 : /* Step 12: M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
1016 0 : memset (buf, 0, 8);
1017 0 : memcpy (buf+8, mhash, hlen);
1018 0 : memcpy (buf+8+hlen, salt, saltlen);
1019 :
1020 : /* Step 13: H' = Hash(M'). */
1021 0 : _gcry_md_hash_buffer (algo, buf, buf, 8 + hlen + saltlen);
1022 :
1023 : /* Step 14: Check H == H'. */
1024 0 : rc = memcmp (h, buf, hlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
1025 :
1026 : leave:
1027 0 : if (em)
1028 : {
1029 0 : wipememory (em, emlen);
1030 0 : xfree (em);
1031 : }
1032 0 : if (buf)
1033 : {
1034 0 : wipememory (buf, buflen);
1035 0 : xfree (buf);
1036 : }
1037 0 : return rc;
1038 : }
|