1 /* compliance.c - Functions for compliance modi
2 * Copyright (C) 2017 g10 Code GmbH
3 * Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
4 *
5 * This file is part of GnuPG.
6 *
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of either
9 *
10 * - the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * or
15 *
16 * - the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at
18 * your option) any later version.
19 *
20 * or both in parallel, as here.
21 *
22 * This file is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses/>.
29 */
30
31 #include <config.h>
32 #include <gcrypt.h>
33
34 #include "openpgpdefs.h"
35 #include "logging.h"
36 #include "util.h"
37 #include "i18n.h"
38 #include "compliance.h"
39
40 static int initialized;
41 static int module;
42
43
44 /* Return the address of a compliance cache variable for COMPLIANCE.
45 * If no such variable exists NULL is returned. FOR_RNG returns the
46 * cache variable for the RNG compliance check. */
47 static int *
get_compliance_cache(enum gnupg_compliance_mode compliance,int for_rng)48 get_compliance_cache (enum gnupg_compliance_mode compliance, int for_rng)
49 {
50 static int r_gnupg = -1, s_gnupg = -1;
51 static int r_rfc4880 = -1, s_rfc4880 = -1;
52 static int r_rfc2440 = -1, s_rfc2440 = -1;
53 static int r_pgp7 = -1, s_pgp7 = -1;
54 static int r_pgp8 = -1, s_pgp8 = -1;
55 static int r_de_vs = -1, s_de_vs = -1;
56
57 int *ptr = NULL;
58
59 switch (compliance)
60 {
61 case CO_GNUPG: ptr = for_rng? &r_gnupg : &s_gnupg ; break;
62 case CO_RFC4880: ptr = for_rng? &r_rfc4880 : &s_rfc4880; break;
63 case CO_RFC2440: ptr = for_rng? &r_rfc2440 : &s_rfc2440; break;
64 case CO_PGP7: ptr = for_rng? &r_pgp7 : &s_pgp7 ; break;
65 case CO_PGP8: ptr = for_rng? &r_pgp8 : &s_pgp8 ; break;
66 case CO_DE_VS: ptr = for_rng? &r_de_vs : &s_de_vs ; break;
67 }
68
69 return ptr;
70 }
71
72
73 /* Initializes the module. Must be called with the current
74 * GNUPG_MODULE_NAME. Checks a few invariants, and tunes the policies
75 * for the given module. */
76 void
gnupg_initialize_compliance(int gnupg_module_name)77 gnupg_initialize_compliance (int gnupg_module_name)
78 {
79 log_assert (! initialized);
80
81 /* We accept both OpenPGP-style and gcrypt-style algorithm ids.
82 * Assert that they are compatible. */
83 log_assert ((int) GCRY_PK_RSA == (int) PUBKEY_ALGO_RSA);
84 log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E);
85 log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S);
86 log_assert ((int) GCRY_PK_ELG_E == (int) PUBKEY_ALGO_ELGAMAL_E);
87 log_assert ((int) GCRY_PK_DSA == (int) PUBKEY_ALGO_DSA);
88 log_assert ((int) GCRY_PK_ECC == (int) PUBKEY_ALGO_ECDH);
89 log_assert ((int) GCRY_PK_ELG == (int) PUBKEY_ALGO_ELGAMAL);
90 log_assert ((int) GCRY_CIPHER_NONE == (int) CIPHER_ALGO_NONE);
91 log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA);
92 log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES);
93 log_assert ((int) GCRY_CIPHER_CAST5 == (int) CIPHER_ALGO_CAST5);
94 log_assert ((int) GCRY_CIPHER_BLOWFISH == (int) CIPHER_ALGO_BLOWFISH);
95 log_assert ((int) GCRY_CIPHER_AES == (int) CIPHER_ALGO_AES);
96 log_assert ((int) GCRY_CIPHER_AES192 == (int) CIPHER_ALGO_AES192);
97 log_assert ((int) GCRY_CIPHER_AES256 == (int) CIPHER_ALGO_AES256);
98 log_assert ((int) GCRY_CIPHER_TWOFISH == (int) CIPHER_ALGO_TWOFISH);
99 log_assert ((int) GCRY_MD_MD5 == (int) DIGEST_ALGO_MD5);
100 log_assert ((int) GCRY_MD_SHA1 == (int) DIGEST_ALGO_SHA1);
101 log_assert ((int) GCRY_MD_RMD160 == (int) DIGEST_ALGO_RMD160);
102 log_assert ((int) GCRY_MD_SHA256 == (int) DIGEST_ALGO_SHA256);
103 log_assert ((int) GCRY_MD_SHA384 == (int) DIGEST_ALGO_SHA384);
104 log_assert ((int) GCRY_MD_SHA512 == (int) DIGEST_ALGO_SHA512);
105 log_assert ((int) GCRY_MD_SHA224 == (int) DIGEST_ALGO_SHA224);
106
107 switch (gnupg_module_name)
108 {
109 case GNUPG_MODULE_NAME_GPGSM:
110 case GNUPG_MODULE_NAME_GPG:
111 break;
112
113 default:
114 log_assert (!"no policies for this module");
115 }
116
117 module = gnupg_module_name;
118 initialized = 1;
119 }
120
121 /* Return true if ALGO with a key of KEYLENGTH is compliant to the
122 * given COMPLIANCE mode. If KEY is not NULL, various bits of
123 * information will be extracted from it. If CURVENAME is not NULL, it
124 * is assumed to be the already computed. ALGO may be either an
125 * OpenPGP-style pubkey_algo_t, or a gcrypt-style enum gcry_pk_algos,
126 * both are compatible from the point of view of this function. */
127 int
gnupg_pk_is_compliant(enum gnupg_compliance_mode compliance,int algo,unsigned int algo_flags,gcry_mpi_t key[],unsigned int keylength,const char * curvename)128 gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
129 unsigned int algo_flags,
130 gcry_mpi_t key[], unsigned int keylength,
131 const char *curvename)
132 {
133 enum { is_rsa, is_dsa, is_elg, is_ecc } algotype;
134 int result = 0;
135
136 if (! initialized)
137 return 0;
138
139 switch (algo)
140 {
141 case PUBKEY_ALGO_RSA:
142 case PUBKEY_ALGO_RSA_E:
143 case PUBKEY_ALGO_RSA_S:
144 algotype = is_rsa;
145 break;
146
147 case PUBKEY_ALGO_DSA:
148 algotype = is_dsa;
149 break;
150
151 case PUBKEY_ALGO_ELGAMAL_E:
152 algotype = is_elg;
153 break;
154
155 case PUBKEY_ALGO_ECDH:
156 case PUBKEY_ALGO_ECDSA:
157 case PUBKEY_ALGO_EDDSA:
158 algotype = is_ecc;
159 break;
160
161 case PUBKEY_ALGO_ELGAMAL:
162 return 0; /* Signing with Elgamal is not at all supported. */
163
164 default: /* Unknown. */
165 return 0;
166 }
167
168 if (compliance == CO_DE_VS)
169 {
170 char *curve = NULL;
171
172 switch (algotype)
173 {
174 case is_elg:
175 result = 0;
176 break;
177
178 case is_rsa:
179 result = (keylength == 2048
180 || keylength == 3072
181 || keylength == 4096);
182 /* Although rsaPSS was not part of the original evaluation
183 * we got word that we can claim compliance. */
184 (void)algo_flags;
185 break;
186
187 case is_dsa:
188 if (key)
189 {
190 size_t P = gcry_mpi_get_nbits (key[0]);
191 size_t Q = gcry_mpi_get_nbits (key[1]);
192 result = (Q == 256
193 && (P == 2048 || P == 3072));
194 }
195 break;
196
197 case is_ecc:
198 if (!curvename && key)
199 {
200 curve = openpgp_oid_to_str (key[0]);
201 curvename = openpgp_oid_to_curve (curve, 0);
202 if (!curvename)
203 curvename = curve;
204 }
205
206 result = (curvename
207 && (algo == PUBKEY_ALGO_ECDH
208 || algo == PUBKEY_ALGO_ECDSA)
209 && (!strcmp (curvename, "brainpoolP256r1")
210 || !strcmp (curvename, "brainpoolP384r1")
211 || !strcmp (curvename, "brainpoolP512r1")));
212 break;
213
214 default:
215 result = 0;
216 }
217 xfree (curve);
218 }
219 else
220 {
221 result = 1; /* Assume compliance. */
222 }
223
224 return result;
225 }
226
227
228 /* Return true if ALGO with the given KEYLENGTH is allowed in the
229 * given COMPLIANCE mode. USE specifies for which use case the
230 * predicate is evaluated. This way policies can be strict in what
231 * they produce, and liberal in what they accept. */
232 int
gnupg_pk_is_allowed(enum gnupg_compliance_mode compliance,enum pk_use_case use,int algo,unsigned int algo_flags,gcry_mpi_t key[],unsigned int keylength,const char * curvename)233 gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
234 enum pk_use_case use, int algo,
235 unsigned int algo_flags, gcry_mpi_t key[],
236 unsigned int keylength, const char *curvename)
237 {
238 int result = 0;
239
240 if (! initialized)
241 return 1;
242
243 switch (compliance)
244 {
245 case CO_DE_VS:
246 switch (algo)
247 {
248 case PUBKEY_ALGO_RSA:
249 case PUBKEY_ALGO_RSA_E:
250 case PUBKEY_ALGO_RSA_S:
251 switch (use)
252 {
253 case PK_USE_DECRYPTION:
254 case PK_USE_VERIFICATION:
255 result = 1;
256 break;
257 case PK_USE_ENCRYPTION:
258 case PK_USE_SIGNING:
259 result = (keylength == 2048
260 || keylength == 3072
261 || keylength == 4096);
262 break;
263 default:
264 log_assert (!"reached");
265 }
266 (void)algo_flags;
267 break;
268
269 case PUBKEY_ALGO_DSA:
270 if (use == PK_USE_VERIFICATION)
271 result = 1;
272 else if (use == PK_USE_SIGNING && key)
273 {
274 size_t P = gcry_mpi_get_nbits (key[0]);
275 size_t Q = gcry_mpi_get_nbits (key[1]);
276 result = (Q == 256 && (P == 2048 || P == 3072));
277 }
278 break;
279
280 case PUBKEY_ALGO_ELGAMAL:
281 case PUBKEY_ALGO_ELGAMAL_E:
282 result = (use == PK_USE_DECRYPTION);
283 break;
284
285 case PUBKEY_ALGO_ECDH:
286 if (use == PK_USE_DECRYPTION)
287 result = 1;
288 else if (use == PK_USE_ENCRYPTION)
289 {
290 char *curve = NULL;
291
292 if (!curvename && key)
293 {
294 curve = openpgp_oid_to_str (key[0]);
295 curvename = openpgp_oid_to_curve (curve, 0);
296 if (!curvename)
297 curvename = curve;
298 }
299
300 result = (curvename
301 && (!strcmp (curvename, "brainpoolP256r1")
302 || !strcmp (curvename, "brainpoolP384r1")
303 || !strcmp (curvename, "brainpoolP512r1")));
304
305 xfree (curve);
306 }
307 break;
308
309 case PUBKEY_ALGO_ECDSA:
310 if (use == PK_USE_VERIFICATION)
311 result = 1;
312 else
313 {
314 char *curve = NULL;
315
316 if (! curvename && key)
317 {
318 curve = openpgp_oid_to_str (key[0]);
319 curvename = openpgp_oid_to_curve (curve, 0);
320 if (!curvename)
321 curvename = curve;
322 }
323
324 result = (use == PK_USE_SIGNING
325 && curvename
326 && (!strcmp (curvename, "brainpoolP256r1")
327 || !strcmp (curvename, "brainpoolP384r1")
328 || !strcmp (curvename, "brainpoolP512r1")));
329 xfree (curve);
330 }
331 break;
332
333
334 case PUBKEY_ALGO_EDDSA:
335 break;
336
337 default:
338 break;
339 }
340 break;
341
342 default:
343 /* The default policy is to allow all algorithms. */
344 result = 1;
345 }
346
347 return result;
348 }
349
350
351 /* Return true if (CIPHER, MODE) is compliant to the given COMPLIANCE mode. */
352 int
gnupg_cipher_is_compliant(enum gnupg_compliance_mode compliance,cipher_algo_t cipher,enum gcry_cipher_modes mode)353 gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
354 cipher_algo_t cipher,
355 enum gcry_cipher_modes mode)
356 {
357 if (! initialized)
358 return 0;
359
360 switch (compliance)
361 {
362 case CO_DE_VS:
363 switch (cipher)
364 {
365 case CIPHER_ALGO_AES:
366 case CIPHER_ALGO_AES192:
367 case CIPHER_ALGO_AES256:
368 case CIPHER_ALGO_3DES:
369 switch (module)
370 {
371 case GNUPG_MODULE_NAME_GPG:
372 return mode == GCRY_CIPHER_MODE_CFB;
373 case GNUPG_MODULE_NAME_GPGSM:
374 return mode == GCRY_CIPHER_MODE_CBC;
375 }
376 log_assert (!"reached");
377
378 default:
379 return 0;
380 }
381 log_assert (!"reached");
382
383 default:
384 return 0;
385 }
386
387 log_assert (!"reached");
388 }
389
390
391 /* Return true if CIPHER is allowed in the given COMPLIANCE mode. If
392 * PRODUCER is true, the predicate is evaluated for the producer, if
393 * false for the consumer. This way policies can be strict in what
394 * they produce, and liberal in what they accept. */
395 int
gnupg_cipher_is_allowed(enum gnupg_compliance_mode compliance,int producer,cipher_algo_t cipher,enum gcry_cipher_modes mode)396 gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer,
397 cipher_algo_t cipher,
398 enum gcry_cipher_modes mode)
399 {
400 if (! initialized)
401 return 1;
402
403 switch (compliance)
404 {
405 case CO_DE_VS:
406 switch (cipher)
407 {
408 case CIPHER_ALGO_AES:
409 case CIPHER_ALGO_AES192:
410 case CIPHER_ALGO_AES256:
411 case CIPHER_ALGO_3DES:
412 switch (module)
413 {
414 case GNUPG_MODULE_NAME_GPG:
415 return (mode == GCRY_CIPHER_MODE_NONE
416 || mode == GCRY_CIPHER_MODE_CFB);
417 case GNUPG_MODULE_NAME_GPGSM:
418 return (mode == GCRY_CIPHER_MODE_NONE
419 || mode == GCRY_CIPHER_MODE_CBC
420 || (mode == GCRY_CIPHER_MODE_GCM && !producer));
421 }
422 log_assert (!"reached");
423
424 case CIPHER_ALGO_BLOWFISH:
425 case CIPHER_ALGO_CAMELLIA128:
426 case CIPHER_ALGO_CAMELLIA192:
427 case CIPHER_ALGO_CAMELLIA256:
428 case CIPHER_ALGO_CAST5:
429 case CIPHER_ALGO_IDEA:
430 case CIPHER_ALGO_TWOFISH:
431 return (module == GNUPG_MODULE_NAME_GPG
432 && (mode == GCRY_CIPHER_MODE_NONE
433 || mode == GCRY_CIPHER_MODE_CFB)
434 && ! producer);
435 default:
436 return 0;
437 }
438 log_assert (!"reached");
439
440 default:
441 /* The default policy is to allow all algorithms. */
442 return 1;
443 }
444
445 log_assert (!"reached");
446 }
447
448
449 /* Return true if DIGEST is compliant to the given COMPLIANCE mode. */
450 int
gnupg_digest_is_compliant(enum gnupg_compliance_mode compliance,digest_algo_t digest)451 gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
452 digest_algo_t digest)
453 {
454 if (! initialized)
455 return 0;
456
457 switch (compliance)
458 {
459 case CO_DE_VS:
460 switch (digest)
461 {
462 case DIGEST_ALGO_SHA256:
463 case DIGEST_ALGO_SHA384:
464 case DIGEST_ALGO_SHA512:
465 return 1;
466 default:
467 return 0;
468 }
469 log_assert (!"reached");
470
471 default:
472 return 0;
473 }
474
475 log_assert (!"reached");
476 }
477
478
479 /* Return true if DIGEST is allowed in the given COMPLIANCE mode. If
480 * PRODUCER is true, the predicate is evaluated for the producer, if
481 * false for the consumer. This way policies can be strict in what
482 * they produce, and liberal in what they accept. */
483 int
gnupg_digest_is_allowed(enum gnupg_compliance_mode compliance,int producer,digest_algo_t digest)484 gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
485 digest_algo_t digest)
486 {
487 if (! initialized)
488 return 1;
489
490 switch (compliance)
491 {
492 case CO_DE_VS:
493 switch (digest)
494 {
495 case DIGEST_ALGO_SHA256:
496 case DIGEST_ALGO_SHA384:
497 case DIGEST_ALGO_SHA512:
498 return 1;
499 case DIGEST_ALGO_SHA1:
500 case DIGEST_ALGO_SHA224:
501 case DIGEST_ALGO_RMD160:
502 return ! producer;
503 case DIGEST_ALGO_MD5:
504 return ! producer && module == GNUPG_MODULE_NAME_GPGSM;
505 default:
506 return 0;
507 }
508 log_assert (!"reached");
509
510 default:
511 /* The default policy is to allow all algorithms. */
512 return 1;
513 }
514
515 log_assert (!"reached");
516 }
517
518
519 /* Return True if the random number generator is compliant in
520 * COMPLIANCE mode. */
521 int
gnupg_rng_is_compliant(enum gnupg_compliance_mode compliance)522 gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
523 {
524 int *result;
525 int res;
526
527 result = get_compliance_cache (compliance, 1);
528
529 if (result && *result != -1)
530 res = *result; /* Use cached result. */
531 else if (compliance == CO_DE_VS)
532 {
533 /* We also check whether the library is at all compliant. */
534 res = gnupg_gcrypt_is_compliant (compliance);
535
536 /* In DE_VS mode under Windows we also require that the JENT RNG
537 * is active. Check it here. */
538 #ifdef HAVE_W32_SYSTEM
539 if (res == 1)
540 {
541 char *buf;
542 const char *fields[5];
543
544 buf = gcry_get_config (0, "rng-type");
545 if (buf
546 && split_fields_colon (buf, fields, DIM (fields)) >= 5
547 && atoi (fields[4]) > 0)
548 ; /* Field 5 > 0 := Jent is active. */
549 else
550 result = 0; /* Force non-compliance. */
551 gcry_free (buf);
552 }
553 #endif /*HAVE_W32_SYSTEM*/
554 }
555 else
556 res = 1;
557
558 if (result)
559 *result = res;
560
561 return res;
562 }
563
564
565 /* Return true if the used Libgcrypt is compliant in COMPLIANCE
566 * mode. */
567 int
gnupg_gcrypt_is_compliant(enum gnupg_compliance_mode compliance)568 gnupg_gcrypt_is_compliant (enum gnupg_compliance_mode compliance)
569 {
570 int *result;
571 int res;
572
573 result = get_compliance_cache (compliance, 0);
574
575 if (result && *result != -1)
576 res = *result; /* Use cached result. */
577 else if (compliance == CO_DE_VS)
578 {
579 int is19orlater = !!gcry_check_version ("1.9.0");
580
581 /* A compliant version of GnuPG requires Libgcrypt >= 1.8.1 and
582 * less than 1.9.0. Version 1.9.0 requires a re-evaluation and
583 * can thus not be used for de-vs. */
584 if (gcry_check_version ("1.8.1") && !is19orlater)
585 res = 1; /* Compliant version of Libgcrypt. */
586 else if (is19orlater)
587 {
588 /* Libgcrypt might be nice enough to tell us whether it is
589 * compliant. */
590 char *buf;
591 const char *fields[3];
592
593 buf = gcry_get_config (0, "compliance");
594 if (buf
595 && split_fields_colon (buf, fields, DIM (fields)) >= 2
596 && strstr (fields[1], "de-vs"))
597 res = 1; /* Compliant. */
598 else
599 res = 0; /* Non-compliant. */
600 gcry_free (buf);
601 }
602 else
603 res = 0; /* Non-compliant version of Libgcrypt. */
604 }
605 else
606 res = 1;
607
608 if (result)
609 *result = res;
610
611 return res;
612 }
613
614
615 const char *
gnupg_status_compliance_flag(enum gnupg_compliance_mode compliance)616 gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
617 {
618 switch (compliance)
619 {
620 case CO_GNUPG:
621 return "8";
622 case CO_RFC4880:
623 case CO_RFC2440:
624 case CO_PGP7:
625 case CO_PGP8:
626 log_assert (!"no status code assigned for this compliance mode");
627 case CO_DE_VS:
628 return "23";
629 }
630 log_assert (!"invalid compliance mode");
631 }
632
633
634 /* Parse the value of --compliance. Returns the value corresponding
635 * to the given STRING according to OPTIONS of size LENGTH, or -1
636 * indicating that the lookup was unsuccessful, or the list of options
637 * was printed. If quiet is false, an additional hint to use 'help'
638 * is printed on unsuccessful lookups. */
639 int
gnupg_parse_compliance_option(const char * string,struct gnupg_compliance_option options[],size_t length,int quiet)640 gnupg_parse_compliance_option (const char *string,
641 struct gnupg_compliance_option options[],
642 size_t length,
643 int quiet)
644 {
645 size_t i;
646
647 if (! ascii_strcasecmp (string, "help"))
648 {
649 log_info (_("valid values for option '%s':\n"), "--compliance");
650 for (i = 0; i < length; i++)
651 log_info (" %s\n", options[i].keyword);
652 return -1;
653 }
654
655 for (i = 0; i < length; i++)
656 if (! ascii_strcasecmp (string, options[i].keyword))
657 return options[i].value;
658
659 log_error (_("invalid value for option '%s'\n"), "--compliance");
660 if (! quiet)
661 log_info (_("(use \"help\" to list choices)\n"));
662 return -1;
663 }
664
665
666 /* Return the command line option for the given COMPLIANCE mode. */
667 const char *
gnupg_compliance_option_string(enum gnupg_compliance_mode compliance)668 gnupg_compliance_option_string (enum gnupg_compliance_mode compliance)
669 {
670 switch (compliance)
671 {
672 case CO_GNUPG: return "--compliance=gnupg";
673 case CO_RFC4880: return "--compliance=openpgp";
674 case CO_RFC2440: return "--compliance=rfc2440";
675 case CO_PGP7: return "--compliance=pgp7";
676 case CO_PGP8: return "--compliance=pgp8";
677 case CO_DE_VS: return "--compliance=de-vs";
678 }
679
680 log_assert (!"invalid compliance mode");
681 }
682