/src/gnutls/lib/algorithms/secparams.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * Copyright (C) 2011-2012 Free Software Foundation, Inc.  | 
3  |  |  *  | 
4  |  |  * Author: Nikos Mavrogiannopoulos  | 
5  |  |  *  | 
6  |  |  * This file is part of GnuTLS.  | 
7  |  |  *  | 
8  |  |  * The GnuTLS is free software; you can redistribute it and/or  | 
9  |  |  * modify it under the terms of the GNU Lesser General Public License  | 
10  |  |  * as published by the Free Software Foundation; either version 2.1 of  | 
11  |  |  * the License, or (at your option) any later version.  | 
12  |  |  *  | 
13  |  |  * This library is distributed in the hope that it will be useful, but  | 
14  |  |  * WITHOUT ANY WARRANTY; without even the implied warranty of  | 
15  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  | 
16  |  |  * Lesser General Public License for more details.  | 
17  |  |  *  | 
18  |  |  * You should have received a copy of the GNU Lesser General Public License  | 
19  |  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>  | 
20  |  |  *  | 
21  |  |  */  | 
22  |  |  | 
23  |  | #include "gnutls_int.h"  | 
24  |  | #include "algorithms.h"  | 
25  |  | #include "errors.h"  | 
26  |  | #include "x509/common.h"  | 
27  |  |  | 
28  |  | typedef struct { | 
29  |  |   const char *name;  | 
30  |  |   gnutls_sec_param_t sec_param;  | 
31  |  |   unsigned int bits; /* security level */  | 
32  |  |   unsigned int pk_bits; /* DH, RSA, SRP */  | 
33  |  |   unsigned int dsa_bits; /* bits for DSA. Handled differently since  | 
34  |  |          * choice of key size in DSA is political.  | 
35  |  |          */  | 
36  |  |   unsigned int subgroup_bits; /* subgroup bits */  | 
37  |  |   unsigned int ecc_bits; /* bits for ECC keys */  | 
38  |  |   unsigned int ml_dsa_bits;  | 
39  |  | } gnutls_sec_params_entry;  | 
40  |  |  | 
41  |  | static const gnutls_sec_params_entry sec_params[] = { | 
42  |  |   { "Insecure", GNUTLS_SEC_PARAM_INSECURE, 0, 0, 0, 0, 0, 0 }, | 
43  |  |   { "Export", GNUTLS_SEC_PARAM_EXPORT, 42, 512, 0, 84, 0, 0 }, | 
44  |  |   { "Very weak", GNUTLS_SEC_PARAM_VERY_WEAK, 64, 767, 0, 128, 0, 0 }, | 
45  |  |   { "Weak", GNUTLS_SEC_PARAM_WEAK, 72, 1008, 1008, 160, 160, 0 }, | 
46  |  | #ifdef ENABLE_FIPS140  | 
47  |  |   { "Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160, 160, 0 }, | 
48  |  |   { | 
49  |  |     "Legacy",  | 
50  |  |     GNUTLS_SEC_PARAM_LEGACY,  | 
51  |  |     96,  | 
52  |  |     1024,  | 
53  |  |     1024,  | 
54  |  |     192,  | 
55  |  |     192,  | 
56  |  |     0,  | 
57  |  |   },  | 
58  |  |   { "Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 224, 224, 0 }, | 
59  |  |   { "High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256, 0 }, | 
60  |  | #else  | 
61  |  |   { "Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160, 160, | 
62  |  |     0 }, /* ENISA-LEGACY */  | 
63  |  |   { "Legacy", GNUTLS_SEC_PARAM_LEGACY, 96, 1776, 2048, 192, 192, 0 }, | 
64  |  |   { "Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 256, 224, 0 }, | 
65  |  |   { "High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256, 0 }, | 
66  |  | #endif  | 
67  |  |   { "Ultra", GNUTLS_SEC_PARAM_ULTRA, 192, 8192, 8192, 384, 384, | 
68  |  |     MLDSA65_PUBKEY_SIZE },  | 
69  |  |   { "Future", GNUTLS_SEC_PARAM_FUTURE, 256, 15360, 15360, 512, 512, | 
70  |  |     MLDSA87_PUBKEY_SIZE },  | 
71  |  |   { NULL, 0, 0, 0, 0, 0, 0, 0 } | 
72  |  | };  | 
73  |  |  | 
74  |  | /**  | 
75  |  |  * gnutls_sec_param_to_pk_bits:  | 
76  |  |  * @algo: is a public key algorithm  | 
77  |  |  * @param: is a security parameter  | 
78  |  |  *  | 
79  |  |  * When generating private and public key pairs a difficult question  | 
80  |  |  * is which size of "bits" the modulus will be in RSA and the group size  | 
81  |  |  * in DSA. The easy answer is 1024, which is also wrong. This function  | 
82  |  |  * will convert a human understandable security parameter to an  | 
83  |  |  * appropriate size for the specific algorithm.  | 
84  |  |  *  | 
85  |  |  * Returns: The number of bits, or (0).  | 
86  |  |  *  | 
87  |  |  * Since: 2.12.0  | 
88  |  |  **/  | 
89  |  | unsigned int gnutls_sec_param_to_pk_bits(gnutls_pk_algorithm_t algo,  | 
90  |  |            gnutls_sec_param_t param)  | 
91  | 0  | { | 
92  | 0  |   unsigned int ret = 0;  | 
93  | 0  |   const gnutls_sec_params_entry *p;  | 
94  |  |  | 
95  |  |   /* handle DSA differently */  | 
96  | 0  |   for (p = sec_params; p->name; p++) { | 
97  | 0  |     if (p->sec_param == param) { | 
98  | 0  |       if (algo == GNUTLS_PK_DSA)  | 
99  | 0  |         ret = p->dsa_bits;  | 
100  | 0  |       else if (IS_EC(algo) || IS_GOSTEC(algo))  | 
101  | 0  |         ret = p->ecc_bits;  | 
102  | 0  |       else if (IS_ML_DSA(algo))  | 
103  | 0  |         ret = p->ml_dsa_bits;  | 
104  | 0  |       else  | 
105  | 0  |         ret = p->pk_bits;  | 
106  | 0  |       break;  | 
107  | 0  |     }  | 
108  | 0  |   }  | 
109  |  | 
  | 
110  | 0  |   return ret;  | 
111  | 0  | }  | 
112  |  |  | 
113  |  | /**  | 
114  |  |  * gnutls_sec_param_to_symmetric_bits:  | 
115  |  |  * @algo: is a public key algorithm  | 
116  |  |  * @param: is a security parameter  | 
117  |  |  *  | 
118  |  |  * This function will return the number of bits that correspond to  | 
119  |  |  * symmetric cipher strength for the given security parameter.  | 
120  |  |  *  | 
121  |  |  * Returns: The number of bits, or (0).  | 
122  |  |  *  | 
123  |  |  * Since: 3.3.0  | 
124  |  |  **/  | 
125  |  | unsigned int gnutls_sec_param_to_symmetric_bits(gnutls_sec_param_t param)  | 
126  | 0  | { | 
127  | 0  |   unsigned int ret = 0;  | 
128  | 0  |   const gnutls_sec_params_entry *p;  | 
129  |  |  | 
130  |  |   /* handle DSA differently */  | 
131  | 0  |   for (p = sec_params; p->name; p++) { | 
132  | 0  |     if (p->sec_param == param) { | 
133  | 0  |       ret = p->bits;  | 
134  | 0  |       break;  | 
135  | 0  |     }  | 
136  | 0  |   }  | 
137  |  | 
  | 
138  | 0  |   return ret;  | 
139  | 0  | }  | 
140  |  |  | 
141  |  | /* Returns the corresponding size for subgroup bits (q),  | 
142  |  |  * given the group bits (p).  | 
143  |  |  */  | 
144  |  | unsigned int _gnutls_pk_bits_to_subgroup_bits(unsigned int pk_bits)  | 
145  | 0  | { | 
146  | 0  |   unsigned int ret = 0;  | 
147  | 0  |   const gnutls_sec_params_entry *p;  | 
148  |  | 
  | 
149  | 0  |   for (p = sec_params; p->name; p++) { | 
150  | 0  |     ret = p->subgroup_bits;  | 
151  | 0  |     if (p->pk_bits >= pk_bits)  | 
152  | 0  |       break;  | 
153  | 0  |   }  | 
154  |  | 
  | 
155  | 0  |   return ret;  | 
156  | 0  | }  | 
157  |  |  | 
158  |  | /* Returns a corresponding SHA algorithm size for the  | 
159  |  |  * public key bits given. It is based on the NIST mappings.  | 
160  |  |  */  | 
161  |  | gnutls_digest_algorithm_t _gnutls_pk_bits_to_sha_hash(unsigned int pk_bits)  | 
162  | 0  | { | 
163  | 0  |   const gnutls_sec_params_entry *p;  | 
164  |  | 
  | 
165  | 0  |   for (p = sec_params; p->name; p++) { | 
166  | 0  |     if (p->pk_bits >= pk_bits) { | 
167  | 0  |       if (p->bits <= 128)  | 
168  | 0  |         return GNUTLS_DIG_SHA256;  | 
169  | 0  |       else if (p->bits <= 192)  | 
170  | 0  |         return GNUTLS_DIG_SHA384;  | 
171  | 0  |       else  | 
172  | 0  |         return GNUTLS_DIG_SHA512;  | 
173  | 0  |     }  | 
174  | 0  |   }  | 
175  |  |  | 
176  | 0  |   return GNUTLS_DIG_SHA256;  | 
177  | 0  | }  | 
178  |  |  | 
179  |  | /**  | 
180  |  |  * gnutls_sec_param_get_name:  | 
181  |  |  * @param: is a security parameter  | 
182  |  |  *  | 
183  |  |  * Convert a #gnutls_sec_param_t value to a string.  | 
184  |  |  *  | 
185  |  |  * Returns: a pointer to a string that contains the name of the  | 
186  |  |  *   specified security level, or %NULL.  | 
187  |  |  *  | 
188  |  |  * Since: 2.12.0  | 
189  |  |  **/  | 
190  |  | const char *gnutls_sec_param_get_name(gnutls_sec_param_t param)  | 
191  | 0  | { | 
192  | 0  |   const char *ret = "Unknown";  | 
193  | 0  |   const gnutls_sec_params_entry *p;  | 
194  |  | 
  | 
195  | 0  |   for (p = sec_params; p->name; p++) { | 
196  | 0  |     if (p->sec_param == param) { | 
197  | 0  |       ret = p->name;  | 
198  | 0  |       break;  | 
199  | 0  |     }  | 
200  | 0  |   }  | 
201  |  | 
  | 
202  | 0  |   return ret;  | 
203  | 0  | }  | 
204  |  |  | 
205  |  | /**  | 
206  |  |  * gnutls_pk_bits_to_sec_param:  | 
207  |  |  * @algo: is a public key algorithm  | 
208  |  |  * @bits: is the number of bits  | 
209  |  |  *  | 
210  |  |  * This is the inverse of gnutls_sec_param_to_pk_bits(). Given an algorithm  | 
211  |  |  * and the number of bits, it will return the security parameter. This is  | 
212  |  |  * a rough indication.  | 
213  |  |  *  | 
214  |  |  * Returns: The security parameter.  | 
215  |  |  *  | 
216  |  |  * Since: 2.12.0  | 
217  |  |  **/  | 
218  |  | gnutls_sec_param_t gnutls_pk_bits_to_sec_param(gnutls_pk_algorithm_t algo,  | 
219  |  |                  unsigned int bits)  | 
220  | 0  | { | 
221  | 0  |   gnutls_sec_param_t ret = GNUTLS_SEC_PARAM_INSECURE;  | 
222  | 0  |   const gnutls_sec_params_entry *p;  | 
223  |  | 
  | 
224  | 0  |   if (bits == 0)  | 
225  | 0  |     return GNUTLS_SEC_PARAM_UNKNOWN;  | 
226  |  |  | 
227  | 0  |   if (IS_EC(algo) || IS_GOSTEC(algo)) { | 
228  | 0  |     for (p = sec_params; p->name; p++) { | 
229  | 0  |       if (p->ecc_bits > bits)  | 
230  | 0  |         break;  | 
231  | 0  |       ret = p->sec_param;  | 
232  | 0  |     }  | 
233  | 0  |   } else if (IS_ML_DSA(algo)) { | 
234  | 0  |     for (p = sec_params; p->name; p++) { | 
235  | 0  |       if (p->ml_dsa_bits > bits)  | 
236  | 0  |         break;  | 
237  | 0  |       ret = p->sec_param;  | 
238  | 0  |     }  | 
239  | 0  |   } else { | 
240  | 0  |     for (p = sec_params; p->name; p++) { | 
241  | 0  |       if (p->pk_bits > bits)  | 
242  | 0  |         break;  | 
243  | 0  |       ret = p->sec_param;  | 
244  | 0  |     }  | 
245  | 0  |   }  | 
246  |  | 
  | 
247  | 0  |   return ret;  | 
248  | 0  | }  |